实际问题
如何执行预构建命令以在子项目中创建一系列生成的标头,但是仅当我在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")