我有一个在CMake构建过程中生成的文件列表.我想在之后使用"add_library"编译这些文件,但我不知道哪些文件在生成之后才生成.反正有没有把它构建成CMake脚本?
Sal*_*lsa 12
好吧,我认为这是可能的,所以我将分享我所做的.我的问题是我必须编译几个CORBA idls作为项目源的一部分,我不想手动列出每个文件.我觉得找文件会更好.所以我这样做了:
file(GLOB IDLS "idls/*.idl")
set(ACE_ROOT ${CMAKE_FIND_ROOT_PATH}/ace/ACE-${ACE_VERSION})
foreach(GENERATE_IDL ${IDLS})
get_filename_component(IDLNAME ${GENERATE_IDL} NAME_WE)
set(OUT_NAME ${CMAKE_CURRENT_SOURCE_DIR}/idls_out/${IDLNAME})
list(APPEND IDL_COMPILED_FILES ${OUT_NAME}C.h ${OUT_NAME}C.cpp ${OUT_NAME}S.h ${OUT_NAME}S.cpp)
add_custom_command(OUTPUT ${OUT_NAME}C.h ${OUT_NAME}C.cpp ${OUT_NAME}S.h ${OUT_NAME}S.cpp
COMMAND ${ACE_ROOT}/bin/tao_idl -g ${ACE_ROOT}/bin/ace_gperf -Sci -Ssi -Wb,export_macro=TAO_Export -Wb,export_include=${ACE_ROOT}/include/tao/TAO_Export.h -Wb,pre_include=${ACE_ROOT}/include/ace/pre.h -Wb,post_include=${ACE_ROOT}/include/ace/post.h -I${ACE_ROOT}/include/tao -I${CMAKE_CURRENT_SOURCE_DIR} ${GENERATE_IDL} -o ${CMAKE_CURRENT_SOURCE_DIR}/idls_out/
COMMENT "Compiling ${GENERATE_IDL}")
endforeach(GENERATE_IDL)
set_source_files_properties(${IDL_COMPILED_FILES}
PROPERTIES GENERATED TRUE)
set(TARGET_NAME ${PROJECT_NAME}${DEBUG_SUFFIX})
add_executable(
${TARGET_NAME}
${SOURCE}
${IDL_COMPILED_FILES}
)
Run Code Online (Sandbox Code Playgroud)
如果未创建我的一个idl编译输出(*C.cpp,*Ch,*S.cpp和*Sh),那么GENERATED属性很有用,因此build命令不会抱怨该文件不存在.
Flo*_*ian 11
好吧,可以使用CMake的ExternalProject功能使用两个CMake脚本来完成.
在主CMake脚本中,您需要添加生成源文件的自定义目标,如下所示,以及对第二个(外部)CMake项目的引用:
# Main CMakeLists.txt
add_custom_target(
code_generation
COMMAND your_code_generation_tool -o ${CMAKE_CURRENT_BINARY_DIR}/libgenerated/
)
include(ExternalProject)
ExternalProject_Add(
libgenerated
DEPENDS code_generation
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/path/to/external/project/
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/libgenerated-build
CMAKE_ARGS -DGENERATED_SOURCE_DIR=${CMAKE_CURRENT_BINARY_DIR}/libgenerated
BUILD_ALWAYS 1
INSTALL_CMD ""
)
add_executable(
${PROJECT_NAME}
...
)
target_link_libraries(
${PROJECT_NAME}
${CMAKE_CURRENT_BINARY_DIR}/libgenerated-build/libgenerated.a
)
add_dependencies(${PROJECT_NAME} libgenerated)
Run Code Online (Sandbox Code Playgroud)
现在,您可以在第二个(外部)CMake脚本中执行文件通配,并将找到的所有文件链接到静态库中:
# External project CMakeLists.txt
project(libgenerated)
file(GLOB_RECURSE SOURCES ${GENERATED_SOURCE_DIR}/*)
add_library(${PROJECT_NAME} ${SOURCES})
Run Code Online (Sandbox Code Playgroud)
在这个简单的解决方案中,即使没有任何更改,每次运行构建步骤时都会生成并构建文件.如果要避免这种情况,可以将标记文件添加到自定义目标,如以下改进的解决方案:
# Main CMakeLists.txt
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libgenerated-stamp
COMMAND your_code_generation_tool -o ${CMAKE_CURRENT_BINARY_DIR}/libgenerated/
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/libgenerated-stamp
DEPENDS the_input_file(s)_you_generate_your_code_from
)
add_custom_target(
code_generation
DEPENDS ${CMAKE_CURRENT_BUILD_DIR}/libgenerated-stamp
)
...
Run Code Online (Sandbox Code Playgroud)
如果代码生成器的输入文件中的更改未必导致更改所有生成的文件,则可以通过copy_if_different在外部项目中使用CMake 命令来进一步改进解决方案,如以下高级解决方案中所示:
# External project CMakeLists.txt
project(libgenerated)
file(GLOB_RECURSE SOURCES ${GENERATED_SOURCE_DIR}/*)
add_custom_target(
make_directory
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/generated
)
foreach(FILE ${SOURCES})
get_filename_component(BASENAME ${FILE} NAME)
list(APPEND ACTUAL_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/generated/${BASENAME}")
add_custom_target(
copy_${BASENAME}_if_different
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE} ${CMAKE_CURRENT_BINARY_DIR}/generated
)
add_dependencies(make_directory copy_${BASENAME}_if_different)
endforeach()
add_library(${PROJECT_NAME} ${ACTUAL_SOURCES})
add_dependencies(${PROJECT_NAME} make_directory)
Run Code Online (Sandbox Code Playgroud)
在此解决方案中,所有生成的文件都会被复制到另一个位置(${CMAKE_CURRENT_BINARY_DIR}/generated),如果它们已经更改或已添加并从那里构建.此方法仅导致更改文件的构建(但在删除文件时需要清除).
如果您不知道将生成的文件的名称,您可以“glob”它们所在的文件夹。
file( GLOB_RECURSE MY_SRC dest_folder/*.cpp )
add_library( libname SHARED ${MY_SRC} )
现在我不确定是什么触发了这些文件的生成。仅当您手动运行 cmake 时才会发生“通配”:它将无法自动检测是否存在新文件。
| 归档时间: |
|
| 查看次数: |
12475 次 |
| 最近记录: |