【发布时间】:2018-11-09 01:46:59
【问题描述】:
我有如下CMakeLists.txt,根据对象库定义了一个对象库和一个共享库,如下:
add_library(foo OBJECT
foo.cpp
)
add_library(bar SHARED
bar.cpp
$<TARGET_OBJECTS:foo>
)
add_executable(baz baz.cpp)
target_link_libraries(baz
PUBLIC bar
)
链接baz 时出现以下链接器错误:
/usr/bin/ld: CMakeFiles/foo.dir/foo.cpp.o: relocation R_X86_64_PC32 against symbol `_ZSt4cout@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
这是因为foo.cpp 不是用-fPIC 构建的(bar.cpp 是)。这可以通过添加来解决:
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)
这是解决此问题的正确方法吗?在我看来,应该有一个更清洁的解决方案。我觉得 CMake 在这里可以更聪明,并且看到来自 foo 的对象仅在需要 -fPIC 的上下文中使用。我正在使用 CMake 3.11。
一些上下文;在我们的项目中,我们需要从分散在不同目录中的大量资源构建一个共享库。现在,我们为每个目录创建单独的共享库。这些库中的大多数都依赖于 Bison 源,在幕后依赖于 add_custom_command 来构建。这引入了库之间的编译时依赖关系,严重限制了我们可以并行化构建的程度(请参阅:https://gitlab.kitware.com/cmake/cmake/issues/15555)。
每个目录的对象库然后用于构建共享库似乎是解决此问题的好方法。
【问题讨论】:
-
编译器标志等 CMake 属性将在需要的范围内渗透到所有相关目标。但是,您想要的基本上是某些属性也可以“涓涓细流”。我不认为这就是它的工作方式,甚至从 CMake 开发人员的角度来看它也不是预期的工作方式。当然,你可以为 CMake 编写一个补丁来做到这一点,但我怀疑它是否会被主线接受,只是说...... :-)
-
@ArneVogel,确实有道理。
-
我很高兴,如果你昨天没有问这个问题,我今天会问这个问题。 :-)