CMAKE学习

发布时间:2024年01月17日


CMake是一个项目构建工具,并且是跨平台的,Makefile(通过 make 命令进行项目的构建),大多是IDE软件都集成了make,比如:VS 的 nmake、linux 下的 GNU make,makefile 通常依赖于当前的编译平台,而且编写 makefile 的工作量比较大,解决依赖关系时也容易出错。CMake的优点:

  • 跨平台
  • 能够管理大型项目
  • 简化编译构建过程和编译过程
  • 可扩展:可以为cmake编写特定功能的模块,扩充cmake功能。

VScode 文件编译和调试

  1. 单文件编译调试直接点就行了。
  2. 项目源文件中创建CMakeLists.txt。编写CMakeLists.txt文件
  3. vscode中配置cmake,按快捷键 ctrl+shift+p,在窗口中搜索 CMake configure,选择编译器,或者在终端中,创建build文件夹,在build文件夹下输入cmake … 这一步会生成build文件夹中的相关文件,以及makefile文件。
  4. 终端输入make,就会生成可执行文件。
  5. 调试:生成一个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": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/build/sort", //1. 可执行文件的绝对路径,需要随着调试文件的变化而变化
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}/build/", //2.路径,也需要写好
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Build", //前置操作,会往task.json中寻找Build操作
            "miDebuggerPath": "/usr/bin/gdb" //gdb,默认的,如果需要修改,需要自己改动
        }

    ]
}
  1. 配置tasks.json,得到任务文件,后续改动代码,比较方便的进行自动修改调试。
{
    "version": "2.0.0",
    "options": {
        "cwd": "${fileDirname}/build/" //3.路径,也需要配置好,和2配置的一样
    },

    "tasks": [
        {
            "label": "cmake",
            "type": "shell",
            "command": "cmake",
            "args": [
                ".."
            ]
        },
        {
            "label": "make",
            "group":{
                "kind":"build",
                "isDefault":true
            },
            "command": "make",
            "args":[
            ]
        },
        {
            "label":"Build", //Build操作
            "dependsOn":[ //会先后执行cmake和make
                "cmake",
                "make"                
            ]
        }
    ]
}


CMake语法

  1. cmake_minimum_required:指定使用的 cmake 的最低版本
  2. project:定义工程名称
  3. add_executable:定义工程会生成一个可执行程序
  4. set:定义变量,还可以指定C++编译的标准为C++14等(target_compile_features也可以),指定各项设置,如输出路径等。
  5. aux_source_directory:可以查找某个路径下的所有源文件
  6. file:可以搜索目录中的所有文件
  7. include_directories:设置包含的头文件目录
  8. add_library:制作静态或动态库,在Linux中,静态库名字分为三部分:lib+库名字+.a,只需要指定出库的名字。动态库类似,只不过后缀为.so。
  9. LIBRARY_OUTPUT_PATH:设置库文件的输出路径,这个宏对应静态库文件和动态库文件都适用。

两个重要的宏定义:

  • PROJECT_SOURCE_DIR:项目路径
  • CMAKE_CURRENT_SOURCE_DIR:cmake所在文件夹路径。
cmake_minimum_required(VERSION 3.0) #指定使用的 cmake 的最低版本

project(SortMake) # 设置项目名称,参数可以随意指定
include_directories(include)# 设置包含的头文件目录

aux_source_directory(src SRC_SUB) # 搜索 src 目录下所有的源文件,并将结果列表存储在变量 SRC_SUB 中
aux_source_directory(. SRC_CUR) # 搜索 当前 目录下所有的源文件,并将结果列表存储在变量 SRC_CUR 中

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 14) #设置CMAKE编译版本为14
set(CMAKE_BUILD_TYPE Debug) # debug版本

add_library(calc STATIC ${SRC_SUB}) # calc是静态库的名字,STATIC是关键字,不可变更。${SRC_SUB}是需要制作静态库的文件夹
# 最终会将src文件夹下的文件生成静态库文件libcalc.a

add_library(calcs SHARED ${SRC_SUB}) # calcs是动态库的名字,SHARED是关键字,不可变更。${SRC_SUB}是需要制作动态库的文件夹
# 最终会将src文件夹下的文件生成静态库文件libcalcs.so

# 设置动态库/静态库生成路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
 
add_executable(sort ${SRC_SUB} ${SRC_CUR}) # 指定使用源文件${SRC_SUB} ${SRC_CUR},生成可执行文件sort
target_compile_features(sort PRIVATE cxx_std_14) #也可以用target_compile_features命令用于指定目标sort需要私有编译特性cxx_std_14,它将确保编译器使用C++14标准。

创建build文件夹,切换到build,shell执行cmake .. 命令,会生成makefile文件,此时再执行make命令,就可以对项目进行构建得到所需的可执行程序了。

  1. link_libraries:链接静态库,静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
  2. target_link_libraries:链接动态库,也可以链接静态库,默认权限为public,动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存。
# 指定需要链接的库的路径,lib库中包含静态库文件和动态库文件
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 链接静态库
link_libraries(calc)
 
add_executable(sort ${SRC_SUB} ${SRC_CUR}) # 指定使用源文件${SRC_SUB} ${SRC_CUR},生成可执行文件sort
target_compile_features(sort PRIVATE cxx_std_14) #也可以用target_compile_features命令用于指定目标sort需要私有编译特性cxx_std_14,它将确保编译器使用C++14标准。

# 指定可执行程序要链接的动态库,这里的写法是sort链接的时候,需要链接线程库pthread和第三方库calcs
target_link_libraries(sort pthread calcs)
  1. message:日志,有各个级别的输出信息。
  2. 变量操作:
    • set可以进行字符串拼接,将结果存储到第一个参数中。
    • list命令比set更加强大,指定APPEND参数,可以进行数据追加。REMOVE_ITEM参数,可以移除字符串

嵌套

嵌套的 CMake 也是一个树状结构,最顶层的 CMakeLists.txt 是根节点,其次都是子节点。

  • 根节点CMakeLists.txt中的变量全局有效
  • 父节点CMakeLists.txt中的变量可以在子节点中使用
  • 子节点CMakeLists.txt中的变量只能在当前节点中使用
  • add_subdirectory:可以添加子目录
cmake_minimum_required(VERSION 3.0)
project(test)
# 定义变量
# 静态库生成的路径
set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
# 测试程序生成的路径
set(EXEC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin)
# 头文件目录
set(HEAD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)

set(CMAKE_BUILD_TYPE Debug) # debug版本
# 静态库的名字
set(CALC_LIB calc)
set(SORT_LIB sort)
# 可执行程序的名字
set(APP_NAME_1 test1)
set(APP_NAME_2 test2)
# 添加子目录
add_subdirectory(calc)
add_subdirectory(sort)
add_subdirectory(test1)
add_subdirectory(test2)

参考列表
https://www.bilibili.com/video/BV1fy4y1b7TC/
https://subingwen.cn/cmake/CMake-primer/

文章来源:https://blog.csdn.net/cliu1_16/article/details/135554343
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。