cmake学习
cmake的流程

cmake 包含不同文件时
准备工作
本教程看的是一个gitbook
安装
pacman -S cmake
cmake的一般构建过程
#在CMakeList.txt所在的目录
mkdir build
cd build
cmake ..
make .
新的cmake这么做
cmake -S . -B build
cmake --build build
#debug cmake
cmake --trace
在软件开发中,构建系统(build system)是用来从源代码生成用户可以使用的目标的自动化工具。目标可以包括库、可执行文件、或者生成的脚本等等。
构建目录呢,用于存储构建系统文件(比如makefile以及其他一些cmake相关配置文件)和构建输出文件(编译生成的中间文件、可执行程序、库)的顶级目录。
set(CMAKE_CXX_STANDARD 17)
之前设置的CMAKE_CXX_STANDARD只是一个可选属性,如果编译器不支持此标准版本,则还是有可能会退化为以前的版本。如果我们想要明确表示需要某个C++标准,则可以通过:
set(CMAKE_CXX_STANDARD_REQUIRED True)
生成器(generaor)
是为构建系统生成文件的工具
从单个源文件到库
单个源文件
cmake_minimum_required(VERSION 3.11)
project("the single exe"
VERSION 1.0.0
LANGUAGES CXX
)
add_executable( result main.cpp )
cmake的语句不区分大小写,但是函数的参数区分
cmake是构建系统生成器
make用来构建项目
最终的可执行文件可以生成到任意目录
cmake --build destination
cmake 里源文件的概念是CMAkeList.txt所在的目录,不是你所创建的文件夹的根目录
| Variable | Info |
|---|---|
| CMAKE_SOURCE_DIR | 工程的顶级目录 |
| CMAKE_CURRENT_SOURCE_DIR | CMakeLists.txt所在的目录 |
| PROJECT_SOURCE_DIR | 工程的顶级目录 |
| CMAKE_CURRENT_LIST_DIR | CMakeLists.txt所在的目录 |
| CMAKE_BINARY_DIR | 如果是内部编译,就指的是工程的顶级目录,如果是外部编译,指的就是工程编译发生的目录 |
| CMAKE_CURRENT_BINARY_DIR | 外部编译时,指的是target目录,内部编译时,指的是顶级目录 |
| PROJECT_BINARY_DIR | 如果是内部编译,就指的是工程的顶级目录,如果是外部编译,指的就是工程编译发生的目录 |
具有类的文件
#第一种方法
#目录结构 头文件在一个文件夹中 main和其他cpp文件在头文件夹外边
cmake_minimum_required(VERSION 3.11)
project("study"
VERSION 1.0.0
LANGUAGES CXX
)
add_executable(${PROJECT_NAME} main.cpp Message.cpp)
target_include_directories(
${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/head
)
#第二种情况
#文件目录 头文件和库放在一个文件夹里,用生成库的方式来比编译
cmake_minimum_required(VERSION 3.11)
project("study"
VERSION 1.0.0
LANGUAGES CXX
)
add_executable(${PROJECT_NAME} main.cpp)
add_subdirectory(head)
#特别要注意这里,这里使用的第三个参数是库的名称,而不是一个目录.下边那个函数的第三个参数才使用的是目录(这个命令代表将库链接到可执行文件中
target_link_libraries(${PROJECT_NAME}
PUBLIC
Message
)
target_include_directories(
${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/head
)
# 第三种情况 所有的文件都包含在一个目录中
#这时的好处是不用添加那个include的文件夹
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-03 LANGUAGES CXX)
add_library(message
STATIC
Message.hpp
Message.cpp
)
add_executable(hello-world hello-world.cpp)
target_link_libraries(hello-world message)
# 把第一个文件复制到第二个文件夹里的某个文件
configure_file( autoGeneratedHeaders/projectConfig.h.in ${PROJECT_SOURCE_DIR}/autoGeneratedHeaders/projectConfig.h )
#添加包含的头文件
target_include_directories(CMakeLearnDemo PUBLIC
autoGeneratedHeaders
)
用条件语句控制编译
#这是关于流程控制部分的
cmake_minimum_required(VERSION 3.14)
project( project-4 LANGUAGES CXX VERSION 1.0.0.1)
set ( USE_LIBRARY OFF )
message( STATUS "Compile source into a library?" ${USE_LIBRARY} )
set ( BUILD_SHARED_LIBS OFF)
list (APPEND _source Message.cpp Message.h )
if (USE_LIBRARY)
add_library (message ${_source})
add_executable(hello main.cpp)
target_link_libraries (hello message)
else()
add_executable(hello main.cpp ${_source})
endif()
target_include_directories(hello
PUBLIC
${PROJECT_SOURCE_DIR}
)
#在构建的时候可以看自己编译器型号的,主要就是用了那几个变量
message(STATUS "Is the C++ compiler loaded? ${CMAKE_CXX_COMPILER_LOADED}")
if(CMAKE_CXX_COMPILER_LOADED)
message(STATUS "The C++ compiler ID is: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "Is the C++ from GNU? ${CMAKE_COMPILER_IS_GNUCXX}")
message(STATUS "The C++ compiler version is: ${CMAKE_CXX_COMPILER_VERSION}")
endif()
message(STATUS "Is the C compiler loaded? ${CMAKE_C_COMPILER_LOADED}")
if(CMAKE_C_COMPILER_LOADED)
message(STATUS "The C compiler ID is: ${CMAKE_C_COMPILER_ID}")
message(STATUS "Is the C from GNU? ${CMAKE_COMPILER_IS_GNUCC}")
message(STATUS "The C compiler version is: ${CMAKE_C_COMPILER_VERSION}")
endif()
可以设置变量的东西:
set
option
编译器的选定
两种方式
#第一种
$ cmake -D CMAKE_CXX_COMPILER=clang++ ..
#第二种
$ env CXX=clang++ cmake ..
切换构建类型
cmake 通过CMAKE_BUILD_TYPE 配置构建类型
构建类型有:
- Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件。
- Release:用于构建的优化的库或可执行文件,不包含调试符号。
- RelWithDebInfo:用于构建较少的优化库或可执行文件,包含调试符号。
- MinSizeRel:用于不增加目标代码大小的优化方式,来构建库或可执行文件。
#这是关于构建类型的
cmake_minimum_required (VERSION 3.18)
project ( hello VERSION 2.0.0.0 LANGUAGES CXX )
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "Build type" FORCE)
endif()
message(STATUS "BUILD type:" ${CMAKE_BUILD_TYPE})
message(STATUS "C flags, Debug configuration: ${CMAKE_C_FLAGS_DEBUG}")
message(STATUS "C flags, Release configuration: ${CMAKE_C_FLAGS_RELEASE}")
message(STATUS "C flags, Release configuration with Debug info: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(STATUS "C flags, minimal Release configuration: ${CMAKE_C_FLAGS_MINSIZEREL}")
message(STATUS "C++ flags, Debug configuration: ${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "C++ flags, Release configuration: ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "C++ flags, Release configuration with Debug info: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message(STATUS "C++ flags, minimal Release configuration: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
为语言指定标准
set(CMAKE_CXX_STANDARD 17)
之前设置的CMAKE_CXX_STANDARD只是一个可选属性,如果编译器不支持此标准版本,则还是有可能会退化为以前的版本。如果我们想要明确表示需要某个C++标准,则可以通过:
set(CMAKE_CXX_STANDARD_REQUIRED True)
CXX_STANDARD会设置我们想要的标准。
CXX_EXTENSIONS告诉CMake,只启用ISO C++标准的编译器标志,而不使用特定编译器的扩展。
CXX_STANDARD_REQUIRED指定所选标准的版本。如果这个版本不可用,CMake将停止配置并出现错误。当这个属性被设置为OFF时,CMake将寻找下一个标准的最新版本,直到一个合适的标志。这意味着,首先查找C++14,然后是C++11,然后是C++98。(译者注:目前会从C++20或C++17开始查找)