如何使用CMake获取多配置生成器和基于makefile的目标文件的路径?

时间:2015-04-26 23:27:11

标签: windows cmake

我想基于动态方式中目标文件中的所有符号生成module definition file(想想GTKMMgendef)。

为此,我想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}?我是否错过了一些可以直接指向正确位置的简单变量?

1 个答案:

答案 0 :(得分:1)

将我的评论转化为答案

由CMake生成的Makefile项目具有完全不同的内部结构,然后为Visual Studio生成解决方案/项目。我认为这既不是错误也不是特征,这些结构只针对其用例进行了优化。

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

所以我已经采用了您的代码示例,并使用Visual Studio 14 2015NMake Makefiles生成器对CMake 3.3.2进行了替代测试。

<强>替代

  1. 关于名为"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)
    
  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}
    )
    
  3. <强>参考