如何使用CMake为多重configuration生成器和基于生成文件的目标文件获取path?

我想用dynamic的方式生成一个基于对象文件中所有符号的模块定义文件 (想想GTKMM的gendef )。

为此,我想为目标的PRE_LINK步骤add_custom_command PRE_LINK 。 然而,看起来没有简单的方法来获取所有CMake的目标文件的path,它可以用于普通的makefile,也可以用于像Visual Studio这样的多configuration生成器。

现在,我有以下

 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 ) 

然而,这是相当尴尬和庞大的,因为我必须在我看来使用生成器expression式 。 有没有更好的方法来实现这种效果,即为每个构buildconfiguration调用某个外部程序?

它是一个CMake错误(特征?),对于普通的makefile,所有的目标文件都转到CMakeFiles/tgt.dir文件夹,而对于多configuration生成器,所有的目标文件都转到CMakeFiles/tgt.dir兄弟 ,即tgt.dir/$<CONFIG> ? 我是否错过了一些简单的variables,直接指向正确的地方?

Solutions Collecting From Web of "如何使用CMake为多重configuration生成器和基于生成文件的目标文件获取path?"

把我的评论变成一个答案

由CMake生成的Makefile项目具有完全不同的内部结构,然后为Visual Studio生成解决方案/项目。 我认为这既不是一个bug也不是一个功能,这些结构只是针对它们的使用进行了优化。

据我所知,没有简单的CMake内部方法来获取目标文件的列表或中间文件目录的路径,例如读取目标属性。

所以我已经拿到你的代码示例,并使用Visual Studio 14 2015NMake Makefiles生成器对CMake 3.3.2做了一些替代测试。

备择方案

  1. CMake邮件列表中的一个名为“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) 
  2. 您可以将构建环境特定的元素添加到您的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} ) 

参考

  • NMAKE:文件名宏