【发布时间】:2018-03-18 10:24:21
【问题描述】:
对于我的项目,我希望能够将核心 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(或等效的)编译器标志,而是什么时候我需要设置它。
【问题讨论】:
-
如果您的目标是 Android x86_64,则 NDK cmake 工具链文件将为您处理 PIC。
标签: c++ cmake shared-libraries static-libraries