Cソースコードを Clang と vscode for mac で デバッグ
repos: https://github.com/sato1043/try_clang_env
概要
- C言語環境のキャッチアップ実施。
- 手持ちの Mac が XCode 導入済で、 Clang を利用
- vscode for mac で IDEデバッグ
準備
- XCode
- homebrew
- vscode
$ brew cask install visual-studio-code
-
Cmd + Space -> visual studio code
-
vscode上で) F1 -> install extensions
-
vscode上で) F1 -> configure default build task
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "make",
"type": "shell",
"command": "make",
"args": ["-j4", "debug"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
- ccache
$ brew install ccache
$ echo 'export PATH=/usr/local/opt/ccache/libexec:$PATH' >> ~/.profile
# => .profile は自分のシェル用のprofile
- clang-format
$ brew install clang-format
$ clang-format -dump-config -style=Google > .clang-format
- vscode上で) F1 -> install extensions
- vscode上で) F1 -> open settings(JSON)
{
"editor.formatOnSave": true
}
- cppcheck
- cunit
- tcmalloc(gperftools)
- valgrind
$ brew install cppcheck cunit gperftools valgrind
- vscode上で) F1 -> install extensions
-
C/C++ Intellisense
- F12, Shift+F12, Cmd+F12 など、タグジャンプ
-
C/C++ Intellisense
- global
$ xcode-select --install
$ brew install global
- vscode上で) F1 -> open settings(JSON)
{
:
"codegnuglobal.executable": "/usr/local/bin/global"
}
- vscode上で) F1 -> install extensions
$ brew install plantuml
- vscode上で) F1 -> install extensions
コード
Makefile
- vscode上で) F1 -> new file
- ファイル名は Makefile
TARGET := a.out
MAIN_C := ./main.c
TEST_C := ./test.c
SRCS := $(filter-out $(TEST_C), $(wildcard ./*.c) $(wildcard ./**/*.c))
OBJS := $(SRCS:%.c=%.o)
DEPS := $(SRCS:%.c=%.d)
-include $(DEPS)
TSRCS := $(filter-out $(MAIN_C), $(wildcard ./*.c) $(wildcard ./**/*.c))
TOBJS := $(TSRCS:%.c=%.o)
TDEPS := $(TSRCS:%.c=%.d)
-include $(TDEPS)
.PHONY: release debug all check clean test
CFLAGS := -std=c17 -Weverything
CFLAGS_D :=-O0 -DDEBUG -g
CFLAGS_R :=-O2 -DNDEBUG
LDFLAGS :=-ltcmalloc
LDFLAGS_D :=-g -debug
LDFLAGS_R :=
all: CFLAGS+=$(CFLAGS_R)
all: LDFLAGS+=$(LDFLAGS_R)
all: clean $(TARGET)
debug: CFLAGS+=$(CFLAGS_D)
debug: LDFLAGS+=$(LDFLAGS_D)
debug: check $(TARGET)
CC := clang
.c.o:
$(CC) -MMD -MP $(CFLAGS) -c $<
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS)
run: $(TARGET)
valgrind --leak-check=full ./$(TARGET)
time: $(TARGET)
time ./$(TARGET)
test: $(TARGET).cunit
valgrind --leak-check=full ./$(TARGET).cunit
$(TARGET).cunit: $(TOBJS)
$(CC) $(LDFLAGS) -lcunit -o $(TARGET).cunit $(TOBJS)
dSYM: $(TARGET)
dsymutil $(TARGET)
tags:
gtags -v
check:
@for src in $(SRCS) ; do \
clang-format -i "$$src" ; \
cppcheck --enable=all --check-config "$$src" ; \
done
clean:
-rm -rf $(DEPS) $(OBJS) $(TDEPS) $(TOBJS) $(TARGET) $(TARGET).dSYM $(TARGET).cunit $(TARGET).cunit.dSYM
usecase.puml
@startuml
User -> (Start)
@enduml
main.c
- vscode上で) F1 -> new file
- ファイル名は main.c
#include <stdio.h>
#include "functions.h"
int main(int argc, char **argv) {
say_hello();
}
functions.h
- vscode上で) F1 -> new file
- ファイル名は functions.h
#pragma once
int say_hello(void);
functions.c
- vscode上で) F1 -> new file
- ファイル名は functions.c
#include <stdio.h>
#include "functions.h"
int say_hello() {
printf("hello world\n");
return 0;
}
test.c
- vscode上で) F1 -> new file
- ファイル名は test.c
#include "CUnit/Basic.h"
#include "CUnit/CUnit.h"
#include "functions.h"
void test_say_hello(void);
int main(void) {
CU_pSuite testSuite;
CU_initialize_registry();
testSuite = CU_add_suite("ATestSuite", NULL, NULL);
CU_add_test(testSuite, "test_say_hello", test_say_hello);
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
CU_cleanup_registry();
return 0;
}
void test_say_hello(void) { CU_ASSERT(say_hello() == 0); }
a.out.cunit
- vscode上で) F1 -> new terminal
$ make test
:
./a.out.cunit
CUnit - A unit testing framework for C - Version 2.1-3
http://cunit.sourceforge.net/
Suite: ATestSuite
Test: test_say_hello ...hello world
passed
Run Summary: Type Total Ran Passed Failed Inactive
suites 1 1 n/a 0 0
tests 1 1 1 0 0
asserts 1 1 1 0 n/a
Elapsed time = 0.000 seconds
a.out
- vscode上で) F1 -> run build
- vscode上で) F1 -> new terminal
$ ./a.out
hello world
デバッグ
- vscode上で) F1 -> start debugging
- 初回、設定の新規作成を促される。
- "C++(gdb/lldb)"を選択してlaunch.json編集
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/a.out", <==ここ
"args": [],
"stopAtEntry": true, <==ここ
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false, <==ここ
"MIMode": "lldb"
}
]
}
- F5
- main関数冒頭でブレイク。できました。