这篇文章主要是记录学习Cmake过程中笔记的部分,记录一些基本、关键的使用步骤,以便日后即使忘记了今天,也能在看到这篇笔记后能迅速上手。
本篇文章配合下面的学习链接食用。
学习链接:CMake Tutorial
文件结构大概如下:
|── build/
|── source_file/
|└──── square.cpp
|└──── CMakeLists.txt
其中build文件夹是临时创建的,用于存放编译链接生成的相关文件;source_file文件存放的是源代码以及指引cmake编译链接的cmake格式文件。CMakeLists.txt文件的内容如下:
# 指明cmake最低版本,必写
cmake_minimum_required(VERSION 3.10)
# 创建项目名称,即生成的可执行文件名称
project(Tutorial)
# 将源码 square.cxx 链接到项目名称 square
add_executable(Tutorial Tutorial.cxx)
只需要这三个函数,即可生成单一文件的可执行文件。
因此,编译源码的第一步是在源码同级文件夹下,按照上述格式创建CMakeLists.txt文件,然后创建一个build文件夹,用于存放cmake后生成的文件。build文件夹可以创建在任何地方。下面是创建build文件夹后,编译链接的命令:
cd build
cmake /path/to/the/folder/with/file/CMakeListstxt
cmake --build .
第一行命令进入创建的build文件夹;第二行执行cmake命令,后面的路径是包含CMakeLists.txt文件的文件夹路径;第三行编译并链接。经过上面三步后,build文件夹下生成了一个名为square的可执行文件。
在CMakeLists.txt文件中添加下面内容:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
上面用到了set函数来设置CMAKE_CXX_STANDARD和CMAKE_CXX_STANDARD_REQUIRED变量,表示设定C++标准为C11,且开启该标准。
一个C++项目可以通过在源码中修改展示项目版本的源码,还可以通过cmake的方式来修改项目版本而不需要对源码进行改动。
cmake修改项目版本功能的文件逻辑如下:
CMakeLists.txt
-> TutorialConfig.h.in
-> Tutorial.h
先在CMakeLists.txt文件的project()
函数中指定版本:project(Tutorial VERSION 2.0)
,其中VERSION是project函数自带的关键字,2.0是用户设定的版本参数,该参数会自动存储在cmake的关键字< PROJECT-NAME>_VERSION_MAJOR中
然后在TutorialConfig.h.in文件中通过代码:
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
来将 cmake 关键字 < PROJECT-NAME>_VERSION_MAJOR 和用户自定义的 Tutorial_VERSION_MAJOR 变量关联起来,意思是变量 Tutorial_VERSION_MAJOR 可以是任意名称,而@VAR@中的VAR是cmake定义的关键字。
定义为关键字后,然后通过CMakeLists.txt中调用函数configure_file
:
configure_file(TutorialConfig.h.in TutorialConfig.h)
将 cmake 格式的 TutorialConfig.h.in 输入文件转化为头文件 TutorialConfig.h ,此时会发现头文件中已经自动定义好了之前在TutorialConfig.h.in中定义的变量和其对应的值。
最后在源码中加入头文件 TutorialConfig.h 即可。
第一部分内容主要是对单个C++文件进行构建。在非单个文件构成的项目中,肯定包括了各种级别的库、功能函数。第二部分主要对层级代码构建进行说明。
紧接第一部分内容,现在要使用自写的sqrt函数来替代C++中系统封装好的sqrt函数。
当要为主函数添加编写的库时,使用cmake编译的流程如下:
add_library()
函数为库源码添加库名称,链接库源码到库名称:add_library(MathFunction mysqrt.cxx)
add_subdirectory()
函数将库所在的文件夹添加到搜索路径中,用于构建target_link_libraries()
函数将库中项目名称与顶级项目名称链接:target_link_libraries(Tutorial PUBLIC MathFunctions)
target_include_directories()
函数来为主函数所在文件添加库函数头文件搜索路径:target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/MathFunctions"
)
最后在主函数文件中添加库函数头文件即可调用。
可以看到,上面的操作主要包括三个方面:
还是比较好记
在练习四中,我们添加的是固定的库。那么针对偶尔需要用到库,我们可以将库的调用方式设为可选。
下面是添加固定库时,CMakeLists.txt 文件中的内容:
cmake_minimum_required(VERSION 3.10)
project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
configure_file(TutorialConfig.h.in TutorialConfig.h)
add_subdirectory(MathFunctions)
add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC MathFunctions)
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/MathFunctions")
下面是添加可选库时,CMakeLists.txt 文件中的内容:
cmake_minimum_required(VERSION 3.10)
project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
option(USE_MYMATH "Use tutorial provided math implementation" ON)
configure_file(TutorialConfig.h.in TutorialConfig.h)
if(USE_MYMATH)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
两份文件中的区别如下:
option(USE_MYMATH "Use tutorial provided math implementation" ON)
#cmakedefine USE_MYMATH
代码,定义 USE_MYMATHif ... endif
语句来判断可选库的使用情况其他在源代码中修改的部分就看一下教程就好。
写了两部分cmake使用,应该够用了,不够再来补。