Issue
To be frank I'm at my wit's end and I really need a place to crash. While compiling I am keeping getting a
error: linker command failed with exit code 1 (use -v to see invocation)
I presume it is due to incompability or simply different compiler versions between the project build and the boost libraries but as long as I read the binaries are perfect compatible(?).
Building Boost
I compiled via MinGW on Windows 10 but to exclude errors here I ended up building boost using this git shell script which worked with the latest versions of Boost (1.64.0) and NDK (r15b). I did it in the VirtualBox with Ubuntu 16.04 since I had not enough knowledge to adapt it to Windows 10 (at least I was not able to). Now I have shard and static libs compiled with gnu-4.9 and llvm-3.5 for x86 (which my emulator in AStudio is baded on too).
Android Studio
I am using Cmake to build the C/C++ libraries of my project. I have several C libs and one C++ lib that are dependant from each other. The last is the one using boost. Since all libraries are built and found with no error it seems to be a name mangling problem to me though all C header files have the preprocessor declaration: extern C. Except for the boost parts all is running flawlessly
CMake
The find_package() REQUIRED parameter is set and the Boost_DEBUG tells that all components have been found. Since at a certain point I got the error
undefined reference to boost::system::generic_category()
I added system to the components, so my minimalistic components setup contains only chrono and system like suggested on many other threads concerning this particular problem. I tried to link the boost libs individually, without success:
target_link_libraries( MyLib ${Boost_SYSTEM_LIBRARY}
${Boost_CHRONO_LIBRARY}
)
But now I have the problem described above and at this point I am hoisting the flag of truce. EVERY HINT is HIGHLY appreciated!! Thank you very much in advance!
CMakeLists.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'
}
===== UPDATE =====
I added
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -DBOOST_SYSTEM_NO_DEPRECATED"
}
to the build.gradle file and now it compiles as expected even including the thread or chrono libs!! Though some commands i decommented earlier are still not working now. I am getting following error now:
libboost_chrono.a: error adding symbols: File in wrong format
This should be a problem with the version of the apk and the boost libs??! How to ensure i am using the right Boost version if so?
Solution
To sumarize the comments:
The compilation error "undefined reference to boost::system::generic_category()
" can be worked-around by adding the -DBOOST_SYSTEM_NO_DEPRECATED
to the compiler flags (see here for further details: undefined reference to boost::system::system_category() when compiling).
To limit the build only to x86, you can provide the abiFilters "x86"
in the "externalNativeBuild:cmake" section next to the cppFlags.
The dlopen()
problem:
When the library is linked dynamically, it needs to be also in the shared library search paths, otherwise it might not be found when actually running the executable. So the Boost shared libs path needs to be put to the PATH
(Windows) or LD_LIBRARY_PATH
(Linux) (if it is not in the standard locations like '/lib[64]' or '/usr/local/lib[64]').
Alternatively you can build with static libraries instead:
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED ...)
Another alternative is to add the Boost libraries locations to the RPATH during the installation step:
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
(but that might not be desirable for release builds, as it fixes the library location, which might be in a different place on the target machine)
Answered By - EmDroid
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.