cmake 学习笔记
代码地址:
https://gitcode.net/u014254963/cmake-study/-/tree/master/hello_cmake_project
https://gitcode.net/u014254963/cmake-study/-/tree/master/hello_cmake_project_vs
本文目标
- 多目录构建
- 引用自己写的动态库
- 关于单元测试的一些实践
- 使用 python 脚本控制构建的生命周期的目标描述
注意
- 本文不涉及任何静态库的操作
- 本文不涉及任何第三方库的 find_package 操作
- 本文不涉及任何 install 操作
简单的多目录
linux 与 vs 不需要测试
目录结构
F:\2023\code\cmake\hello_cmake_project>tree /f
卷 dox 的文件夹 PATH 列表
卷序列号为 34D2-6BE8
F:.
│ CMakeLists.txt
│
├─.vscode
│ launch.json
│ tasks.json
│
├─include
│ person.h
│
└─src
CMakeLists.txt
main.cpp
person.cpp
F:\2023\code\cmake\hello_cmake_project>
c++
person.h
#ifndef_PERSON_H_#define_PERSON_H_#include<string>classPerson{public:Person();~Person();
std::string SayHello();};#endif// _PERSON_H_
person.cpp
#include"person.h"Person::Person(){}Person::~Person(){}
std::string Person::SayHello(){return"hello world";}
main.cpp
#include<iostream>#include"person.h"intmain(){
Person *p =newPerson();
std::cout << p->SayHello()<< std::endl;delete p;
std::cout <<"hello world"<< std::endl;return0;}
CMakeLists.txt
CMakeLists.txt
# 该项目所需 cmake 的最小版本, 如果 cmake 版本小于设置的版本, cmake 将停止处理并报错
cmake_minimum_required(VERSION 3.0)
# 设置项目名称和语言
project(hello_cmake_project CXX)set(CMAKE_BUILD_TYPE DEBUG)
# 指定 c++11set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED True)MESSAGE(STATUS "源码目录: " ${PROJECT_SOURCE_DIR})MESSAGE(STATUS "构建目录: " ${PROJECT_BINARY_DIR})add_subdirectory(src)
src/CMakeLists.txt
# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 源文件列表
aux_source_directory(. SRCS)
# 可执行文件目录
#set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 使用指定的源文件向项目添加可执行文件
add_executable(${PROJECT_NAME} ${SRCS})
使用过程
F:\2023\code\cmake\hello_cmake_project>cmake -S.-G"Unix Makefiles"-B build && cmake --build build --config debug
-- The CXX compiler identification is GNU 10.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/program/tdmgcc/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 源码目录: F:/2023/code/cmake/hello_cmake_project
-- 构建目录: F:/2023/code/cmake/hello_cmake_project/build
-- Configuring done
-- Generating done
-- Build files have been written to: F:/2023/code/cmake/hello_cmake_project/build
[33%] Building CXX object src/CMakeFiles/hello_cmake_project.dir/main.cpp.obj
[66%] Building CXX object src/CMakeFiles/hello_cmake_project.dir/person.cpp.obj
[100%] Linking CXX executable hello_cmake_project.exe
[100%] Built target hello_cmake_project
F:\2023\code\cmake\hello_cmake_project>.\build\src\hello_cmake_project.exe
hello world
hello world
F:\2023\code\cmake\hello_cmake_project>
多目录生成动态库并使用
linux 和 vs 均需测试
源码
目录结构
F:\2023\code\cmake\hello_cmake_project>tree /f
卷 dox 的文件夹 PATH 列表
卷序列号为 34D2-6BE8
F:.
│ CMakeLists.txt
│
├─.vscode
│ launch.json
│ tasks.json
│
├─include
│ └─human
│ person.h
│
└─src
│ CMakeLists.txt
│
├─human
│ CMakeLists.txt
│ person.cpp
│
└─main
CMakeLists.txt
main.cpp
F:\2023\code\cmake\hello_cmake_project>
c++
只需要修改一下
person.h
引入的路径即可
#include"human/person.h"
CMakeLists.txt
CMakeLists.txt
# 该项目所需 cmake 的最小版本, 如果 cmake 版本小于设置的版本, cmake 将停止处理并报错
cmake_minimum_required(VERSION 3.0)
# 设置项目名称和语言
project(hello_cmake_project CXX)set(CMAKE_BUILD_TYPE DEBUG)
# 指定 c++11set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED True)#human库名称set(lib_human human)add_subdirectory(src)
src/CMakeLists.txt
add_subdirectory(main)add_subdirectory(human)
src/human/CMakeLists.txt
# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 源文件列表
aux_source_directory(. HUMAN_SRCS)
# 设置生成目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)
# 生成动态库, 默认生成的是静态库
add_library(${lib_human} SHARED ${HUMAN_SRCS})
# 指定动态库版本
#VERSION 动态库版本#SOVERSION API版本set_target_properties(${lib_human} PROPERTIES VERSION 1.0 SOVERSION 1)
src/main/CMakeLists.txt
# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 源文件列表
aux_source_directory(. MAIN_SRCS)
# 可执行文件目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)
# 使用指定的源文件向项目添加可执行文件
add_executable(${PROJECT_NAME} ${MAIN_SRCS})
# 声明链接时需要参与的依赖库名称
target_link_libraries(${PROJECT_NAME} ${lib_human})
命令行验证
注意: 缺失 dll 的提示需要在 cmd 下才能验证出来, 当然直接双击 exe 也可以验证
F:\2023\code\cmake\hello_cmake_project>cmake -S.-G"Unix Makefiles"-B build && cmake --build build --config debug
-- The CXX compiler identification is GNU 10.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/program/tdmgcc/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: F:/2023/code/cmake/hello_cmake_project/build
[25%] Building CXX object src/human/CMakeFiles/human.dir/person.cpp.obj
[50%] Linking CXX shared library F:/2023/code/cmake/hello_cmake_project/dist/libhuman.dll
[50%] Built target human
[75%] Building CXX object src/main/CMakeFiles/hello_cmake_project.dir/main.cpp.obj
[100%] Linking CXX executable F:/2023/code/cmake/hello_cmake_project/dist/hello_cmake_project.exe
[100%] Built target hello_cmake_project
F:\2023\code\cmake\hello_cmake_project>cd dist
F:\2023\code\cmake\hello_cmake_project\dist>dir
驱动器 F 中的卷是 dox
卷的序列号是 34D2-6BE8
F:\2023\code\cmake\hello_cmake_project\dist 的目录
2023/01/21 18:09 <DIR>.2023/01/21 18:09 <DIR>..2023/01/21 18:09 2,931,195 hello_cmake_project.exe
2023/01/21 18:09 752,047 libhuman.dll
2023/01/21 18:09 3,976 libhuman.dll.a
3 个文件 3,687,218 字节
2 个目录 92,873,236,480 可用字节
F:\2023\code\cmake\hello_cmake_project\dist>hello_cmake_project.exe
hello world
hello world
F:\2023\code\cmake\hello_cmake_project\dist>move libhuman.dll libhuman.dll.bak
移动了 1 个文件。
F:\2023\code\cmake\hello_cmake_project\dist>hello_cmake_project.exe
F:\2023\code\cmake\hello_cmake_project\dist>
如何在 vscode 中使用
由于默认的 exe 和 dll 生成的目录比较深, 所以重新设置了生成路径
#src/human/CMakeLists.txt
# 设置生成目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)#src/main/CMakeLists.txt
# 可执行文件目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)
相应的
launch.json
也要修改
"program":"${workspaceFolder}/dist/hello_cmake_project.exe"
linux 验证
这一部分没有什么特殊的
ubuntu@ubuntu-cpp:~/code/cmake/hello_cmake_project$ ll
total 20
drwxrwxr-x 4 ubuntu ubuntu 4096 Jan 2119:27 ./
drwxrwxr-x 4 ubuntu ubuntu 4096 Jan 2119:27 ../
-rw-rw-r-- 1 ubuntu ubuntu 402 Jan 2119:27 CMakeLists.txt
drwxrwxr-x 3 ubuntu ubuntu 4096 Jan 2119:27 include/
drwxrwxr-x 4 ubuntu ubuntu 4096 Jan 2119:27 src/
ubuntu@ubuntu-cpp:~/code/cmake/hello_cmake_project$ cmake -S.-B build && cmake --build build --config debug
-- The CXX compiler identification is GNU 11.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/code/cmake/hello_cmake_project/build
[25%] Building CXX object src/human/CMakeFiles/human.dir/person.cpp.o
[50%] Linking CXX shared library /home/ubuntu/code/cmake/hello_cmake_project/dist/libhuman.so
[50%] Built target human
[75%] Building CXX object src/main/CMakeFiles/hello_cmake_project.dir/main.cpp.o
[100%] Linking CXX executable /home/ubuntu/code/cmake/hello_cmake_project/dist/hello_cmake_project
[100%] Built target hello_cmake_project
ubuntu@ubuntu-cpp:~/code/cmake/hello_cmake_project$ ls-l dist
total 124
-rwxrwxr-x 1 ubuntu ubuntu 63384 Jan 2119:27 hello_cmake_project
lrwxrwxrwx 1 ubuntu ubuntu 13 Jan 2119:27 libhuman.so -> libhuman.so.1
lrwxrwxrwx 1 ubuntu ubuntu 15 Jan 2119:27 libhuman.so.1 -> libhuman.so.1.0
-rwxrwxr-x 1 ubuntu ubuntu 60968 Jan 2119:27 libhuman.so.1.0
ubuntu@ubuntu-cpp:~/code/cmake/hello_cmake_project$ ./dist/hello_cmake_project
hello world
hello world
ubuntu@ubuntu-cpp:~/code/cmake/hello_cmake_project$
如何在 vs 2019 中使用
这一部分稍显繁琐
- vs 的 debug 和 release 生成路径不一样
- 需要复制 dll 到 exe 所在目录
注意: CMakeLists.txt 脚本与源码均有变动
目录结构
F:\2023\code\cmake\hello_cmake_project_vs>tree /f
Folder PATH listing for volume dox
Volume serial number is 34D2-6BE8
F:.
│ CMakeLists.txt
│
├───include
│ └───human
│ framework.h
│ pch.h
│ person.h
│
└───src
│ CMakeLists.txt
│
├───human
│ CMakeLists.txt
│ dllmain.cpp
│ pch.cpp
│ person.cpp
│
└───main
CMakeLists.txt
main.cpp
F:\2023\code\cmake\hello_cmake_project_vs>
c++
include/human/framework.h
#pragmaonce#defineWIN32_LEAN_AND_MEAN// 从 Windows 头文件中排除极少使用的内容// Windows 头文件#include<windows.h>
include/human/pch.h
// pch.h: 这是预编译标头文件。// 下方列出的文件仅编译一次,提高了将来生成的生成性能。// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。#ifndefPCH_H#definePCH_H// 添加要在此处预编译的标头#include"framework.h"#endif//PCH_H
include/human/person.h
#ifndef_PERSON_H_#define_PERSON_H_#defineDllExport__declspec(dllexport)#include<string>classDllExport Person
{public:Person();~Person();
std::string SayHello();};#endif// _PERSON_H_
src/human/dllmain.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include"human/pch.h"
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
){switch(ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}
src/human/pch.cpp
#include"human/pch.h"
src/human/person.cpp
#include"human/pch.h"#include"human/person.h"Person::Person(){}Person::~Person(){}
std::string Person::SayHello(){return"hello world";}
src/main/main.cpp
#include<iostream>#include"human/person.h"intmain(){
Person *p =newPerson();
std::cout << p->SayHello()<< std::endl;delete p;
std::cout <<"hello world"<< std::endl;return0;}
CMakeLists.txt
CMakeLists.txt
# 该项目所需 cmake 的最小版本, 如果 cmake 版本小于设置的版本, cmake 将停止处理并报错
cmake_minimum_required(VERSION 3.0)
# 设置项目名称和语言
project(hello_cmake_project CXX)set(CMAKE_BUILD_TYPE DEBUG)
# 指定 c++11set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED True)
# 设置编译类型为 Debug
#set(CMAKE_BUILD_TYPE "Debug")#set(CMAKE_BUILD_TYPE "Release")
# -------------------------------------------------------------------------------------------
#[[
将 CMAKE_BUILD_TYPE 保存到 project_debug , 避免重复判断
设置 debug 库后缀
]]if(CMAKE_BUILD_TYPE)string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE)if(${BUILD_TYPE} STREQUAL "debug")set(project_debug 1)set(CMAKE_BUILD_TYPE "Debug")set(CMAKE_DEBUG_POSTFIX d)elseif(${BUILD_TYPE} STREQUAL "release")set(project_debug 0)set(CMAKE_BUILD_TYPE "Release")else()set(project_debug 1)set(CMAKE_BUILD_TYPE "Debug")set(CMAKE_DEBUG_POSTFIX d)endif()else()set(project_debug 1)set(CMAKE_BUILD_TYPE "Debug")set(CMAKE_DEBUG_POSTFIX d)endif()
# -------------------------------------------------------------------------------------------
#[[
设置构建目录
]]if(project_debug)set(build_dir out/build/x64-Debug)else()set(build_dir out/build/x64-Release)endif()
# -------------------------------------------------------------------------------------------
#[[
全局引入的头文件
]]
# 当前项目目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# -------------------------------------------------------------------------------------------
#[[
全局变量
]]
# 每个目标源文件所在目录(相对于根目录)set(main_dir src/main)set(human_dir src/human)
######### 主程序 变量
# 主程序可执行文件路径
set(main_binary_dir ${CMAKE_INSTALL_PREFIX}/${main_dir})string(REPLACE install build main_binary_dir ${main_binary_dir})
######### human 库 变量
#human库路径set(human_library_dir ${CMAKE_INSTALL_PREFIX}/${human_dir})string(REPLACE install build human_library_dir ${human_library_dir})#human库名称, 不带后缀set(human_lib_name human)#human库名称, 带后缀set(human_lib_file_name ${human_lib_name}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
# -------------------------------------------------------------------------------------------
#[[
输出信息
]]message(STATUS "CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}")message(STATUS "main_binary_dir ${main_binary_dir}")message(STATUS "human_library_dir ${human_library_dir}")message(STATUS "human_lib_name ${human_lib_name}")message(STATUS "human_lib_file_name ${human_lib_file_name}")if(project_debug)message(STATUS "current project compile type is debug")else()message(STATUS "current project compile type is release")endif()add_subdirectory(src)
src/CMakeListst.txt
add_subdirectory(main)add_subdirectory(human)
src/human/CMakeListst.txt
# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 源文件列表
aux_source_directory(. HUMAN_SRCS)
# 设置生成目录
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)
# 生成动态库, 默认生成的是静态库
add_library(${human_lib_name} SHARED ${HUMAN_SRCS})
# 指定动态库版本
#VERSION 动态库版本#SOVERSION API版本set_target_properties(${human_lib_name} PROPERTIES VERSION 1.0 SOVERSION 1)
# 指定 msvc 编译模式
if(project_debug)target_link_options(${human_lib_name} PRIVATE /DEBUG)else()target_link_options(${human_lib_name} PRIVATE /RELEASE)endif()
# 构建后复制到主程序 exe 所在路径
if(project_debug)add_custom_command(TARGET ${human_lib_name} POST_BUILD
COMMAND ${CMAKE_COMMAND}-E copy ${human_library_dir}/${human_lib_file_name} ${main_binary_dir}/${human_lib_file_name})else()add_custom_command(TARGET ${human_lib_name} POST_BUILD
COMMAND ${CMAKE_COMMAND}-E copy ${human_library_dir}/${human_lib_file_name} ${main_binary_dir}/${human_lib_file_name})endif()
src/man/CMakeListst.txt
# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 源文件列表
aux_source_directory(. MAIN_SRCS)
# 可执行文件目录
#set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/dist)
# 使用指定的源文件向项目添加可执行文件
add_executable(${PROJECT_NAME} ${MAIN_SRCS})
# 声明链接时需要参与的依赖库名称
target_link_libraries(${PROJECT_NAME} ${human_lib_name})
# 指定 msvc 编译模式
if(project_debug)target_link_options(${PROJECT_NAME} PRIVATE /DEBUG)else()target_link_options(${PROJECT_NAME} PRIVATE /RELEASE)endif()
cmake 生成
debug 生成如下
1> 已为默认配置“x64-Debug”启动 CMake 生成。
1> 命令行: "C:\WINDOWS\system32\cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "D:\PROGRAM\MICROSOFT\VS2019\IDE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="F:\2023\code\cmake\hello_cmake_project_vs\out\install\x64-Debug" -DCMAKE_CXX_COMPILER:FILEPATH="D:/program/microsoft/vs2019/ide/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe" -DCMAKE_MAKE_PROGRAM="D:\PROGRAM\MICROSOFT\VS2019\IDE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\Ninja\ninja.exe" "F:\2023\code\cmake\hello_cmake_project_vs" 2>&1"1> 工作目录: F:\2023\code\cmake\hello_cmake_project_vs\out\build\x64-Debug
1>[CMake] -- The CXX compiler identification is MSVC 19.29.30133.0
1>[CMake] -- Detecting CXX compiler ABI info
1>[CMake] -- Detecting CXX compiler ABI info - done1>[CMake] -- Check for working CXX compiler: D:/program/microsoft/vs2019/ide/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
1>[CMake] -- Detecting CXX compile features
1>[CMake] -- Detecting CXX compile features - done1>[CMake] -- CMAKE_BUILD_TYPE : Debug
1>[CMake] -- main_binary_dir F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Debug/src/main
1>[CMake] -- human_library_dir F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Debug/src/human
1>[CMake] -- human_lib_name human
1>[CMake] -- human_lib_file_name humand.dll
1>[CMake] -- current project compile type is debug
1>[CMake] -- Configuring done1>[CMake] -- Generating done1>[CMake] -- Build files have been written to: F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Debug
1> 已提取 CMake 变量。
1> 已提取源文件和标头。
1> 已提取代码模型。
1> 已提取工具链配置。
1> 已提取包含路径。
1> CMake 生成完毕。
release 生成如下
1> 已为配置“x64-Release”启动 CMake 生成。
1> 命令行: "C:\WINDOWS\system32\cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "D:\PROGRAM\MICROSOFT\VS2019\IDE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:PATH="F:\2023\code\cmake\hello_cmake_project_vs\out\install\x64-Release" -DCMAKE_CXX_COMPILER:FILEPATH="D:/program/microsoft/vs2019/ide/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe" -DCMAKE_MAKE_PROGRAM="D:\PROGRAM\MICROSOFT\VS2019\IDE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\Ninja\ninja.exe" "F:\2023\code\cmake\hello_cmake_project_vs" 2>&1"1> 工作目录: F:\2023\code\cmake\hello_cmake_project_vs\out\build\x64-Release
1>[CMake] -- The CXX compiler identification is MSVC 19.29.30133.0
1>[CMake] -- Detecting CXX compiler ABI info
1>[CMake] -- Detecting CXX compiler ABI info - done1>[CMake] -- Check for working CXX compiler: D:/program/microsoft/vs2019/ide/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
1>[CMake] -- Detecting CXX compile features
1>[CMake] -- Detecting CXX compile features - done1>[CMake] -- CMAKE_BUILD_TYPE : Release
1>[CMake] -- main_binary_dir F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Release/src/main
1>[CMake] -- human_library_dir F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Release/src/human
1>[CMake] -- human_lib_name human
1>[CMake] -- human_lib_file_name human.dll
1>[CMake] -- current project compile type is release
1>[CMake] -- Configuring done1>[CMake] -- Generating done1>[CMake] -- Build files have been written to: F:/2023/code/cmake/hello_cmake_project_vs/out/build/x64-Release
1> 已提取 CMake 变量。
1> 已提取源文件和标头。
1> 已提取代码模型。
1> 已提取工具链配置。
1> 已提取包含路径。
1> CMake 生成完毕。
要点
- 从 vs 的 cmake 输出可看出, vs 设置了
-DCMAKE_CXX_COMPILER:FILEPATH=".../cl.exe"
,-DCMAKE_MAKE_PROGRAM="...\ninja.exe"
. 关于ninja
的文档可在https://ninja-build.org/找到. 简单来说,ninja
是个Makefile/make
的替代品, 与 linux 对比的话, 就是把gcc
换成了cl.exe
, 把make
换成了ninja
- 与之前的使用方式相同, 构建 release 版本, 需要手动设置
set(CMAKE_BUILD_TYPE "Release")
关于单元测试
参考
浅谈c++单元测试
C++单元测试工具——doctest
doctest
cmake 整合 doctest 示例
修改的是 vscode 的版本
目录结构
F:\2023\code\cmake\hello_cmake_project>tree /f
卷 dox 的文件夹 PATH 列表
卷序列号为 34D2-6BE8
F:.
│ build.txt
│ CMakeLists.txt
│
├─.vscode
│ launch.json
│ tasks.json
│
├─include
│ └─human
│ person.h
│
├─src
│ │ CMakeLists.txt
│ │
│ ├─human
│ │ CMakeLists.txt
│ │ person.cpp
│ │
│ └─main
│ CMakeLists.txt
│ main.cpp
│
├─test
│ CMakeLists.txt
│ hellocmaketest.cpp
│
└─third
└─doctest
doctest.h
F:\2023\code\cmake\hello_cmake_project>
顶层 CMakeLists.txt
# 该项目所需 cmake 的最小版本, 如果 cmake 版本小于设置的版本, cmake 将停止处理并报错
cmake_minimum_required(VERSION 3.0)
# 设置项目名称和语言
project(hello_cmake_project CXX)set(CMAKE_BUILD_TYPE DEBUG)
# 指定 c++14set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED True)#human库名称set(lib_human human)add_subdirectory(src)
# 下面的就是测试相关的
# 传递项目根目录
set(proj_dir ${PROJECT_SOURCE_DIR})
# 添加测试项目所在目录
add_subdirectory(test)
# 必须添加这两行, 而且必须在顶层 CMakeLists.txt 添加
enable_testing()add_test(NAME hello_cmake_test COMMAND hello_cmake_test)
test 项目
CMakeLists.txt
# 该项目所需 cmake 的最小版本, 如果 cmake 版本小于设置的版本, cmake 将停止处理并报错
cmake_minimum_required(VERSION 3.0)
# 设置项目名称和语言
project(hello_cmake_test CXX)set(CMAKE_BUILD_TYPE DEBUG)
# 指定 c++14set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED True)include_directories(${proj_dir}/include)include_directories(${proj_dir}/third)aux_source_directory(. TEST_SRCS)set(EXECUTABLE_OUTPUT_PATH ${proj_dir}/dist)add_executable(${PROJECT_NAME} ${TEST_SRCS})target_link_libraries(${PROJECT_NAME} ${lib_human})
hellocmaketest.cpp
#defineDOCTEST_CONFIG_IMPLEMENT_WITH_MAIN#include"doctest/doctest.h"#include"human/person.h"intadd(int x ,int y ){return x + y;}TEST_CASE("test add"){CHECK(3==add(1,2));}TEST_CASE("test person"){
Person *p =newPerson();
std::string s ="hello world";CHECK(0== p->SayHello().compare(s));}
使用过程
F:\2023\code\cmake\hello_cmake_project>cmake -S.-G"Unix Makefiles"-B build && cmake --build build --config debug
-- The CXX compiler identification is GNU 10.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/program/tdmgcc/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: F:/2023/code/cmake/hello_cmake_project/build
[12%] Building CXX object src/human/CMakeFiles/human.dir/person.cpp.obj
[25%] Linking CXX shared library F:/2023/code/cmake/hello_cmake_project/dist/libhuman.dll
[25%] Built target human
[37%] Building CXX object src/main/CMakeFiles/hello_cmake_project.dir/main.cpp.obj
[50%] Linking CXX executable F:/2023/code/cmake/hello_cmake_project/dist/hello_cmake_project.exe
[50%] Built target hello_cmake_project
[62%] Building CXX object src/human/CMakeFiles/human_static.dir/person.cpp.obj
[75%] Linking CXX static library F:/2023/code/cmake/hello_cmake_project/dist/libhuman.a
[75%] Built target human_static
[87%] Building CXX object test/CMakeFiles/hello_cmake_test.dir/hellocmaketest.cpp.obj
[100%] Linking CXX executable F:/2023/code/cmake/hello_cmake_project/dist/hello_cmake_test.exe
[100%] Built target hello_cmake_test
F:\2023\code\cmake\hello_cmake_project>.\dist\hello_cmake_project.exe
hello world
hello world
F:\2023\code\cmake\hello_cmake_project>.\dist\hello_cmake_test.exe
[doctest] doctest version is "2.4.9"[doctest] run with "--help"for options
===============================================================================[doctest]test cases: 2|2 passed |0 failed |0 skipped
[doctest] assertions: 2|2 passed |0 failed |[doctest] Status: SUCCESS!
F:\2023\code\cmake\hello_cmake_project>
使用 python 控制 cmake 构建的生命周期
使用的时候应当是什么样的
使用方式应该是这样:
F:\2023\code\cmake\hello_cmake_project> cm help
build 编译
run 运行
test 测试
doxygen 生成 doxygen 文档
F:\2023\code\cmake\hello_cmake_project> cm build
项目编译中...
项目编译完毕
F:\2023\code\cmake\hello_cmake_project> cm run
启动项目...
hello world
hello world
项目运行结束
F:\2023\code\cmake\hello_cmake_project> cm test
开始测试
[doctest] doctest version is "2.4.9"[doctest] run with "--help"for options
===============================================================================[doctest]test cases: 2|2 passed |0 failed |0 skipped
[doctest] assertions: 2|2 passed |0 failed |[doctest] Status: SUCCESS!
测试结束
F:\2023\code\cmake\hello_cmake_project> cm doxygen
生成 doxygen 文档
应当有什么功能
除了上述的几个命令行参数之外, 还应该有
- 类似git 的 hook 一样, 可以在构建前后或测试前后做一些自定义的动作
- 类似
npm init
一样初始化一个项目 - 自定义命令别名
- windows 和 linux 均需打包测试 提供
python
源码而不是二进制(暂时没搞定)
有哪些功能没有做
构建之前的检查
通常来说, 构建工具都有检查功能, 比如校验构建脚本是否正确, 但是目前没啥必要
依赖管理
比如和
vcpkg
或者
Conan
的整合. 这部分做起来难度太高
和 ide 的集成
比如写个 vscode 或者 vs 的插件, 鼠标点一点就能直接构建, 测试, 生成文档, 发布等等. 这个难度也不小.
参考: VSCode 插件开发教程
下一篇:
cmake 04 使用 python 管理 cmake 工程
版权归原作者 小代码2016 所有, 如有侵权,请联系我们删除。