c++ - CMake:处理共享库与静态库的链接

标签 c++ cmake shared-libraries static-libraries

对于我的项目,我希望能够将核心 C++ 库构建为静态库,但将主要 JNI(Java 胶水)编译为共享库(需要在运行时由 JVM 加载)。在伪代码中,这将是:

project(foo CXX)
add_library(foo1 foo1.cxx)
add_library(foo2 foo2.cxx)
add_library(foojni SHARED foojni.cxx)
target_link_libraries(foojni LINK_PRIVATE foo1 foo2)

现在在 x86_64 上,它失败并显示以下错误消息:

relocation R_X86_64_32 against `.rodata' cannot be used when making a shared object; recompile with -fPIC

显然,简单的解决方法是:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

但是我更喜欢对我的用户侵入性较小的解决方案,相反,我正在考虑:

if(BUILD_JNI)
  if(NOT BUILD_SHARED_LIBS)
    if(CMAKE_COMPILER_IS_GNUCXX)
      if(CMAKE_ARCHITECTURE STREQUAL "x86_64") # FIXME !!
        set(CMAKE_POSITION_INDEPENDENT_CODE ON)
      endif()
    endif()
  endif()
endif()

当然,下面这行是行不通的(没有CMAKE_ARCHITECTURE这样的东西)。

if(CMAKE_ARCHITECTURE STREQUAL "x86_64") # FIXME !!

由于检测体系结构似乎非常困难 (see),即使我能够这样做,我也不知道 ppc64el、mips 或 m68k(在此处插入任何异国情调的系统)的要求是什么。所以我想知道是否有一种简单的方法来查询 cmake 关于:

  • 我的编译器是否支持将共享库链接到静态库?
  • 理想情况下:转储实现此类链接步骤所需的缺失编译器标志。

我知道:

if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")

但是正如上面链接中所解释的,这不适用于交叉编译。


更新:问题显然不是如何设置-fPIC(或等效)编译器标志,而是何时我需要设置

最佳答案

您可以将与位置无关的代码设置为与全局相对的库的属性

project(foo CXX)
add_library(foo1 foo1.cxx)
set_property(TARGET foo1 PROPERTY POSITION_INDEPENDENT_CODE ON)
add_library(foo2 foo2.cxx)
set_property(TARGET foo2 PROPERTY POSITION_INDEPENDENT_CODE ON)
add_library(foojni SHARED foojni.cxx)
target_link_libraries(foojni LINK_PRIVATE foo1 foo2)

参见 What is the idiomatic way in CMAKE to add the -fPIC compiler option?

关于c++ - CMake:处理共享库与静态库的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46608677/

相关文章:

c++ - cmake 中安装命令的作用是什么?

cmake - 通过命令提示符将参数传递给 CMAKE

C 选择特定的函数实现(存在于许多库中)

CMake :Error in configuration process, 项目文件可能无效 Visual Studio 2017

c++ - C++ 静态库可以链接到共享库吗?

c++ - 用 C++ 编写可移植动态加载库的最简单方法是什么?

c++ - std::map 的底层结构是什么?

c++ - 代码块停止使用 gnome-terminal (linux) 执行

c++ - Windows 中的“字段抓取”

c++ - 使用标准类型的 ADL 无法找到运算符