在Linux上使用CMake生成预构建头文件

时间:2019-06-07 01:42:15

标签: c++ linux cmake

实际问题

如何执行预构建命令以在子项目中创建一系列生成的标头,但是仅当我在Linux上时才如此?

或者,如何获得使用execute_process 100%的时间工作的当前解决方案?

背景

我正在使用CMake(3.13)在Windows和Linux上生成一个项目,但是我需要根据所使用的命令执行一些特定的预构建命令。对于Linux,我需要通过使用xxd对其进行十六进制转储来生成项目所依赖的一些标头。具体来说,我必须使用特定的相对路径对它们进行xxd处理,否则xxd输出的名称将发生变化,并且生成的标头将是错误的(我知道此要求相当荒谬,但如果可能的话,我希望能够工作周围)。

此外,此CMakeList位于较大项目的子目录中,并且是CUDA项目(可能无关紧要,但以防万一不是这样)。

我尝试过的解决方案

我使用execute_process提出了部分解决方案,但这并不完美。由于某种原因,它并非总是在构建MySubProject之前运行,因此为什么我尝试切换到add_custom_command。我尝试了此命令的许多变体,但均无济于事。我使用add_custom_command的任何尝试都能在0%的时间内成功。

基于其他线程,我了解到add_custom_command仅在我可以在命令和添加库之间建立依赖关系时起作用,但是尽管有其他示例声称这样做会导致CMake检测依赖关系。

我注意到我的项目与众不同的两件事是我必须将这些命令包装在if (NOT WIN32)命令中,并且需要这些目录名。这些都是我极度痛苦的原因吗?如果是这样,也许我需要创建根据WIN32填写的空变量,然后使用它们调用add_custom_command以便在Windows上时它们什么也不做?

我还尝试过添加诸如DEPENDS之类的属性,尝试使用另一个add_custom_command对标头执行${CMAKE_COMMAND} -E touch,并尝试在调用add_library之前将文件附加到源,甚至尝试将两个add_library调用放在if-else下(由于该子项目是其他子项目的依赖项而导致失败,这导致其他子项目失败)。 >

我也尝试过add_custom_target,但这没有输出参数供我使用hexdump定位。也许还有其他选择?

那里有任何CMake专家有什么建议吗?非常感谢,谢谢。

这是我目前正在做的

# stuff that works perfectly
project("MySubProject")

file(GLOB SUB_SOURCE
    "Source/*.h"
    "Source/*.cpp"
    "Source/*.cuh"
    "Source/*.cu"
)

add_library(MySubProject SHARED ${SUB_SOURCE})
set_target_properties(MySubProject PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${MY_PROJECT_OUTPUT_DIR}
    LIBRARY_OUTPUT_DIRECTORY ${MY_PROJECT_OUTPUT_DIR}
    ARCHIVE_OUTPUT_DIRECTORY ${MY_PROJECT_OUTPUT_DIR}
)

target_link_libraries(MySubProject PRIVATE ${CUDA_cublas_LIBRARY})

# stuff I have to do on linux and only works some of the time
if (NOT WIN32)
  # Create header directory if it does not already exist
  set(HEADER_DIR "${MySubProject_SOURCE_DIR}/GeneratedHeaders")
  file(MAKE_DIRECTORY ${HEADER_DIR})

  # Hexdump to new headers
  execute_process(
    COMMAND xxd -i "../../MySubProject/src/file1.h"
    OUTPUT_FILE "Header1.h"
    WORKING_DIRECTORY ${HEADER_DIR}
  )

  execute_process(
    COMMAND xxd -i "../../MySubProject/src/file2.h"
    OUTPUT_FILE "Header2.h"
    WORKING_DIRECTORY ${HEADER_DIR}
  )
endif()

# more stuff that works perfectly
target_include_directories(MySubProject PUBLIC ${MyUtilProject_SOURCE_DIR}/src)
target_link_libraries(MySubProject PUBLIC MyUtilProject)

此命令的变体是我尝试替换为的

  add_custom_command(
    PRE_BUILD
    OUTPUT "Header1.h"
    COMMAND xxd -i "../..MySubProject/src/file1.h"
    WORKING_DIRECTORY ${HEADER_DIR}
    COMMENT "Using xxd to hexdump headers..."
    VERBATIM
  )
  target_sources(MySubProject PUBLIC "${HEADER_DIR}/Header1.h")

0 个答案:

没有答案