Tips:需要对编译原理有一定了解,内容选自 github
===================================================
A-基础
1-CMakeLists.txt
- 存储所有CMake命令的文件
2-Minimum CMake version
- 指定支持的最低CMake版本
cmake_minimum_required(VERSION 3.5)
3-Projects
- 项目名称
project(hello_cmake)
4-Creating an Executable
- 构建可执行文件,第一个参数是要生成的可执行文件的名称,第二个参数是要编译的源文件的列表。
add_executable(hello_cmake main.cpp)
===================================================
B-头文件
1-Directory Paths
- CMake语法指定了许多变量 ,可用于帮助您在项目或源代码树中找到有用的目录
Variable | Info(直译比较难以理解) |
---|---|
CMAKE_SOURCE_DIR | The root source directory |
CMAKE_CURRENT_SOURCE_DIR | The current source directory if using sub-projects and directories. |
PROJECT_SOURCE_DIR | The source directory of the current cmake project. |
CMAKE_BINARY_DIR | The root binary / build directory. This is the directory where you ran the cmake command. |
CMAKE_CURRENT_BINARY_DIR | The build directory you are currently in. |
PROJECT_BINARY_DIR | The build directory for the current project. |
2-Source Files Variable
- 设置一些关于源文件的环境变量提高可读性
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
- 另一种方法是使用GLOB命令使用通配符模式匹配来查找文件。
file(GLOB SOURCES "src/*.cpp")
- 对于现代CMake,不建议对源使用变量。相反,通常直接在add_xxx函数中声明源。
3-Including Directories
- 使用target_include_directories()来包含头文件。编译此目标时,会通过-I标志将这些目录添加到编译器,例如
-I /directory/path
target_include_directories(target
PRIVATE # PRIVATE/INTERFACE/PUBILC 指定包含的范围
${PROJECT_SOURCE_DIR}/include
)
===================================================
C-静态库
1-Adding a Static Library
- add_library()函数用于从某些源文件创建一个库
add_library(hello_library STATIC
src/Hello.cpp
)
- 如前面的示例所述,我们将源文件直接传递给add_library调用,这是现代CMake的建议。
2-Populating Including Directories
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
-cmake中的变量作用域
scopes | meaning |
---|---|
PRIVATE | the directory is added to this target’s include directories |
INTERFACE | the directory is added to the include directories for any targets that link this library. |
PUBLIC | As above, it is included in this library and also any targets that link this library. |
3-Linking a Library
- 创建可执行文件时,必须告知编译器使用了什么库。可以使用target_link_libraries()函数完成此操作。
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello_library
)
#编译器实例 /usr/bin/c++ CMakeFiles/hello_binary.dir/src/main.cpp.o -o hello_binary -rdynamic libhello_library.a
===================================================
D-动态库
1-Adding a Shared Library-添加动态库
add_library(hello_library SHARED
src/Hello.cpp
)
2-Alias Target-目标别名
- 目标别名在只读上下文中可以代替真实目标名称(只读代表无法更改)
add_library(hello::library ALIAS hello_library)
3-Linking a Shared Library-链接动态库文件
add_executable(hello_binary
src/main.cpp
)
target_link_libraries(hello_binary
PRIVATE
hello::library
)
===================================================
E-安装
1-Installing
- 安装说白了是将编译好的文件复制到安装目录。
- Cmake通过make install允许用户安装二进制文件,库和其他文件。安装位置由变量CMAKE_INSTALL_PREFIX控制。
- make install跑完后,CMake的生成install_manifest.txt文件,其中包括所有已安装的文件的详细信息。
#二进制文件
install (TARGETS cmake_examples_inst_bin
DESTINATION bin)
#库文件
install (TARGETS cmake_examples_inst
LIBRARY DESTINATION lib)
#头文件
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION include)
#配置文件
install (FILES cmake-examples.conf
DESTINATION etc)
===================================================
F-build-type
1-介绍
- CMake具有许多内置的构建配置,可用于编译您的项目。这些指定了优化级别以及调试信息是否包含在二进制文件中
level | meaning |
---|---|
Release | Adds the -O3 -DNDEBUG(屏蔽assert) flags to the compiler |
Debug | Adds the -g flag |
MinSizeRel | Adds -Os -DNDEBUG |
RelWithDebInfo | Adds -O2 -g -DNDEBUG flags |
2-设置构建类型
command line: cmake .. -DCMAKE_BUILD_TYPE=Release
3-设置默认构建类型 in CMakeLists.txt
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()
===================================================
G-编译标志
1-介绍
- CMake支持以多种不同方式设置编译标志:
- using target_compile_definitions() function
- using the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS variables.
2-Set Per-Target C++ Flags-设置每个目标C ++标志
- 在现代CMake中设置C ++标志的推荐方法是使用按目标标志,可以通过target_compile_definitions()将其填充到其他目标。
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
# This will cause the compiler to add the definition -DEX3 when compiling the target.
3-Set Default C++ Flags-设置默认C ++标志
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
- CACHE STRING "Set C++ Compiler Flags" FORCE上面命令的值用于强制在CMakeCache.txt文件中设置此变量。
- 设置后,CMAKE_C_FLAGS和CMAKE_CXX_FLAGS将为该目录或所有包含的子目录中的所有目标全局设置编译器标志/定义。现在不建议将该方法用于一般用途,并且首选使用target_compile_definitions函数。
4-设置CMake标志
command line: cmake .. -DCMAKE_CXX_FLAGS = “ -DEX3”
===================================================
H-第三方库
1-介绍
- 几乎所有不平凡的项目都将要求包含第三方库,头文件或程序。CMake支持使用该find_package()功能查找这些工具的路径。这将从中CMAKE_MODULE_PATH列表中搜索格式为“ FindXXX.cmake”的CMake模块。在Linux上,默认搜索路径将包括/usr/share/cmake/Modules。
2-Finding a Package-寻找第三方库
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
param | meaning |
---|---|
Boost | 库名称,用于查找模块文件FindBoost.cmake |
1.46.1 | 查找的Boost的最低版本 |
REQUIRED | 告诉模块这是必需的,如果失败,它将无法找到 |
COMPONENTS | 要查找的库列表 |
3-Checking if the package is found-检查第三方库
- 大多数随附的软件包将设置一个变量XXX_FOUND,该变量可用于检查该软件包在系统上是否可用。
if(Boost_FOUND)
message ("boost found")
include_directories(${Boost_INCLUDE_DIRS})
else()
message (FATAL_ERROR "Cannot find Boost")
endif()
4-Exported Variables-第三方库导出变量
- 找到软件包后,它通常会导出变量,这些变量可以通知用户在哪里可以找到库,标头或可执行文件。与XXX_FOUND 变量类似,它们是特定于软件包的,通常记录在FindXXX.cmake文件顶部 。例如
Boost_INCLUDE_DIRS - boost 头文件目录.
5-Alias / Imported targets
大多数现代CMake库在其模块文件中导出ALIAS目标。导出目标的好处是它们也可以填充包含目录和链接的库。
例如,从CMake v3.5 +开始,Boost模块支持此功能。与使用自己的ALIAS目标进行库释放相似,模块中的ALIAS可以使引用找到的目标更加容易。
在Boost的情况下,所有目标均使用
Boost::
标识符然后使用子系统的名称导出
===================================================
I-compiling-with-clang
1-Compiler Option-编译器选项
- CMake提供了一些选项来控制用于编译和链接代码的程序
- CMAKE_C_COMPILER-用于编译c代码的程序。
- CMAKE_CXX_COMPILER-用于编译c ++代码的程序。
- CMAKE_LINKER-用于链接二进制文件的程序。
2-Setting Flags-设置标志
cmake .. -DCMAKE_C_COMPILER = clang-3.6 -DCMAKE_CXX_COMPILER = clang ++-3.6
===================================================
L-cpp-standard-C++标准
a.common-method
1-Checking Compile flags-检查编译标志
- CMake支持尝试使用传递给函数的任何标志来编译程序CMAKE_CXX_COMPILER_FLAG。然后将结果存储在您传递的变量中
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
# 本示例将尝试使用标志编译程序-std=c++11并将结果存储在变量中COMPILER_SUPPORTS_CXX11。
# 该行include(CheckCXXCompilerFlag)告诉CMake包括此功能以使其可用
2-Adding the flag-添加标志
- 一旦确定编译是否支持标志,就可以使用将此标志添加到目标中。在此示例中,我们使用
CMAKE_CXX_FLAGS
来将标志传播给所有目标
if(COMPILER_SUPPORTS_CXX11)#
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)#
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
b-cxx-standard
1-Using CXX_STANDARD property
- 设置[CMAKE_CXX_STANDARD]变量将导致
CXX_STANDARD
所有目标上的属性。这使CMake在编译时间设置适当的标志。
c-compile-features
1-Using target_compile_features-使用target_compile_features
- 在目标上调用target_compile_features函数将查看传入的功能,并确定要用于目标的正确编译器标志。
target_compile_features(hello_cpp11 PUBLIC cxx_auto_type)