CMake 学习笔记 01 Basic

Tutorial 仓库
希望不会断更qwq

A hello-cmake

基础结构

cmake_minimum_required(VERSION 3.5)
project(项目名)
add_executeable(可执行文件名 文件列表)
  • project() 生成一个变量 ${PROJECT_NAME} 可以供后续使用;
  • 构建目录可以在当前目录执行
    $ cmake .
  • 也可以在新文件夹下
$ mkdir build && cd $_
$ cmake ..

然后执行make 即可。

B hello-headers

带有头文件的编译
文件结构

├── CMakeLists.txt
├── include
│   └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp

介绍一些可用的变量
CMAKE_SOURCE_DIR 代码目录
CMAKE_CURRENT_SOURCE_DIR (如果有子工程的话)当前代码目录
PROJECT_SOURCE_DIR 当前工程的代码目录
CMAKE_BINARY_DIR 一般指向./build ,就是你运行cmake的地方
CMAKE_CURRENT_BINARY_DIR 当前所在的构建目录
PROJECT_BINARY_DIR 当前工程的构建目录

设置变量

set(变量名 一些文件)
add_executeable(${PROJECT_NAME} xxx)

例如,

set(SRC src/a.cpp src/b.cpp)
add_executeable(${PROJECT_NAME} ${SRC})

最后添加头文件

target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/include)

一种不是很modern的方式添加文件还可以这样做:

file(GLOB SRC "src/*.cpp")

C static-library

生成静态库,链接静态库
目录结构

├── CMakeLists.txt
├── include
│   └── static
│       └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp

先编译Hello.cpp Hello.h 生成静态库。

add_library(hello_library STATIC src/Hello.cpp)

从代码创建静态库。
然后给这个target加上头文件

target_include_directories(hello_library PUBLIC include/)

设置成PUBLIC, 这样在
– 编译静态库的时候会用到头文件
– 外部链接这个静态库的时候会用到头文件

三种模式

- PRIVATE - 目录添加到这个 target 的包含目录下

- INTERFACE - 目录添加到所有链接这个 target 的包含目录下

- PUBLIC - 上面全部

注意,传递给 target_include_directories 的目录将会是 #include 的工作根目录。
例如, 这里的 #include "static/Hello.h" 就是在 include/这个目录下。
链接库

add_executable(hello_binary src/main.cpp)
target_link_library(hello_binary PRIVATE hello_library)

总的代码

cmake_minimum_required(VERSION 3.5)

project(hello_library)

add_library(hello_library STATIC src/Hello.cpp)
target_include_directories(hello_library PUBLIC include/)

add_executable(hello_binary src/main.cpp)
target_link_libraries(hello_binary PRIVATE hello_library)

D shared library

生成动态库,链接动态库

和 C 类似,只不过需要把 add_library(xxx STATIC ...) 改成 SHARED

别名。add_library(xxx ALIAS yyy) 可以给xxx 改成 yyy

E Installing

生成 make install

变量CMAKE_INSTALL_PREFIX 是安装路径的前缀。
可以通过这样的方式指定

cmake .. -DCMAKE_INSTALL_PREFIX=/some/path  

函数install :
* 指定安装编译后的target
安装 binary : install(TARGET name DESTINATION bin)
这将会安装到 ${CMAKE_INSTALL_PREFIX}/bin
安装library: install(TARGET name LIBRARY DESTINTAION lib)
* 安装include: install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)
安装files: install(FILES name.conf DESTINATION etc)

生成安装清单 install_manifest.txt

完整代码:

cmake_minimum_required(VERSION 3.5)

project(cmake_examples_install)

add_library(cmake_examples_inst SHARED
    src/Hello.cpp
)

target_include_directories(cmake_examples_inst
    PUBLIC 
        ${PROJECT_SOURCE_DIR}/include
)

add_executable(cmake_examples_inst_bin
    src/main.cpp
)
target_link_libraries( cmake_examples_inst_bin
    PRIVATE 
        cmake_examples_inst
)

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)

G compile-flags

设置编译参数
给每一个目标都设置:

target_compile_definitions(name PRIVATE EX3)

这样会给name 添加上-DEX3这样的参数。

也可以在全局设置 CMAKE_CXX_FLAGS 变量:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "C++ Compiler Flags" FORCE)

H third-party-library

链接第三方库
find_package()
CMake 的默认寻找路径 CMAKE_MODULE_PATH/usr/share/cmake/Moudules/,对应的组件文件是FindXXX.cmake
每一个这样的文件头部都详细写明了find_package()里的参数和导出变量。
如果找到,会设置XXX_FOUND
例如,如果使用Boost::filesystem

find_package(BOOST 1.73.0 REQUIRED COMPONENTS filesystem system)  

这样CMake 便会去CMAKE_MODULE_PATH中寻找FindBoost.cmake

Modern Cmake 引入了alias。如果库支持(在FindXXX.cmake开头写明)的话,可以直接在target 后这样指定:

target_link_libraries(name PRIVATE Boost::filesystem)

如果不支持,那就需要手动写了
${xxx_INCLUDE_DIRS}${xxx_LIBRARY}

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}
)

I Compiling-with-clang

指定使用的编译器
三个变量:

CMAKE_C_COMPILER - The program used to compile c code.
CMAKE_CXX_COMPILER - The program used to compile c++ code.
CMAKE_LINKER - The program used to link your binary.

可以在运行CMake的时候指定:
CMake .. -Dxxxxx=xxxx

发表评论