Актуальный вопрос
Как выполнить команду перед сборкой, чтобы создать серию сгенерированных заголовков в подпроекте, но только когда я работаю в 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-иначе (который потерпел неудачу из-за того, что этот подпроект являлся зависимостью для других подпроектов, он вызвал сбой других подпроектов).
Я тоже пробовал 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")