Android Studio 链接器命令在包含 Boost 库时失败



坦率地说,我已经到了我的智慧的尽头,我真的需要一个崩溃的地方。在编译时,我一直得到一个

错误:链接器命令失败,退出代码为 1(使用 -v 查看调用(

我认为这是由于项目构建和提升库之间的不兼容或只是编译器版本不同,但只要我阅读二进制文件是完全兼容的(?

构建提升
我在 Windows 10 上通过 MinGW 编译,但为了排除这里的错误,我最终使用这个 git shell 脚本构建了提升,该脚本适用于最新版本的 Boost (1.64.0( 和 NDK (r15b(。我在Ubuntu 16.04的VirtualBox中做到了这一点,因为我没有足够的知识来适应Windows 10(至少我不能(。现在我有使用 gnu-4.9 和 llvm-3.5 编译的 x86 分片和静态库(我在 AStudio 中的模拟器也坏了(。

Android Studio
我正在使用 Cmake 来构建我的项目的 C/C++ 库。我有几个相互依赖的 C 库和一个C++库。最后一个是使用提升的那个。由于所有库都是构建和找到的,没有错误,这对我来说似乎是一个名称重整问题,尽管所有C 头文件都有预处理器声明:extern C.除了升压部分外,所有库都完美运行

CMake
设置了 find_package(( REQUIRED 参数,Boost_DEBUG告诉已找到所有组件。因为在某个时候我得到了错误

对 boost::system::generic_category(( 的未定义引用

我在组件中添加了系统,因此我的简约组件设置仅包含 chrono 和系统,就像许多其他线程上建议的有关此特定问题一样。我试图单独链接提升库,但没有成功:

target_link_libraries( MyLib ${Boost_SYSTEM_LIBRARY} 
${Boost_CHRONO_LIBRARY}
)

但现在我遇到了上述问题,此时我正在举起休战的旗帜。每一个提示都受到高度赞赏!!提前非常感谢!

CMakeList.txt

set( Boost_DEBUG ON )
set( Boost_USE_STATIC_LIBS ON )
set( Boost_USE_STATIC_RUNTIME ON )
set( Boost_USE_MULTITHREADED OFF )
set( Boost_NO_SYSTEM_PATHS ON )
set( BOOST_ALL_DYN_LINK OFF )
set( BOOST_ROOT C:/MyBoost )
set( Boost_INCLUDE_DIR ${BOOST_ROOT}/include )
set( Boost_LIBRARY_DIR ${BOOST_ROOT}/lib )
set( Boost_Version 1.64.0 )
find_package( Boost ${Boost_Version} COMPONENTS system chrono )
if( Boost_FOUND )
target_include_directories( MyLib PUBLIC/PRIVATE ${Boost_INCLUDE_DIR} )    
link_directories( ${Boost_LIBRARY_DIR} )
endif()
target_link_libraries( MyLib ${Boost_LIBRARIES} )

build.gradle

apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "My_ID"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
}

===== 更新 =====

我添加了

externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -DBOOST_SYSTEM_NO_DEPRECATED"
}

到build.gradle文件,现在它甚至可以按预期编译,甚至包括线程或Chrono libs!!尽管我之前取消注释的某些命令现在仍然不起作用。我现在收到以下错误:

libboost_chrono.a:添加符号时出错:文件格式错误

这应该是apk版本和增强库的问题??!如果是这样,如何确保我使用的是正确的 Boost 版本?

总结注释:

编译错误"undefined reference to boost::system::generic_category()"可以通过将-DBOOST_SYSTEM_NO_DEPRECATED添加到编译器标志来解决(有关更多详细信息,请参阅此处:编译时对boost::system::system_category((的未定义引用(。

要将构建限制为 x86,您可以在cppFlag旁边的">externalNativeBuild:cmake"部分中提供abiFilters "x86"

dlopen()问题:

当库是动态链接的,它也需要在共享库搜索路径中,否则在实际运行可执行文件时可能找不到它。因此,Boost 共享库路径需要放在PATH(Windows( 或LD_LIBRARY_PATH(Linux( 上(如果它不在标准位置,如 '/lib[64]' 或 '/usr/local/lib[64]'(。

或者,您可以使用静态库进行构建:

set(Boost_USE_STATIC_LIBS   ON)
find_package(Boost REQUIRED ...)

另一种方法是在安装步骤中将 Boost 库位置添加到 RPATH:

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

(但这对于发布版本来说可能不是可取的,因为它会修复库位置,该位置可能位于目标计算机上的不同位置(

最新更新