
Intro
复习
include(CheckCXXSourceCompiles)check_cxx_source_compiles
今天需要学习一下,如何在cmake过程中使用代码动态生成文件。
初始代码可以复制自Code
开始
- 首先我们先创建一个生成程序
- 在
MathFunctions\MakeTable.cxx
#include <cmath>
#include <fstream>
#include <iostream>
// 程序入口,argc为参数个数,argv为参数列表
int main(int argc, char* argv[])
{
// 如果参数个数小于2,返回1
if (argc < 2) {
return 1;
}
// std::ofstream是一个输出文件流类,用于创建文件并写入数据
// fout是一个输出文件流对象,打开文件名为argv[1],打开方式为out
// argv[1]为第二个参数,即输出文件名
// std::ios_base::out是打开文件的方式,表示写入文件
std::ofstream fout(argv[1], std::ios_base::out);
// fileOpen为fout是否打开成功
const bool fileOpen = fout.is_open();
// 如果fout打开成功
if (fileOpen) {
// 写入文件内容
fout << "double sqrtTable[] = {" << std::endl;
// 循环10次,写入sqrt(i)的值
for (int i = 0; i < 10; ++i) {
fout << sqrt(static_cast<double>(i)) << "," << std::endl;
}
// 写入文件内容
fout << "0};" << std::endl;
// 关闭文件
fout.close();
}
// 根据文件是否打开成功返回0或1
return fileOpen ? 0 : 1;
}
- 新创建一个
MathFunctions\MakeTable.cmake
# 添加可执行文件
add_executable(MakeTable MakeTable.cxx)
# 链接接口库保证编译器选项一致
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# 添加自定义命令
# OUTPUT 指定生成的输出文件
# COMMAND 指定执行的命令
# DEPENDS 指定依赖的目标或文件
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
这样一来,当我们使用这个cmake文件的时候就会自动执行MakeTable命令然后在对应的路径下生成Table.h了。
- 修改
MathFunctions\CMakeLists.txt使用MakeTable.cmake
add_library(MathFunctions MathFunctions.cxx)
target_include_directories(MathFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# 如果USE_MYMATH选项开启
if (USE_MYMATH)
# 添加预处理宏
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# 包含我们刚才配置的MakeTable.cmake文件
include(MakeTable.cmake)
# 创建一个静态库名为SqrtLibrary,其中包含了mysqrt.cxx和Table.h
add_library(SqrtLibrary STATIC mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
# 为SqrtLibrary库添加包含目录
target_include_directories(SqrtLibrary PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
# 链接接口库保证编译器选项一致
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
# 链接MathFunctions库和SqrtLibrary库
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
# 如果没有开启USE_MYMATH选项也要链接MathFunctions库和接口库保证编译器选项一致
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
重点在于
# 包含我们刚才配置的MakeTable.cmake文件
include(MakeTable.cmake)
# 创建一个静态库名为SqrtLibrary,其中包含了mysqrt.cxx和Table.h
add_library(SqrtLibrary STATIC mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
# 为SqrtLibrary库添加包含目录
target_include_directories(SqrtLibrary PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
- 引入了
MakeTable.cmake
测试


重新修改一下MakeTable.cmake试一试
# 添加可执行文件
add_executable(MakeTable MakeTable.cxx)
# 链接接口库保证编译器选项一致
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# 添加自定义命令
# OUTPUT 指定生成的输出文件
# COMMAND 指定执行的命令
# DEPENDS 指定依赖的目标或文件
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# 添加自定义命令
# 这次我们直接用linux下的echo命令输出字符串然后输出到文件中来生成文件
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/A.h
COMMAND ${CMAKE_COMMAND} -E echo "this is a test" > ${CMAKE_CURRENT_BINARY_DIR}/A.h
)
# 这里我们添加一个自定义目标,这个目标依赖于生成的文件
# 由于我们的代码中并没有#include "A.h"所以需要手动添加一下依赖关系
# 添加自定义目标 GenerateA 依赖于 ${CMAKE_CURRENT_BINARY_DIR}/A.h
add_custom_target(GenerateA DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/A.h)
# 将自定义目标 GenerateA 添加到 MakeTable 的依赖中
add_dependencies(MakeTable GenerateA)

复习
- add_custom_command 添加自定义命令
- add_custom_target 添加自定义目标
- add_dependencies 添加依赖关系
這裏推薦一個輸入法軟體,真的有夠好用,又重新激發了本人打字的慾望。 rime