ubuntu 搭建 cmake + vscode 的 c/c++ 开发环境

莱莱  金牌会员 | 2023-6-11 18:47:59 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 914|帖子 914|积分 2742

todo 列表


  • clang-format
  • c++ 整合
软件安装


基本的环境搭建

最基本的 vscode 插件

只需要安装如下两个插件即可
c/c++ 扩展是为了最基本的代码提示和调试支持
cmake language support 是为了提示 CMakeLists.txt 脚本


有可能安装了 cmake language support 还是没有代码提示, 注意配置 cmake 路径

代码

main.cpp
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     printf("\nhello world\n\n");
  5.     return 0;
  6. }
复制代码
CMakeLists.txt
  1. cmake_minimum_required(VERSION 3.24)
  2. project(hello_ubuntu CXX)
  3. set(CMAKE_CXX_STANDARD 14)
  4. set(CMAKE_CXX_STANDARD_REQUIRED True)
  5. add_executable(${PROJECT_NAME} main.cpp)
复制代码
任务配置
  1. {
  2.     // See https://go.microsoft.com/fwlink/?LinkId=733558
  3.     // for the documentation about the tasks.json format
  4.     "version": "2.0.0",
  5.     "tasks": [
  6.         {
  7.             "label": "build-debug",
  8.             "type": "shell",
  9.             "command": "cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug && cmake --build cmake-build-debug",
  10.             "dependsOn": [
  11.                 "configure"
  12.             ]
  13.         },
  14.         {
  15.             "label": "build-release",
  16.             "type": "shell",
  17.             "command": "cmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release && cmake --build cmake-build-release",
  18.             "dependsOn": [
  19.                 "configure"
  20.             ]
  21.         },
  22.         {
  23.             "label": "clean",
  24.             "type": "shell",
  25.             "command": "rm -rf build && rm -rf cmake-build-debug && rm -rf cmake-build-release"
  26.         },
  27.         {
  28.             "label": "rebuild",
  29.             "type": "shell",
  30.             "dependsOn": [
  31.                 "clean",
  32.                 "build-debug",
  33.                 "build-release"
  34.             ]
  35.         },
  36.         {
  37.             "label": "run",
  38.             "type": "shell",
  39.             "command": "./cmake-build-release/hello_ubuntu",
  40.             "dependsOn": [
  41.                 "build-release"
  42.             ]
  43.         }
  44.     ]
  45. }
复制代码
此时可以通过终端菜单的运行任务来运行
改进任务的运行方式

安装如下插件

Task Buttons 插件

.vscode文件夹添加.settings.json,并添加如下内容
  1. {
  2.     "VsCodeTaskButtons.showCounter": true,
  3.     "VsCodeTaskButtons.tasks": [
  4.         {
  5.             "label": "$(notebook-delete-cell) clean",
  6.             "task": "clean"
  7.         },
  8.         {
  9.             "label": "$(debug-configure) rebuild",
  10.             "task": "rebuild"
  11.         },
  12.         {
  13.             "label": "$(notebook-execute) run",
  14.             "task": "run"
  15.         }
  16.     ]
  17. }
复制代码
然后状态栏就会出现对应的按钮, 直接点击任务对应的按钮即可运行任务. 图标从 这里 获取

Task Explorer 插件

此插件将提供了一个任务面板, 安装之后 查看->打开试图 搜索Task Explorer 即可打开此面板, 拖到自己喜欢的位置然后直接点击对应任务右侧的按钮即可运行任务. 任务太多的话, 可以将任务加入 Favorites 列表, 把其他的收起来就可以了

快捷键

参考: https://blog.csdn.net/qq_45859188/article/details/124529266
debug

参考 这里, 直接在 .vscode 文件夹下添加 launch.json
  1. {
  2.   "version": "0.2.0",
  3.   "configurations": [
  4.     {
  5.       "name": "test-debug",
  6.       "type": "cppdbg",
  7.       "request": "launch",
  8.       "program": "${workspaceRoot}/cmake-build-debug/hello_ubuntu",
  9.       "args": [],
  10.       "stopAtEntry": false,
  11.       "cwd": "${workspaceFolder}",
  12.       "environment": [],
  13.       "externalConsole": false,
  14.       "MIMode": "gdb",
  15.       "miDebuggerPath": "/usr/bin/gdb",
  16.       "setupCommands": [
  17.         {
  18.           "description": "Enable pretty-printing for gdb",
  19.           "text": "-enable-pretty-printing",
  20.           "ignoreFailures": true
  21.         }
  22.       ],
  23.       "preLaunchTask": "rebuild"
  24.     }
  25.   ]
  26. }
复制代码
打一个断点, 然后直接 F5

注意: 有时候 vscode 的 debug 会出问题, 此时直接执行 clean 任务再进行调试即可
C语言 整合

CUnit

参考资料

官网 : https://cunit.sourceforge.net/
github: https://github.com/jacklicn/CUnit
官方手册: https://cunit.sourceforge.net/doc/index.html
中文手册: 【单元测试】CUnit用户手册(中文)
简明教程: 【单元测试】CUnit单元测试框架(不支持mock功能)
ubuntu下安装CUnit出现的问题及解决
安装
  1. sudo apt-get update
  2. sudo apt-get install build-essential automake autoconf libtool
  3. mv configure.in configure.ac
  4. aclocal
  5. autoconf
  6. autoheader
  7. libtoolize --automake --copy --debug --force
  8. automake --add-missing
  9. automake
  10. ./configure
  11. make
  12. sudo make install
复制代码
测试
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <CUnit/Basic.h>
  4. #include <CUnit/Automated.h>
  5. /* 被测试的函数,在当中故意安装了一个BUG */
  6. static int sum(int a, int b)
  7. {
  8.     if (a > 4)
  9.     {
  10.         return 0;
  11.     }
  12.     return (a + b);
  13. }
  14. static int suite_init(void)
  15. {
  16.     return 0;
  17. }
  18. static int suite_clean(void)
  19. {
  20.     return 0;
  21. }
  22. static void test_sum(void)
  23. {
  24.     CU_ASSERT_EQUAL(sum(1, 2), 3);
  25.     CU_ASSERT_EQUAL(sum(5, 2), 7);
  26. }
  27. int main()
  28. {
  29.     CU_pSuite pSuite = NULL;
  30.     /* initialize the CUnit test registry */
  31.     if (CUE_SUCCESS != CU_initialize_registry())
  32.     {
  33.         return CU_get_error();
  34.     }
  35.     /* add a suite to the registry */
  36.     pSuite = CU_add_suite("suite_sum", suite_init, suite_clean);
  37.     if (NULL == pSuite)
  38.     {
  39.         CU_cleanup_registry();
  40.         return CU_get_error();
  41.     }
  42.     /* add the tests to the suite */
  43.     if ((NULL == CU_add_test(pSuite, "test_sum", test_sum)))
  44.     {
  45.         CU_cleanup_registry();
  46.         return CU_get_error();
  47.     }
  48.     // basic
  49.     CU_basic_set_mode(CU_BRM_VERBOSE);
  50.     CU_basic_run_tests();
  51.     // automated
  52.     CU_list_tests_to_file();
  53.     CU_automated_run_tests();
  54.     /* Clean up registry and return */
  55.     CU_cleanup_registry();
  56.     return CU_get_error();
  57. }
复制代码
编译
  1. gcc test.c `pkg-config --libs --cflags cunit` -o test
复制代码
此时控制台有了 basic 模式的输出, 并且有了 automated 模式的 xml 文件
  1. laolang@laolang-pc:~/tmp/cunit$ ./test
  2.      CUnit - A unit testing framework for C - Version 2.1-3
  3.      http://cunit.sourceforge.net/
  4. Suite: suite_sum
  5.   Test: test_sum ...FAILED
  6.     1. test.c:33  - CU_ASSERT_EQUAL(sum(5, 2),7)
  7. Run Summary:    Type  Total    Ran Passed Failed Inactive
  8.               suites      1      1    n/a      0        0
  9.                tests      1      1      0      1        0
  10.              asserts      2      2      1      1      n/a
  11. Elapsed time =    0.000 seconds
  12. laolang@laolang-pc:~/tmp/cunit$ l
  13. 总计 32K
  14. -rw-rw-r-- 1 laolang laolang 1.7K 2023-06-11 18:17:16 CUnitAutomated-Listing.xml
  15. -rw-rw-r-- 1 laolang laolang 1.6K 2023-06-11 18:17:16 CUnitAutomated-Results.xml
  16. -rwxrwxr-x 1 laolang laolang  17K 2023-06-11 18:17:14 test*
  17. -rw-rw-r-- 1 laolang laolang 1.2K 2023-06-11 18:17:02 test.c
  18. laolang@laolang-pc:~/tmp/cunit$
复制代码
然后从安装包复制如下几个文件, 和 cunit 输出的 xml 同级

  • CUnit-List.dtd
  • CUnit-List.xsl
  • CUnit-Run.dtd
  • CUnit-Run.xsl
在本地起一个服务器, 比如 npm 的 serve, 两个文件效果如下


关于代码覆盖率

参考: GCOV+LCOV 代码调试和覆盖率统计工具
日志

日志框架有很多, 此处选择 zlog, 官网写的非常详细
github: https://github.com/HardySimpson/zlog/
中文手册: http://hardysimpson.github.io/zlog/UsersGuide-CN.html
整合结果

目录结构
  1. laolang@laolang-pc:~/tmp/helloc$ tree -a
  2. .
  3. ├── app.log
  4. ├── CMakeLists.txt
  5. ├── coverage.sh
  6. ├── .gitignore
  7. ├── resources
  8. │   └── cunit
  9. │       ├── CUnit-List.dtd
  10. │       ├── CUnit-List.xsl
  11. │       ├── CUnit-Run.dtd
  12. │       └── CUnit-Run.xsl
  13. ├── src
  14. │   ├── app
  15. │   │   ├── CMakeLists.txt
  16. │   │   └── helloc.c
  17. │   ├── CMakeLists.txt
  18. │   ├── common
  19. │   │   ├── CMakeLists.txt
  20. │   │   ├── common.h
  21. │   │   ├── zlog_conf.c
  22. │   │   └── zlog_conf.h
  23. │   └── datastruct
  24. │       ├── CMakeLists.txt
  25. │       ├── sum.c
  26. │       └── sum.h
  27. ├── test
  28. │   ├── CMakeLists.txt
  29. │   ├── maintest.c
  30. │   ├── test_sum.c
  31. │   └── test_sum.h
  32. ├── .vscode
  33. │   ├── launch.json
  34. │   ├── settings.json
  35. │   └── tasks.json
  36. └── zlog.conf
  37. 8 directories, 26 files
  38. laolang@laolang-pc:~/tmp/helloc$
复制代码
.vscode

tasks.json
  1. {
  2.     "version": "2.0.0",
  3.     "tasks": [
  4.         {
  5.             "label": "build-debug",
  6.             "type": "shell",
  7.             "command": "cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug && cmake --build cmake-build-debug",
  8.             "dependsOn": [
  9.                 "configure"
  10.             ]
  11.         },
  12.         {
  13.             "label": "build-release",
  14.             "type": "shell",
  15.             "command": "cmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release && cmake --build cmake-build-release",
  16.             "dependsOn": [
  17.                 "configure"
  18.             ]
  19.         },
  20.         {
  21.             "label": "clean",
  22.             "type": "shell",
  23.             "command": "rm -rf build && rm -rf cmake-build-debug && rm -rf cmake-build-release"
  24.         },
  25.         {
  26.             "label": "rebuild",
  27.             "type": "shell",
  28.             "dependsOn": [
  29.                 "clean",
  30.                 "build-debug",
  31.                 "build-release"
  32.             ]
  33.         },
  34.         {
  35.             "label": "run",
  36.             "type": "shell",
  37.             "command": "./cmake-build-release/bin/helloc",
  38.             "dependsOn": [
  39.                 "build-release"
  40.             ]
  41.         },
  42.         {
  43.             "label": "test",
  44.             "type": "shell",
  45.             "command": "./cmake-build-debug/bin/helloc_test && mkdir -p cmake-build-debug/report && mv CUnit*.xml cmake-build-debug/report && cp resources/cunit/CUnit-*.* cmake-build-debug/report/",
  46.             "dependsOn": [
  47.                 "build-debug"
  48.             ]
  49.         },
  50.         {
  51.             "label": "coverage",
  52.             "type": "shell",
  53.             "command": "./coverage.sh",
  54.             "dependsOn": [
  55.                 "clean",
  56.                 "test"
  57.             ]
  58.         }
  59.     ]
  60. }
复制代码
settings.json
  1. {
  2.     "files.exclude": {
  3.         "**/.git": true,
  4.         "**/.svn": true,
  5.         "**/.hg": true,
  6.         "**/CVS": true,
  7.         "**/.DS_Store": true,
  8.         "**/Thumbs.db": true,
  9.         "**/cmake-build-debug":true,
  10.         "**/cmake-build-release":true
  11.     },
  12.     "cmake.cmakePath": "/home/laolang/program/cmake/bin/cmake",
  13.     "VsCodeTaskButtons.showCounter": true,
  14.     "VsCodeTaskButtons.tasks": [
  15.         {
  16.             "label": "$(notebook-delete-cell) clean",
  17.             "task": "clean"
  18.         },
  19.         {
  20.             "label": "$(debug-configure) rebuild",
  21.             "task": "rebuild"
  22.         },
  23.         {
  24.             "label": "$(notebook-execute) run",
  25.             "task": "run"
  26.         },
  27.         {
  28.             "label": "$(test-view-icon) test",
  29.             "task": "test"
  30.         },
  31.         {
  32.             "label": "coverage",
  33.             "task": "coverage"
  34.         }
  35.     ]
  36. }
复制代码
launch.json
  1. {
  2.     "version": "0.2.0",
  3.     "configurations": [
  4.         {
  5.             "name": "app-debug",
  6.             "type": "cppdbg",
  7.             "request": "launch",
  8.             "program": "${workspaceRoot}/cmake-build-debug/bin/helloc",
  9.             "args": [],
  10.             "stopAtEntry": false,
  11.             "cwd": "${workspaceFolder}",
  12.             "environment": [],
  13.             "externalConsole": false,
  14.             "MIMode": "gdb",
  15.             "miDebuggerPath": "/usr/bin/gdb",
  16.             "setupCommands": [
  17.                 {
  18.                     "description": "Enable pretty-printing for gdb",
  19.                     "text": "-enable-pretty-printing",
  20.                     "ignoreFailures": true
  21.                 }
  22.             ],
  23.             "preLaunchTask": "rebuild"
  24.         }
  25.     ]
  26. }
复制代码
coverage.sh
  1. #!/bin/bash
  2. BUILD_PATH=cmake-build-debug
  3. lcov -d . -o ${BUILD_PATH}/app.info -b . -c --exclude '*/test/*' --exclude '*/src/main/*'
  4. genhtml ${BUILD_PATH}/app.info -o ${BUILD_PATH}/lcov
复制代码
zlog.con
  1. [formats]
  2. simple = "%d().%ms %p %V [%F:%L] - %m%n"
  3. [rules]
  4. my_cat.DEBUG    >stdout;    simple
  5. *.*     "app.log", 10MB * 0 ~ "app-%d(%Y%m%d).#2s.log"
复制代码
cmake

顶层 cmake
  1. cmake_minimum_required(VERSION 3.0)
  2. project(helloc C)
  3. set(CMAKE_C_STANDARD 17)
  4. set(CMAKE_C_STANDARD_REQUIRED True)
  5. set(CMAKE_C_EXTENSIONS ON)
  6. set(CMAKE_BUILD_WITH_INSTALL_RPATH True)
  7. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
  8. if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  9.     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -Wall")
  10.     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
  11. endif()
  12. set(lib_common common)
  13. set(lib_datastruct datastruct)
  14. configure_file(${CMAKE_SOURCE_DIR}/zlog.conf ${CMAKE_BINARY_DIR}/bin/zlog.conf COPYONLY)
  15. add_subdirectory(src)
  16. add_subdirectory(test)
  17. enable_testing()
  18. add_test(NAME helloc_test COMMAND helloc_test)
复制代码
test cmake
  1. cmake_minimum_required(VERSION 3.25)
  2. project(helloc_test C)
  3. set(CMAKE_C_STANDARD 17)
  4. set(CMAKE_C_STANDARD_REQUIRED True)
  5. set(CMAKE_C_EXTENSIONS ON)
  6. set(CMAKE_BUILD_WITH_INSTALL_RPATH True)
  7. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -Wall")
  8. SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
  9. include_directories(${CMAKE_SOURCE_DIR}/test)
  10. include_directories(${CMAKE_SOURCE_DIR}/include)
  11. aux_source_directory(. TEST_SRCS)
  12. set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
  13. add_executable(${PROJECT_NAME} ${TEST_SRCS})
  14. target_link_libraries(${PROJECT_NAME} cunit zlog ${lib_common} ${lib_datastruct})
  15. set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "\${ORIGIN}/../lib")
复制代码
其他文件与脚本


效果预览

cunit 的测试报告上面已经有了, 代码覆盖率如下



注意事项


  • 代码覆盖率要求代码必须运行过
  • 如果生成代码覆盖率或者运行测试的时候 lcov 报错, 有可能是因为覆盖率数据文件冲突, 先执行 clean 再执行 test 或者 coverage 即可
  • vscode 的 debug 有可能会崩溃, 结束任务, 关闭终端面板, 手动删除 build 目录再次点击 F5 即可
  • 尝试在 tasks.json 中配置变量, 失败了

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表