如何深入理解并掌握CMake学习-2中的高级技巧和最佳实践?

2026-04-17 23:472阅读0评论SEO教程
  • 内容介绍
  • 相关推荐

本文共计2279个文字,预计阅读时间需要10分钟。

如何深入理解并掌握CMake学习-2中的高级技巧和最佳实践?

CMake 是一个跨平台的自动化构建系统,它用于管理软件项目的构建过程。它允许开发者定义项目的依赖关系,并自动生成构建脚本,如 Makefile 或 Visual Studio 的项目文件。

以下是对您提供的开头内容的简化改写,不超过100字:

理解与不理解的界限,一定要搞懂基础,边学边实践,从案例中入手。关于 CMake 的介绍,可以参考以下链接:[链接1](https://www.cnblogs.com/pam-sh/p/13885959.) 和 [链接2](https://www.cnblogs.com/pam-sh/p/14800154.)。基础 CMake 示例:`A-hello`。

似懂非懂,一定要搞懂基础的,剩下的边做边学,从案例中入手。

有关cmake的介绍,请参考:
1、www.cnblogs.com/pam-sh/p/13885959.html
2、www.cnblogs.com/pam-sh/p/14800154.html

基础 A-hello-cmake(单文件)

1、文件结构

2、CMakeLists文件

#该项目所支持cmake的最低版本号 cmake_minimum_required(VERSION 3.5) #项目名称 project (hello_cmake) #指定从源文件生成可执行文件 add_executable(hello_cmake main.cpp)

注释:
(1)一般将项目名称作为可执行文件名

add_executable(${PROJECT_NAME} main.cpp) B-hello-headers(多文件)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project (hello_headers) # 创建一个源文件变量,表示多个源文件(cpp) set(SOURCES src/Hello.cpp src/main.cpp ) add_executable(hello_headers ${SOURCES}) # 存在不同文件夹(头文件)时,使用该命令让编译器知道,其中PRIVATE表示include文件的使用范围target_include_directories(hello_headers PRIVATE ${PROJECT_SOURCE_DIR}/include )

注释:
1、变量说明
CMake语法指定了许多变量,可用于帮助在项目或源代码树中查找有用的目录。其中包括:
(1)CMAKE_SOURCE_DIR:项目根目录
(2)CMAKE_CURRENT_SOURCE_DIR:当前项目原目录(若存在子项目)
(3)PROJECT_SOURCE_DIR:当前cmake项目的源目录。
(4)CMAKE_BINARY_DIR:binary / build的目录,即运行cmake的目录
(5)CMAKE_CURRENT_BINARY_DIR:当前所在的build目录
(6)PROJECT_BINARY_DIR:当前项目的build目录

2、在创建源文件变量时可以使用通配符

#利用GLOB命令,识别通配符, file(GLOB SOURCES "src/*.cpp")

3、target_include_directories() 中的权限
(1)PRIVATE:被添加到目标include目录
(2)INTERFACE:被添加到任何链接此库的目录中
(3)PUBLIC:此库和其他目标都有链接

这里include中的头文件,正好对应着文件中过的引用。

C-static-library(静态库)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(hello_library) ############################################################ # Create a library ############################################################ #从源文件中生成一个静态库(libhello_library.a) add_library(hello_library STATIC src/Hello.cpp ) target_include_directories(hello_library PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(hello_binary src/main.cpp ) # 链接静态库,即将该静态库告知编译器 target_link_libraries( hello_binary PRIVATE hello_library )

注释:
1、使用add_library()将源文件转换为静态库
2、使用target_link_libraries()函数导入静态库

D-shared-library(动态库)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(hello_library) ############################################################ # Create a library ############################################################ #从源文件中生成一个分析库/动态库(libhello_library.so/libhello_library.dylib) add_library(hello_library SHARED src/Hello.cpp ) # 给动态库取一个别名,可以代替该库使用 add_library(hello::library ALIAS hello_library) target_include_directories(hello_library PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(hello_binary src/main.cpp ) # 链接此动态库 target_link_libraries( hello_binary PRIVATE hello::library ) E-installing(make install)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(cmake_examples_install) ############################################################ # Create a library ############################################################ #创建一个动态库 add_library(cmake_examples_inst SHARED src/Hello.cpp ) # 引入头文件 target_include_directories(cmake_examples_inst PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(cmake_examples_inst_bin src/main.cpp ) #链接动态库 # link the new hello_library target with the hello_binary target target_link_libraries( cmake_examples_inst_bin PRIVATE cmake_examples_inst ) ############################################################ # Install #${CMAKE_INSTALL_PREFIX}默认是/usr/local ############################################################ # 将生成的可执行文件(cmake_examples_inst_bin)下载到${CMAKE_INSTALL_PREFIX}/bin文件夹下, install (TARGETS cmake_examples_inst_bin DESTINATION bin) # 将生成的动态库(libcmake_examples_inst.dylib)下载到${CMAKE_INSTALL_PREFIX}/lib文件夹下 # Note: may not work on windows install (TARGETS cmake_examples_inst LIBRARY DESTINATION lib) # 将该库的头文件下载到${CMAKE_INSTALL_PREFIX}/include文件夹下 install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include) # 将该库的设置文件下载到${CMAKE_INSTALL_PREFIX}/etc文件夹下 install (FILES cmake-examples.conf DESTINATION etc)

注释:
1、在make install时,若在Windows平台中:

install (TARGETS cmake_examples_inst LIBRARY DESTINATION lib RUNTIME DESTINATION bin)

2、在make install 后,会生成install_manifest.txt文件,记录下载的信息
3、下载位置默认为:/usr/local,可以通过该方式指定下载位置:
(1)在cmake时每次手动指定

cmake .. -DCMAKE_INSTALL_PREFIX=/install/location

(2)在CMakeLists文件中指定

if( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) message(STATUS "Setting default CMAKE_INSTALL_PREFIX path to ${CMAKE_BINARY_DIR}/install") set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING "The path to use for make install" FORCE) endif()

(3)在make时手动指定

make install DESTDIR=指定安装位置 F-build-type(调试类型)

1、文件结构

2、CMakeLists文件

# Set the minimum version of CMake that can be used # To find the cmake version run # $ cmake --version cmake_minimum_required(VERSION 3.5) # 设置默认调试类型(RelWithDebInfo) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message("Setting build type to 'RelWithDebInfo' as none was specified.") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # Set the project name project (build_type) # Add an executable add_executable(cmake_examples_build_type main.cpp)

注释:
1、在调试build时,可以指定调试类型:
(1)Release:命令参数 -O3 -DNDEBUG
(2)Debug:命令参数 -g
(3)MinSizeRel:命令参数 -Os -DNDEBUG
(4)RelWithDebInfo:命令参数 -O2 -g -DNDEBUG
可以手动设置:

cmake .. -DCMAKE_BUILD_TYPE=Release/Debug/MinSizeRel/RelWithDebInfo

也可以设置为默认:

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message("Setting build type to 'RelWithDebInfo' as none was specified.") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif()

也可以在cmake中设置:

G-compile-flags(不太懂)

1、文件结构

2、CMakeLists文件

注释:
1、使用target_compile_definitions()函数

2、使用CMAKE_C_FLAGS 和 CMAKE_CXX_FLAGS变量

H-third-party-library(第三方库)

在cmake中,使用find_package()函数引入第三方库,它能找到CMAKE_MODULE_PATH(默认为/usr/share/cmake/Modules)目录下的FindXXX.cmake文件。
这里以Boost库为例,boost更多可参考:www.cnblogs.com/pam-sh/p/16107753.html

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) # Set the project name project (third_party_include) # 使用库文件系统和系统查找boost库的.cmake文件 find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system) # 检查是否找到boost if(Boost_FOUND) message ("boost found") else() message (FATAL_ERROR "Cannot find Boost") endif() # Add an executable add_executable(third_party_include main.cpp) # 链接boost库 target_link_libraries( third_party_include PRIVATE Boost::filesystem )

注释:
1、find_package()
可以在CMAKE_MODULE_PATH目录下查找类似FindXXX.cmake的文件。
解释一下:find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)

  • Boost:表示引入的第三方库的名字,找的就是FindBoost.cmake
  • 1.46.1:表示支持的boost最低版本
  • REQUIRED:表示这库是必要要有的,不然会出错
  • COMPONENTS:表示会在哪找这个库,filesystem和system表示。。

2、Checking if the package is found
很多库中都会设置一个变量“XXX_FOUND”,能够检查系统中是否存在对应的库,以boost为例:

if(Boost_FOUND) message ("boost found") include_directories(${Boost_INCLUDE_DIRS}) else() message (FATAL_ERROR "Cannot find Boost") endif()

在找到包后,通常会导出一些变量,告知库的头文件、静态文件、可执行文件在哪个位置,这些信息通畅里记录在FindXXX.cmake文件中。
上面例子中的:Boost_INCLUDE_DIRS就表示boost库的头文件。
可以使用ccmakecmake-gui在缓存中检查这些变量。

3、别名
当前很多库会使用别名,更加方便的表示,比如boost库,会使用Boost::导出别名:

  • Boost::boost:仅表示库的头文件
  • Boost::system:表示boost系统库
  • Boost::filesystem :表示文件系统

并且会有依赖关系,当使用Boost::filesystem时,会依赖于Boost::boost 和 Boost::system
如果要有针对的导入,可以使用:

如何深入理解并掌握CMake学习-2中的高级技巧和最佳实践?

target_link_libraries( third_party_include PRIVATE Boost::filesystem )

而不使用别名时,则会单独指出:

# Include the boost headers target_include_directories( third_party_include PRIVATE ${Boost_INCLUDE_DIRS} ) # link against the boost libraries target_link_libraries( third_party_include PRIVATE ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} )

其中:
target_include_directories:指向库的include目录,即表示库的头文件
target_link_libraries:表示库的路径

参考

1、github.com/ttroy50/cmake-examples
这是一个学习cmake的地方,有很多案例可以学习,从浅入深
2、pan.baidu.com/s/1Bvzy0gK4O5vEYti3VV2A5g
提取码:0un9,别人总结的笔记
3、CmakeList入门

本文共计2279个文字,预计阅读时间需要10分钟。

如何深入理解并掌握CMake学习-2中的高级技巧和最佳实践?

CMake 是一个跨平台的自动化构建系统,它用于管理软件项目的构建过程。它允许开发者定义项目的依赖关系,并自动生成构建脚本,如 Makefile 或 Visual Studio 的项目文件。

以下是对您提供的开头内容的简化改写,不超过100字:

理解与不理解的界限,一定要搞懂基础,边学边实践,从案例中入手。关于 CMake 的介绍,可以参考以下链接:[链接1](https://www.cnblogs.com/pam-sh/p/13885959.) 和 [链接2](https://www.cnblogs.com/pam-sh/p/14800154.)。基础 CMake 示例:`A-hello`。

似懂非懂,一定要搞懂基础的,剩下的边做边学,从案例中入手。

有关cmake的介绍,请参考:
1、www.cnblogs.com/pam-sh/p/13885959.html
2、www.cnblogs.com/pam-sh/p/14800154.html

基础 A-hello-cmake(单文件)

1、文件结构

2、CMakeLists文件

#该项目所支持cmake的最低版本号 cmake_minimum_required(VERSION 3.5) #项目名称 project (hello_cmake) #指定从源文件生成可执行文件 add_executable(hello_cmake main.cpp)

注释:
(1)一般将项目名称作为可执行文件名

add_executable(${PROJECT_NAME} main.cpp) B-hello-headers(多文件)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project (hello_headers) # 创建一个源文件变量,表示多个源文件(cpp) set(SOURCES src/Hello.cpp src/main.cpp ) add_executable(hello_headers ${SOURCES}) # 存在不同文件夹(头文件)时,使用该命令让编译器知道,其中PRIVATE表示include文件的使用范围target_include_directories(hello_headers PRIVATE ${PROJECT_SOURCE_DIR}/include )

注释:
1、变量说明
CMake语法指定了许多变量,可用于帮助在项目或源代码树中查找有用的目录。其中包括:
(1)CMAKE_SOURCE_DIR:项目根目录
(2)CMAKE_CURRENT_SOURCE_DIR:当前项目原目录(若存在子项目)
(3)PROJECT_SOURCE_DIR:当前cmake项目的源目录。
(4)CMAKE_BINARY_DIR:binary / build的目录,即运行cmake的目录
(5)CMAKE_CURRENT_BINARY_DIR:当前所在的build目录
(6)PROJECT_BINARY_DIR:当前项目的build目录

2、在创建源文件变量时可以使用通配符

#利用GLOB命令,识别通配符, file(GLOB SOURCES "src/*.cpp")

3、target_include_directories() 中的权限
(1)PRIVATE:被添加到目标include目录
(2)INTERFACE:被添加到任何链接此库的目录中
(3)PUBLIC:此库和其他目标都有链接

这里include中的头文件,正好对应着文件中过的引用。

C-static-library(静态库)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(hello_library) ############################################################ # Create a library ############################################################ #从源文件中生成一个静态库(libhello_library.a) add_library(hello_library STATIC src/Hello.cpp ) target_include_directories(hello_library PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(hello_binary src/main.cpp ) # 链接静态库,即将该静态库告知编译器 target_link_libraries( hello_binary PRIVATE hello_library )

注释:
1、使用add_library()将源文件转换为静态库
2、使用target_link_libraries()函数导入静态库

D-shared-library(动态库)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(hello_library) ############################################################ # Create a library ############################################################ #从源文件中生成一个分析库/动态库(libhello_library.so/libhello_library.dylib) add_library(hello_library SHARED src/Hello.cpp ) # 给动态库取一个别名,可以代替该库使用 add_library(hello::library ALIAS hello_library) target_include_directories(hello_library PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(hello_binary src/main.cpp ) # 链接此动态库 target_link_libraries( hello_binary PRIVATE hello::library ) E-installing(make install)

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) project(cmake_examples_install) ############################################################ # Create a library ############################################################ #创建一个动态库 add_library(cmake_examples_inst SHARED src/Hello.cpp ) # 引入头文件 target_include_directories(cmake_examples_inst PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable(cmake_examples_inst_bin src/main.cpp ) #链接动态库 # link the new hello_library target with the hello_binary target target_link_libraries( cmake_examples_inst_bin PRIVATE cmake_examples_inst ) ############################################################ # Install #${CMAKE_INSTALL_PREFIX}默认是/usr/local ############################################################ # 将生成的可执行文件(cmake_examples_inst_bin)下载到${CMAKE_INSTALL_PREFIX}/bin文件夹下, install (TARGETS cmake_examples_inst_bin DESTINATION bin) # 将生成的动态库(libcmake_examples_inst.dylib)下载到${CMAKE_INSTALL_PREFIX}/lib文件夹下 # Note: may not work on windows install (TARGETS cmake_examples_inst LIBRARY DESTINATION lib) # 将该库的头文件下载到${CMAKE_INSTALL_PREFIX}/include文件夹下 install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include) # 将该库的设置文件下载到${CMAKE_INSTALL_PREFIX}/etc文件夹下 install (FILES cmake-examples.conf DESTINATION etc)

注释:
1、在make install时,若在Windows平台中:

install (TARGETS cmake_examples_inst LIBRARY DESTINATION lib RUNTIME DESTINATION bin)

2、在make install 后,会生成install_manifest.txt文件,记录下载的信息
3、下载位置默认为:/usr/local,可以通过该方式指定下载位置:
(1)在cmake时每次手动指定

cmake .. -DCMAKE_INSTALL_PREFIX=/install/location

(2)在CMakeLists文件中指定

if( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) message(STATUS "Setting default CMAKE_INSTALL_PREFIX path to ${CMAKE_BINARY_DIR}/install") set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING "The path to use for make install" FORCE) endif()

(3)在make时手动指定

make install DESTDIR=指定安装位置 F-build-type(调试类型)

1、文件结构

2、CMakeLists文件

# Set the minimum version of CMake that can be used # To find the cmake version run # $ cmake --version cmake_minimum_required(VERSION 3.5) # 设置默认调试类型(RelWithDebInfo) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message("Setting build type to 'RelWithDebInfo' as none was specified.") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # Set the project name project (build_type) # Add an executable add_executable(cmake_examples_build_type main.cpp)

注释:
1、在调试build时,可以指定调试类型:
(1)Release:命令参数 -O3 -DNDEBUG
(2)Debug:命令参数 -g
(3)MinSizeRel:命令参数 -Os -DNDEBUG
(4)RelWithDebInfo:命令参数 -O2 -g -DNDEBUG
可以手动设置:

cmake .. -DCMAKE_BUILD_TYPE=Release/Debug/MinSizeRel/RelWithDebInfo

也可以设置为默认:

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message("Setting build type to 'RelWithDebInfo' as none was specified.") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif()

也可以在cmake中设置:

G-compile-flags(不太懂)

1、文件结构

2、CMakeLists文件

注释:
1、使用target_compile_definitions()函数

2、使用CMAKE_C_FLAGS 和 CMAKE_CXX_FLAGS变量

H-third-party-library(第三方库)

在cmake中,使用find_package()函数引入第三方库,它能找到CMAKE_MODULE_PATH(默认为/usr/share/cmake/Modules)目录下的FindXXX.cmake文件。
这里以Boost库为例,boost更多可参考:www.cnblogs.com/pam-sh/p/16107753.html

1、文件结构

2、CMakeLists文件

cmake_minimum_required(VERSION 3.5) # Set the project name project (third_party_include) # 使用库文件系统和系统查找boost库的.cmake文件 find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system) # 检查是否找到boost if(Boost_FOUND) message ("boost found") else() message (FATAL_ERROR "Cannot find Boost") endif() # Add an executable add_executable(third_party_include main.cpp) # 链接boost库 target_link_libraries( third_party_include PRIVATE Boost::filesystem )

注释:
1、find_package()
可以在CMAKE_MODULE_PATH目录下查找类似FindXXX.cmake的文件。
解释一下:find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)

  • Boost:表示引入的第三方库的名字,找的就是FindBoost.cmake
  • 1.46.1:表示支持的boost最低版本
  • REQUIRED:表示这库是必要要有的,不然会出错
  • COMPONENTS:表示会在哪找这个库,filesystem和system表示。。

2、Checking if the package is found
很多库中都会设置一个变量“XXX_FOUND”,能够检查系统中是否存在对应的库,以boost为例:

if(Boost_FOUND) message ("boost found") include_directories(${Boost_INCLUDE_DIRS}) else() message (FATAL_ERROR "Cannot find Boost") endif()

在找到包后,通常会导出一些变量,告知库的头文件、静态文件、可执行文件在哪个位置,这些信息通畅里记录在FindXXX.cmake文件中。
上面例子中的:Boost_INCLUDE_DIRS就表示boost库的头文件。
可以使用ccmakecmake-gui在缓存中检查这些变量。

3、别名
当前很多库会使用别名,更加方便的表示,比如boost库,会使用Boost::导出别名:

  • Boost::boost:仅表示库的头文件
  • Boost::system:表示boost系统库
  • Boost::filesystem :表示文件系统

并且会有依赖关系,当使用Boost::filesystem时,会依赖于Boost::boost 和 Boost::system
如果要有针对的导入,可以使用:

如何深入理解并掌握CMake学习-2中的高级技巧和最佳实践?

target_link_libraries( third_party_include PRIVATE Boost::filesystem )

而不使用别名时,则会单独指出:

# Include the boost headers target_include_directories( third_party_include PRIVATE ${Boost_INCLUDE_DIRS} ) # link against the boost libraries target_link_libraries( third_party_include PRIVATE ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} )

其中:
target_include_directories:指向库的include目录,即表示库的头文件
target_link_libraries:表示库的路径

参考

1、github.com/ttroy50/cmake-examples
这是一个学习cmake的地方,有很多案例可以学习,从浅入深
2、pan.baidu.com/s/1Bvzy0gK4O5vEYti3VV2A5g
提取码:0un9,别人总结的笔记
3、CmakeList入门