系统生成器

Cmake

除了源文件之外,还需要向CMake提供项目配置描述。必须把CMake指令放入一个名为CMakeLists.txt的文件中,CMake才能够解析。

CMake是一个构建系统生成器,描述构建系统应当如何操作才能编译代码,GNU/Linux上,CMake默认生成Unix Makefile来构建项目:

  • Makefilemake将运行指令来构建项目。
  • CMakefile:包含临时文件的目录,CMake用于检测操作系统、编译器等。此外,根据所选的生成器,它还包含特定的文件。
  • cmake_install.cmake:处理安装规则的CMake脚本,在项目安装时使用。
  • CMakeCache.txt:如文件名所示,CMake缓存。CMake在重新运行配置时使用这个文件。

Cmakelists.txt

编译工程

mkdir build && cd build
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. && make
  1. 第一行,设置CMake所需的最低版本。
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
  1. 第二行,声明项目的名称(project-01)和支持的编程语言(CXX代表C++):
project(project-01 LANGUAGES CXX)
  1. C++版本的定义
set(CMAKE_CXX_STANDARD 11)
  1. 检测外部库和程序:find_package是用于发现和设置包的CMake模块(CMake命令,用于标识系统标准位置中的包)的命令,当调用find_package(<name>)时,模块中的命令将会运行。
find_package(PythonInterp 2.7)
  1. 指示CMake创建一个新目标:可执行文件hello-world。这个可执行文件是通过编译和链接源文件hello-world.cpp生成的。CMake将为编译器使用默认设置,并自动选择生成工具:
add_executable(hello-world hello-world.cpp)
  1. 添加头文件搜索路径
    1. 为所有目标添加头文件搜索路径:将指定目录添加到编译器的头文件搜索路径之下,指定的目录被解释成当前源码路径的相对路径。
    2. 为指定目标(target)添加头文件搜索路径:指定目标是指通过add_executable()add_library()命令生成的目标
// 为所有目标添加头文件搜索路径
include_directories(sub_dir) # 注意当前CMakeLists.txt和sub_dir相对路径关系
include_directories(${PROJECT_SOURCE_DIR}/sub_dir) # 通过源码根目录来定位sub_dir

// 为指定目标(`target`)添加头文件搜索路径
target_include_directories(projectA ./include1) # 注意相对路径关系
add_executable(projectA main.cpp)
  • include_directories 会为当前CMakeLists.txt的所有目标,以及之后添加的所有子目录的目标添加头文件搜索路径。
  • target_include_directories 只会为指定目标包含头文件搜索路径。如果想为不同目标设置不同的搜索路径,那么用target_include_directories更合适。
  1. 添加源文件
aux_source_directory(< dir > < variable >)  
// 搜集所有在指定路径下的源文件的文件名,并将输出结果列表储存在指定的变量中。
  1. 添加一个子目录并构建该子目录
add_subdirectory (sub_dir)

构建和链接静态库和动态库

  1. 创建目标库,库的名称和源码文件名相同,具体代码如下:
add_library(message
	STATIC
		Message.hpp
		Message.cpp
)
  • STATIC:用于创建静态库,即编译文件的打包存档,以便在链接其他目标时使用,例如:可执行文件。
  • SHARED:用于创建动态库,即可以动态链接,并在运行时加载的库。可以在CMakeLists.txt中使用add_library(message SHARED Message.hpp Message.cpp)从静态库切换到动态共享对象(DSO)。
  • OBJECT:可将给定add_library的列表中的源码编译到目标文件,不将它们归档到静态库中,也不能将它们链接到共享对象中。如果需要一次性创建静态库和动态库,那么使用对象库尤其有用。
  • MODULE:又为DSO组。与SHARED库不同,它们不链接到项目中的任何目标,不过可以进行动态加载。该参数可以用于构建运行时插件。
  1. 创建hello-world可执行文件的目标部分不需要修改:
  2. 将目标库链接到可执行目标:
target_link_libraries(hello-world message)

条件编译

  1. 引入逻辑变量USE_LIBRARY,值为OFF
set(USE_LIBRARY OFF)
//打印逻辑变量值
message(STATUS "Compile sources into a library? ${USE_LIBRARY}")
  1. 引入一个基于USE_LIBRARY值的if-else语句
//引入变量_sources,包括Message.hpp和Message.cpp
list(APPEND _sources Message.hpp Message.cpp)

if(USE_LIBRARY)
	add_library(message ${_sources})
	add_executable(hello-world hello-world.cpp)
	target_link_libraries(hello-world message)
else()
	add_executable(hello-world hello-world.cpp ${_sources})
endif()

Python库

有两种方式可以将解释语言(如Python)与编译语言(如C或C++)组合在一起使用。

  1. 扩展Python,通过编译成共享库的C或C++模块在这些类型上提供新类型和新功能。
  2. 将Python解释器嵌入到C或C++程序中。
#include <Python.h>

int main(int argc, char *argv[]) {
	Py_SetProgramName(argv[0]); /* optional but recommended */
	Py_Initialize();
	PyRun_SimpleString("from time import time,ctime\n"
	"print 'Today is',ctime(time())\n");
	Py_Finalize();
	return 0;
}
//找到Python解释器
find_package(PythonInterp REQUIRED) 
//通过(FindPythonLibs.cmake模块)找到Python头文件和库
find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED)
//可执行文件包含Python.h头文件,这个目标的include目录必须包含Python的include目录
target_include_directories(c++-embedded-python
	PRIVATE
	PYTHON_INCLUDE_DIRS}
)
//将可执行文件链接到Python库
target_link_libraries(c++-embedded-python
	PRIVATE
	${PYTHON_LIBRARIES}
)

Makefile

  1. 变量定义
    一般是字符串,规则类似宏。var=var1,使用:$(var)

  2. Makefile编写规则

目标文件:依赖文件
     命令1
     命令2
     ...
     命令n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值