cmake 简单学习记录


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 配置构建类型

构建类型有:

  1. Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件。
  2. Release:用于构建的优化的库或可执行文件,不包含调试符号。
  3. RelWithDebInfo:用于构建较少的优化库或可执行文件,包含调试符号。
  4. 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++20C++17开始查找)


文章作者: Aknightive
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Aknightive !
评论
  目录