问题描述
我已经为Android编译了一些静态和共享库.具体来说,我有图书馆
I have compiled some static and shared libraries for Android. Specifically, I have the libraries
libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a
libcoinblas.so libcoinlapack.so libcoinmetis.so libcoinmumps.so libipopt.so
此外,这些库是相互依赖的,即
Furthermore, these libraries are inter-dependent, that is,
Lapack requires Blas
Mumps requires Blas and Metis
Ipopt requires Mumps, Metis, and Lapack
使用共享库时,Android项目可以正确链接并运行,但无法使用静态库进行构建.
The Android project correctly links and runs when using the shared libraries, but fails to build with the static libraries.
在共享情况下,我正在使用cmake文件
In the shared case, I am using the cmake file
cmake_minimum_required(VERSION 3.4.1)
add_library( native-lib
SHARED
src/main/cpp/cpp_example.cpp
src/main/cpp/MyNLP.cpp)
# Add dependent libraries
add_library(blas SHARED IMPORTED)
set_property(TARGET blas PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinblas.so)
add_library(lapack SHARED IMPORTED)
set_property(TARGET lapack PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinlapack.so)
add_library(metis SHARED IMPORTED)
set_property(TARGET metis PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmetis.so)
add_library(mumps SHARED IMPORTED)
set_property(TARGET mumps PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmumps.so)
add_library(ipopt SHARED IMPORTED)
set_property(TARGET ipopt PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libipopt.so)
# Location of header files
include_directories(${CMAKE_SOURCE_DIR}/libs/include
${CMAKE_SOURCE_DIR}/libs/include/ThirdParty)
target_link_libraries( native-lib
blas
lapack
metis
mumps
ipopt
)
,在静态情况下
cmake_minimum_required(VERSION 3.4.1)
add_library( native-lib
SHARED
src/main/cpp/cpp_example.cpp
src/main/cpp/MyNLP.cpp)
# Add dependent libraries
add_library(blas STATIC IMPORTED)
set_property(TARGET blas PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinblas.a)
add_library(lapack STATIC IMPORTED)
set_property(TARGET lapack PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinlapack.a)
add_library(metis STATIC IMPORTED)
set_property(TARGET metis PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmetis.a)
add_library(mumps STATIC IMPORTED)
set_property(TARGET mumps PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmumps.a)
add_library(ipopt STATIC IMPORTED)
set_property(TARGET ipopt PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libipopt.a)
# Location of header files
include_directories(${CMAKE_SOURCE_DIR}/libs/include
${CMAKE_SOURCE_DIR}/libs/include/ThirdParty)
target_link_libraries( native-lib
blas
lapack
metis
mumps
ipopt
)
我想我只需要更改从
add_library(libxxx SHARED IMPORTED)
set_property(TARGET libxxx PROPERTY ... libxxx.so)
到
add_library(libxxx STATIC IMPORTED)
set_property(TARGET libxxx PROPERTY ... libxxx.a)
但这不起作用.具体来说,在静态情况下,我得到了一堆(数百)
But that does not work. Specifically, in the static case, I get a bunch (hundreds) of
undefined reference to xxx
错误.例如
../../../../libs/arm64-v8a/libipopt.a(IpLapack.o): In function `Ipopt::IpLapackDppsv(int, int, double const*, double*, int, int&)':
IpLapack.cpp:(.text+0x3d4): undefined reference to `dppsv_'
尽管错误不仅是由于缺少Lapack功能造成的,而且还包括Mumps和其他功能.
Although the errors are not just due to missing Lapack functions, but also Mumps and others.
看着特定的失败命令,我相信这些库是按正确的顺序指定的:
Looking at the specific failed command, I believe that the libraries were specified in the correct order:
请注意,我在上面整理了一些路径,以使它们易于阅读,但是到最后,您可以看到库是按顺序列出的
Note that I sanitized the paths a little bit above so that they are slightly readable, but towards the end you can see that the libraries are listed in the order
libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a
编辑
我还尝试将链接命令从target_link_library
更改为link_library
:
EDIT
I also tried changing the link command from target_link_library
to link_library
:
link_libraries(native-lib blas lapack metis mumps ipopt)
但这也失败了.由于某种原因,在这种情况下,link命令甚至不包含它应该链接的库:
but this also fails. For some reason, in this case, the link command doesn't even include the libraries that it is supposed to link:
推荐答案
您的库是相互依赖的:
Lapack requires Blas
Mumps requires Blas and Metis
Ipopt requires Mumps, Metis, and Lapack
这意味着链接它们的顺序应该相反:
This means that the order for linking them should be reverse:
ipopt
mumps
metis
lapack
blas
如果您不想浪费时间来确定最佳顺序,而是让链接程序找出(这可能),可以使用
If you don't want to waste your time on figuring out the best order, but rather let the linker to find out (this may slow your builds significantly), you can use
target_link_libraries(native-lib -Wl,-start-group 布拉斯 拉帕克 梅蒂斯 腮腺炎 ipopt -Wl,-end-group).
target_link_libraries(native-lib -Wl,--start-group blas lapack metis mumps ipopt -Wl,--end-group).
您还可以通过 IMPORTED_LINK_INTERFACE_LIBRARIES 来教CMake有关导入的静态库之间的依赖关系,例如
You can also teach CMake about the dependencies between imported static libs, via IMPORTED_LINK_INTERFACE_LIBRARIES, e.g.
set_target_properties(lapack
PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES
blas)
以此类推.
这将翻译
target_link_libraries( native-lib
blas
lapack
)
收件人
clang++ -o libnative-lib.so … libblas.a libnlapack.a libblas.a
这篇关于Android:链接到预构建的静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!