CMake快速使用+VSCode开发(调试)

CMake学习使用

1、cmake安装和入门使用

1.1 安装
sudo apt install cmake	# 即可安装

cmake -version  # 查看安装的cmake版本

1.2 简单程序使用cmake

在指定的目录中作为项目目录,里面只有一个Apply.cpp文件。此外为了使用cmake,需要有一个CMakeLists.txt文件。内容如下:

在项目目录中创建一个build文件夹,然后进入该目录进行命令的操作。如下:

此时,有了Makefile文件,然后可以使用make命令来生成可执行程序app,如下:

最后可以使用app来执行程序。如果需要删除app可执行文件,可以使用make clean然后app就会被清理掉,再使用make又可以重新生成。

1.3 总结三个cmake命令
# 1、设置对cmake的最小版本,这里设置了要求的最低版本是3.0
cmake_minimum_required(VERSION 3.0)

# 2、设置工程名为apply,此外还可以设置工程的版本,以及对工程的描述。
project(apply VERSION 1.0 DESCRIPTION "这是一个简单的工程")

# 3、生成可执行文件
add_executable(app Apply.cpp)
# add_executable(exename source1 source2 ... sourceN)
# 第一个参数为可执行程序名,后面的是n多个cpp文件

2、项目级的组织结构

2.1 项目结构安排

4.0.1目录是项目目录,其中include是项目的头文件,所有头文件都放在这里面;src是cpp源文件的目录;build是cmake命令生成的相关的文件的目录(Makefile);bin目录是make命令之后生成的目标对象的存放目录(可执行文件、静态库、动态库)。CMakeLists.txt文件内容如下:

# cmake配置

# 1、设置对cmake的最小版本
cmake_minimum_required(VERSION 3.0)

# 2、设置工程名
project(apply VERSION 12.0 DESCRIPTION "这是一个项目级别的工程")

# 3、指定需要的头文件目录
include_directories(include) # 相对于CMakeLists.txt所在的目录

# 4、获取指定目录下的所有cpp文件,用SRC_LIST变量代替
# 如果src目录下的cpp文件很多,在生成可执行文件时一个个写出来十分不便,所以可以使用这个命令方便使用
# aux_source_directory(src SRC_LIST)

# 4.1
# aux_source_directory虽然能够很方便的获取所有cpp,但是某些情况下有部分cpp不需要,此时可以使用set命令解决
set(
    SRC_LIST 
    ./src/Computer.cpp
    ./src/Log.cpp
    ./src/main.cpp
)

# 5、生成可执行文件,这里的所有cpp文件用变量替代
add_executable(app ${SRC_LIST})

# 6、设置目标对象(可执行文件)的输出目录。即app可执行文件就会输出到bin目录中
# EXECUTABLE_OUTPUT_PATH是cmake中已定义的变量,表示目标二进制可执行文件的存放位置
# PROJECT_SOURCE_DIR 是工程根目录的变量
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

2.2 命令总结
# 1、设置变量set(varname value1 value2 ...)
# 设置cpp文件集合的变量,即通过SRC_LIST替代所有cpp文件
set(SRC_LIST main.cpp foo.cpp bar.cpp)
# 增加编译选项,CMAKE_CXX_FLAGS是cmake系统的变量
set(CMAKE_CXX_FLAGS "-O2 -Wall")

# 2、向工程添加多个特定的头文件搜索路径 --->相当于指定g++编译器的-I参数
# 语法: include_directories(dir1 dir2 ...)
include_directories(include1 include2 ...)

# 3、aux_source_directory获取指定目录下的所有cpp资源文件
aux_source_directory(src SRC_LIST)   # 获取src目录下的cpp资源文件,将其用变量SRC_LIST替代

# 4、添加编译选项,相当于-std=c++11 -g -Wall等
add_compile_options(-Wall -g -std=c++11)

3、静态库和动态库的生成

3.1 项目结构

# cmake配置

# 1、设置对cmake的最小版本
cmake_minimum_required(VERSION 3.0)

# 2、设置工程名
project(apply VERSION 12.0 DESCRIPTION "这是一个关于库的工程")

# 3、指定需要的头文件目录
include_directories(include)

# 4、获取指定目录下的所有cpp文件,用SRC_LIST变量代替
aux_source_directory(src SRC_LIST)

# 5、生成静态库文件和动态库文件,这里的所有cpp文件用变量替代
add_library(kiki_so SHARED ${SRC_LIST})
add_library(kiki_a STATIC ${SRC_LIST})

# 设置输出对象的名称
set_target_properties (kiki_so PROPERTIES OUTPUT_NAME "kiki")
set_target_properties (kiki_a PROPERTIES OUTPUT_NAME "kiki")

# 6、设置库的输出目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

输出结果如下:

3.2 总结命令
# 1、生成库文件(包括动态库和静态库)
add_library(libname [SHARED|STATIC] source1 source2 ... sourceN) 

# 2、设置库的输出目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# EXECUTABLE_OUTPUT_PATH 变量是可执行文件的输出目录变量
# LIBRARY_OUTPUT_PATH 变量是动态库静态库的输出目录变量

# 3、用于设置一个目标的属性。这个命令通常用于设置生成的可执行文件、静态库或动态库的一些属性。
set_target_properties(
    <target> 
    PROPERTIES 
    <prop1> <value1> 
    <prop2> <value2>
    ...
) 
# 所以,第一个target通常是add_libary和add_executable所生成的对象。OUTPUT_NAME属性表示输出的文件名
# 这个命令通常设置的属性有:
* OUTPUT_NAME:指定生成的目标的名称。默认情况下,生成的目标的名称与目标的名称相同,但是可以通过 OUTPUT_NAME 属性来自定义名称。
* LIBRARY_OUTPUT_DIRECTORY:指定生成的动态库的输出目录。默认情况下,生成的动态库将被放置在构建目录下,但是可以通过 LIBRARY_OUTPUT_DIRECTORY 属性来自定义输出目录。
设置这个属性类似于set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)的效果,但是这个会将所有目标都输出到指定的目录中;如果通过这个属性设置,可以设置指定的目标到指定的目录中。如上面的两个库,可以将其中一个动态库对象输出到其他目录中。不可以输出改变静态库的输出目录。
* ARCHIVE_OUTPUT_DIRECTORY:指定生成的静态库的输出目录。同LIBRARY_OUTPUT_DIRECTORY属性的功能。
* RUNTIME_OUTPUT_DIRECTORY:指定生成的可执行文件的输出目录。set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)功能类似。

4、使用静态库和动态库

4.1 项目结构

# 使用动态库静态库

# 设置项目对cmake的最低要求
cmake_minimum_required(VERSION 3.25)

# 设置工程名以及版本
project(AppSO VERSION 2.1)

# 设置头文件变量,其包含所有需要的头文件。
# 第一个目录是本项目的,第二个是动态库的头文件目录,第三个是静态库头文件目录
set(headers include ../3.29.3/include ../3.29.5/include)

# 设置头文件变量到项目中
include_directories(${headers})

# 设置编译选项
add_compile_options(-Wall -std=c++11 -g)

# 设置资源变量
set(cpps src/program.cpp src/main.cpp)

# 生成指定的可执行程序
add_executable(apply ${cpps})

# 情况一:libtps.so放在/usr/lib目录中
# 找到动态库,这里是已经把libtps.so放到了默认索的路径中
# find_library(TPS_LIB_VAR tps) 
# 添加动态库连接相当于g++ -l
# target_link_libraries(app ${TPS_LIB_VAR})

# 情况二:是不将动态libtps.so放到指定默认的搜索目录中
# add_library命令创建一个名为tps的目标,表示一个动态库。IMPORTED选项告诉CMake这个目标不是通过源代码编译出来的,而是外部已经编译好的目标。
# 然后使用set_target_properties命令设置tps目标的属性,其中IMPORTED_LOCATION属性指定了动态库文件的路径。
# 最后,target_link_libraries命令将动态库链接到app可执行文件中。命令如下:
# add_library(tps_obj SHARED IMPORTED)
# set_target_properties(tps_obj PROPERTIES IMPORTED_LOCATION /home/yoyo/workspaces/cmakes/3.29.3/build/libtps.so)
# target_link_libraries(app tps_obj)

# 情况三:与情况二相同,只是操作方式不同
find_library(TPS_LIB_VAR_ tps HINTS /home/yoyo/workspaces/cmakes/3.29.3/build/)
# 第二个目录是静态库文件(静态库比较简单,直接写就行)
set(libs ${TPS_LIB_VAR_} /home/yoyo/workspaces/cmakes/3.29.5/build/libstps.a)

# 连接所有的库
target_link_libraries(apply ${libs})

# 设置可执行程序的输出目录
set_target_properties(apply PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY "../bin"
)
4.2 总结命令
# 1、find_library: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径。表示在指定的目录下找对应库名称的库,用第一个参数变量名称保存。如果不写第三个和第四个参数就默认在系统默认的目录中搜索库。

# 2、target_link_libraries:链接库,第一个参数是可执行程序目标对象,第二个参数是库。

VSCode调试运行

VSCode调试配置

#### launch.json文件配置
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/bin/apply",  ### 配置可执行文件
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "/usr/bin/gdb",
            "preLaunchTask": "Build",       ### 还需要配置任务json文件,配置这个可以避免修改源码之后需要手动make重新生成。这个Build是task.json文件中一个label
        }
    ]
}
#### tasks.json文件配置
{
    "version": "2.0.0",
    "options": {
        "cwd": "${workspaceFolder}/build"
    },
    "tasks": [
        {
            "type": "shell",
            "label": "cmake",
            "command": "cmake",
            "args": [
                ".."
            ]
        },
        {
            "label": "make",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "command": "make",
            "args": []
        },
        {
            "label": "Build",   ### launch.json中选择了这个
            "dependsOrder": "sequence",
            "dependsOn": [
                "cmake",
                "make"
            ]
        }
    ]
}


文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2023年12月7日
下一篇 2023年12月7日

相关推荐