如何表示地图文件依赖于add_executable?

时间:2014-05-09 20:06:31

标签: cmake map-files

我使用标准命令构建可执行文件:

add_executable(MyExe a.c b.c)

我正在调整CMAKE_EXE_LINKER_FLAGS以发出一个地图文件,然后就可以了。

但是,如果我删除了地图文件,执行增量生成并不会重新生成地图文件。这是有道理的,因为我还没有表示地图文件取决于MyExe。在上面的场景中,MyExe.map甚至不是目标,所以cmake甚至不知道它存在。

我已尝试创建自定义目标,但我无法创建重新生成地图文件的自定义命令,因为它来自add_executable()。然后我尝试使用add_dependencies(),但这似乎只会影响构建顺序。

我可以显式地重新运行链接器作为构建自定义目标的自定义命令,但这似乎很浪费,因为链接确实需要一些时间。

似乎我需要一些方法来告诉add_executable,除了可执行映像之外还有更多输出。有没有办法做到这一点?

如果有人能指出我正确的方向,我会很感激!提前感谢您阅读。

1 个答案:

答案 0 :(得分:6)

我在CMake's mailing list上也看过同样的问题并且从未收到回答。所以让我试着在这里回答。

CMake没有对地图文件的官方支持,也没有 - 如果手动添加必要的链接器标志 - 以获得可执行目标的多个输出。

如果您不想将其添加为额外的自定义命令/目标步骤,则可以使用OBJECT_OUTPUTS源文件属性链接到作为可执行文件一部分的目标文件(不幸的是仅使用Makefile生成器)

我已经使用GNU工具链成功测试了以下示例:

cmake_minimum_required(VERSION 2.6)

project(MapFileDep)

file(WRITE "main.cpp" "int main() { return 0; }")

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    set(
        CMAKE_EXE_LINKER_FLAGS 
        "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=output.map"
    )
endif()

add_executable(${PROJECT_NAME} "main.cpp")

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    set_source_files_properties(
        "main.cpp" 
        PROPERTIES OBJECT_OUTPUTS "output.map"
    )
endif()

<强>替代

这里是更高级的替代方案(也涵盖了@jww的用例):

添加生成/创建/复制output.map文件的内容(当它不存在时)并使用LINK_DEPENDS目标属性使CMake在output.map更改时意识到重新链接:< / p>

add_custom_command(
    OUTPUT "output.map"
    COMMAND "${CMAKE_COMMAND}" -E touch "output.map"
)

add_executable(${PROJECT_NAME} "main.cpp" "output.map")

set_target_properties(
    ${PROJECT_NAME} 
    PROPERTIES 
        LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/output.map"
)