【问题标题】:Link CMake built libraries to prebuilt object file将 CMake 构建的库链接到预构建的目标文件
【发布时间】:2019-08-17 21:18:54
【问题描述】:

我有以下设置,其中包含一个预构建的目标文件 (payload.o) 和 4 个库 lib1lib2lib3lib4 均由该 cmake 项目构建。

prebuilt/
--- payload.o
lib1/
--- CMakeLists.txt
--- src/
--- ...
lib2/
--- CMakeLists.txt
--- src/
lib34/
--- Makefile
--- src1/
--- src2/

payload.o 是提供的预构建对象,无法在此 cmake 项目中构建。

lib1lib2cmake 感知库,lib3lib4 是通过 Makefile (add_custom_command()) 生成的。

lib2 依赖于lib1 符号,lib3 依赖于lib2lib1 依赖于lib3,此外lib4 依赖于lib3。如您所见,它是一个循环依赖图。

此外,payload.o 依赖于 lib3lib4


因此,我试图实现的链接器调用是:

ld prebuilt/payload.o -L <cmake build directory here> --start-group lib1 lib2 lib3 --end-group lib4

我尝试通过以下方式添加预构建的目标文件:

add_executable(payload IMPORTED prebuilt/payload.o)
target_link_libraries(payload lib1 lib2 lib3 lib4)

但这会失败并显示错误消息

Cannot specify link libraries for target "payload" which is not built by this project

有什么想法吗?


有问题的缩写 cmake 文件:

project(...)
# build lib1/lib2
add_subdirectory(lib1)
add_subdirectory(lib2)


# add custom command & target
add_custom_command(
    OUTPUT
    "${LIB3} ${LIB4}"
    COMMAND
...
    VERBATIM
    )
add_custom_target(lib34 DEPENDS "${LIB3} ${LIB4}")
add_dependencies(lib34 lib2)

add_library(lib3 STATIC IMPORTED ${LIB3})
add_dependencies(lib3 lib34)
add_library(lib4 STATIC IMPORTED ${LIB4})
add_dependencies(lib4 lib34)

# lib1 -> lib3
add_dependencies(lib1 lib3)

# payload target
add_executable(payload IMPORTED 
    prebuilt/payload.o
    )

add_dependencies(payload lib3 lib4)
target_link_libraries(payload lib1 lib2 lib3 lib4 <...>)

【问题讨论】:

  • 我们可以用 cmake 将 .o 编译成一个静态库,然后链接到那个静态库吗? add_executable IMPORTED 用于添加预先存在的可执行文件,但您可以尝试 add_library( OBJECT IMPORTED)

标签: c++ build cmake linker


【解决方案1】:

只需删除导入的:

add_executable(payload prebuilt/payload.o)

cmake 应该知道该做什么。 IMPORTED 用于 cmake 之外的可执行构建。

或者,您可以指定导入的对象库,因为这正是您所拥有的 - 由外部实体构建的对象文件:

# import .o file as object library
add_library(payload_object OBJECT IMPORTED GLOBAL)
set_target_properties(payload_object IMPORTED_OBJECTS ${CMAKE_CURRENT_SOURCE_DIR}/prebuilt/payload.o

# create payload executable, add payload objects
add_executable(payload ${TARGET_OBJECTS:payload_object})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-03
    • 2016-08-16
    • 2015-01-06
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多