我想基于动态方式中目标文件中的所有符号生成module definition file(想想GTKMM的gendef)。
为此,我想add_custom_command
PRE_LINK
一个目标步骤。但是,看起来没有 easy 方法可以使用CMake获取所有目标文件的路径,这些文件适用于普通的makefile以及Visual Studio等多配置生成器。
现在,我有以下
add_custom_command(TARGET tgt PRE_LINK
COMMAND gendef ${CMAKE_CURRENT_BINARY_DIR}/tgt.def $<TARGET_FILE_NAME:tgt> ${CMAKE_CURRENT_BINARY_DIR}/$<$<BOOL:${CMAKE_BUILD_TYPE}>:${CMAKE_FILES_DIRECTORY}>/tgt.dir/${CMAKE_CFG_INTDIR}/*.obj
)
然而,由于我不得不在我看来使用generator expression,这是非常笨拙和笨重的。有没有更好的方法来实现这种效果,即为每个构建配置调用某个外部程序?
是否是一个CMake错误(功能?),对于普通的makefile,所有目标文件都转到CMakeFiles/tgt.dir
文件夹,而对于多配置生成器,所有文件都转到CMakeFiles的兄弟,即{{ 1}?我是否错过了一些可以直接指向正确位置的简单变量?
答案 0 :(得分:1)
将我的评论转化为答案
由CMake生成的Makefile项目具有完全不同的内部结构,然后为Visual Studio生成解决方案/项目。我认为这既不是错误也不是特征,这些结构只针对其用例进行了优化。
据我所知,没有简单的CMake内部方法来获取目标文件列表或中间文件目录的路径,例如:阅读目标财产。
所以我已经采用了您的代码示例,并使用Visual Studio 14 2015
和NMake Makefiles
生成器对CMake 3.3.2进行了替代测试。
<强>替代强>
关于名为"CMake: Is there an elegant way to get list of object files participating into a library?"的CMake邮件列表的一个相关讨论建议使用中间静态库:
add_library(tgtlib STATIC tgt.c)
add_custom_command(
OUTPUT tgt.def
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> $<TARGET_FILE:tgtLib>
)
file(WRITE dummy.c "")
add_library(tgt SHARED dummy.c tgt.def)
target_link_libraries(tgt tgtlib)
您可以在PRE_LINK
步骤中添加特定于构建环境的元素:
if(CMAKE_CONFIGURATION_TYPES)
set(_obj_files "$(IntermediateOutputPath)*.obj")
else()
set(_obj_files "$?")
endif()
add_custom_command(
TARGET MainProject
PRE_LINK
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> ${_obj_files}
)
<强>参考强>