Android:链接到预构建的静态库 [英] Android: Linking to prebuilt static libraries

查看:80
本文介绍了Android:链接到预构建的静态库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为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:

失败:cmd.exe/C"cd.&& clang ++.exe --target = aarch64-none-linux-android --gcc-toolchain = C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot = sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API __ = 23 -g -DANDROID -ffunction-sections -funwind表-fstack-protector-strong-无规范前缀-Wa,-noexecstack -Wformat -Werror = format-security -O0 -fno-limit-debug -info -Wl,-exclude-libs,libgcc.a -Wl,-exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-臂64 -Wl,-build-id -Wl,-警告共享文本-Wl,-致命警告-Wl,-无未定义-Wl,-z,noexecstack-有参数-Wl,-z ,relro -Wl,-z,现在-shared -Wl,-soname,libnative-lib.so -o ........ \ build \ intermediates \ cmake \ debug \ obj \ arm64-v8a \ libnative-lib .所以 CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a -latomic -lm "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc ++/4.9/libs/arm64-v8a/libgnustl_static.a" && cd."

FAILED: cmd.exe /C "cd . && clang++.exe --target=aarch64-none-linux-android --gcc-toolchain=C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=23 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a -latomic -lm "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a" && cd ."

请注意,我在上面整理了一些路径,以使它们易于阅读,但是到最后,您可以看到库是按顺序列出的

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:

失败:cmd.exe/C"cd.&& C:\ Android \ android-sdk \ ndk-bundle \ toolchains \ llvm \ prebuilt \ windows-x86_64 \ bin \ clang ++.exe --target = aarch64-none-linux-android --gcc-toolchain = C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot = C:/Android/android-sdk/ndk-bundle/sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API __ = 23 -g -DANDROID -ffunction-sections -funwind表-fstack-protector-strong-无规范前缀-Wa,-noexecstack -Wformat -Werror = format-security -O0 -fno-limit-debug -info -Wl,-exclude-libs,libgcc.a -Wl,-exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-臂64 -Wl,-build-id -Wl,-警告共享文本-Wl,-致命警告-Wl,-无未定义-Wl,-z,noexecstack-有参数-Wl,-z ,relro -Wl,-z,现在-shared -Wl,-soname,libnative-lib.so -o ........ \ build \ intermediates \ cmake \ debug \ obj \ arm64-v8a \ libnative-lib .所以 CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o -latomic -lm "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc ++/4.9/libs/arm64-v8a/libgnustl_static.a" && cd." CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o:在 函数`Java_io_jeti_ipopt_1static_MainActivity_stringFromJNI':

FAILED: cmd.exe /C "cd . && C:\Android\android-sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android --gcc-toolchain=C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=C:/Android/android-sdk/ndk-bundle/sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=23 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o -latomic -lm "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a" && cd ." CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o: In function `Java_io_jeti_ipopt_1static_MainActivity_stringFromJNI':

推荐答案

您的库是相互依赖的:

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:链接到预构建的静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆