Cmake·

[#9][Adding a Custom Command and Generated File][A菌严肃的CMake手记]

美式A菌

美式A菌

26 1

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 添加依赖关系

所属系列

从当前文章继续阅读它所在合集中的前后内容。

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 1

登录 后参与评论

评论 1

美式A菌
美式A菌1月15日 11:21

這裏推薦一個輸入法軟體,真的有夠好用,又重新激發了本人打字的慾望。 rime