文章

从开源项目重学C语言-vscode配置

计划

从youtube上找到一个大神讲解学习路线,计划第一个学习的开源项目是cJSON

1. 下载源码,并跑通IDE的debug

我这边使用的ide是vs code,除了跑跑xcode的项目,第一次接触c语言工程的编译,发现有很大的不同。

  1. 下载安装vscode的插件C/C++、CMake、CMake Tools、Code Runner
  2. 说实话,本人比较笨,ide和插件都弄好了,要debug起来,还是研究了好久,搜索了一堆“macos vscode c 多文件调试、C 多文件编译”等等,文章推荐大多都是用Makefile,所以下面会有Makefile使用的基本讲解

2. Makefile使用

主要教程可以参考:如何使用MakefileMake 命令教程Makefile使用总结跟我一起写Makefile

Makefile文件是和make命令一起配合使用的,主要用于解决项目中各种库和代码之间的依赖关系。当然Makefile还能组织我们平时的一些日常操作(shell命令)。

代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(build)。

Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目。但是实际上 ,任何只要某个文件有变化,就要重新构建的项目,都可以用Make构建。

例如我有三个文件,main.c ioput.c calc.c,Makefile文件如下:源码来源

1
2
all: calc ioput.c main.c 
	gcc -o calc main.c ioput.c calc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
test|⇒ make  
gcc -o calc main.c ioput.c calc.c
test|⇒ ./calc
Enter the year:2021
Enter the month:2

     February 2021
Su Mo Tu We Th Fr Sa 
    1  2  3  4  5  6 
 7  8  9 10 11 12 13 
14 15 16 17 18 19 20 
21 22 23 24 25 26 27 
28 

Makefile还有挺多用法的,我这里暂时先不研究了,抓紧去学习cJSON了

3. CMakeLists.txt的使用

https://zhuanlan.zhihu.com/p/67022315

先安装cmake

1
brew install cmake

用vs code用这篇文章的方法利用VScode和cmake编译构建C++工程代码

安装CMake Tools的扩展,调用命令台工具(command+shift+p),然后选中CMake: Configure

WX20210209-223044@2x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[main] 正在配置文件夹: cJson 
[proc] 执行命令: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -H/Users/qiujunyun/Documents/WorkSpace/CC++/cJson -B/Users/qiujunyun/Documents/WorkSpace/CC++/cJson/build -G "Unix Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Configuring done
[cmake] CMake Warning (dev):
[cmake]   Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
[cmake]   --help-policy CMP0042" for policy details.  Use the cmake_policy command to
[cmake]   set the policy and suppress this warning.
[cmake] 
[cmake]   MACOSX_RPATH is not specified for the following targets:
[cmake] 
[cmake]    cjson
[cmake] 
[cmake] This warning is for project developers.  Use -Wno-dev to suppress it.
[cmake] 
[cmake] -- Generating done
[cmake] -- Build files have been written to: /Users/qiujunyun/Documents/WorkSpace/CC++/cJson/build

提示所有库都找到了。

然后我们点击下面的debug按钮:

WX20210209-223418@2x

就可以进行debug了

WX20210209-223653@2x

4. vscode的调试工具

官方文档见Debugging

主要是 两个文件的配置:launch.json和task.son VSCode 结合Makefile设置调试方法

具体可以查看我弄好的tinyhttpd的调试例子,这里用的是结合makefile的方式去debug的,当然也可以不用makefile,直接添加一个编译的task,如windows 10上使用vscode编译运行和调试C/C++

下面贴下例子:

Launch.json,其中preLaunchTask指向的就是tasks.json中的task

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/httpd",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "lldb",
            "preLaunchTask": "build-debug"
        }
    ]
}

tasks.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {// 这个就是使用gcc的方式
            "label": "complie",
            "type": "shell",
            "command": "gcc",
            "args": [
                "-W",
                "-Wall",
                "-lpthread",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
              "cwd": "${workspaceFolder}"
            }
        },
        {// 这个就是使用makefile的方式
            "label": "build-debug",
            "type": "shell",
            "command": "make",
            "args": [
                "debug"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "clean",
            "type": "shell",
            "command": "make",
            "args": [
                "clean"
            ]
        }
    ]
}

5. 其他

还能使用命令行工具gdb来进行debug调试gdb 调试利器,在mac是使用lldb,命令是一样的

使用gdb调试程序完全教程

GDB调试C/C++程序

首先编译一定要加 -g 这样调试才能看到代码

同样以tinyhttpd项目为例子,lldb的调试最后就是这样的,命令行创建断点,命令行run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2tinyhttpd|master⚡ ⇒ gcc -W -Wall -lpthread -g -o httpd httpd.c
2tinyhttpd|master⚡ ⇒ lldb httpd
(lldb) target create "httpd"
Current executable set to '/Users/rambo/Documents/MyProject/CC++/2tinyhttpd/httpd' (x86_64).
(lldb) b 584
Breakpoint 1: where = httpd`main + 54 at httpd.c:584:39, address = 0x0000000100003a16
(lldb) run
Process 30789 launched: '/Users/rambo/Documents/MyProject/CC++/2tinyhttpd/httpd' (x86_64)
Process 30789 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100003a16 httpd`main at httpd.c:584:39
   581 	 //pthread_t newthread;
   582
   583 	 server_sock = startup(&port);
-> 584 	 printf("httpd running on port %d\n", port);
   585
   586 	 while (1)
   587 	 {
Target 0: (httpd) stopped.
(lldb) next
httpd running on port 60876
Process 30789 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100003a28 httpd`main at httpd.c:589:24
   586 	 while (1)
   587 	 {
   588 	  //阻塞等待客户端的连接,参读《TLPI》P1157
-> 589 	  client_sock = accept(server_sock,
   590 	                       (struct sockaddr *)&client_name,
   591 	                       &client_name_len);
   592 	  if (client_sock == -1)
Target 0: (httpd) stopped.
(lldb) quit
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] Y
本文由作者按照 CC BY 4.0 进行授权