Android:链接到预构建的静态库

不来梅

我已经为Android编译了一些静态和共享库。具体来说,我有图书馆

libcoinblas.a   libcoinlapack.a   libcoinmetis.a   libcoinmumps.a   libipopt.a
libcoinblas.so  libcoinlapack.so  libcoinmetis.so  libcoinmumps.so  libipopt.so

此外,这些库是相互依赖的,也就是说,

Lapack requires Blas
Mumps  requires Blas and Metis
Ipopt  requires Mumps, Metis, and Lapack

使用共享库时,Android项目可以正确链接并运行,但无法使用静态库进行构建。

在共享的情况下,我正在使用cmake文件

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)

但这不起作用。具体来说,在静态情况下,我得到了一堆(几百个)

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等。


编辑

查看特定的失败命令,我相信这些库是按正确的顺序指定的:

失败: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-无规范前缀-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,-警告共享文本-Wl,-致命警告-Wl,-无定义的-Wl,-z,noexecstack-有参数-Wl,-z,relro -Wl,-z ,现在-共享-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。”

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

libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a

编辑

我也尝试将link命令从更改target_link_librarylink_library

link_libraries(native-lib blas lapack metis mumps ipopt)

但这也失败了。由于某种原因,在这种情况下,链接命令甚至不包含应该链接的库:

/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中:/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中:

亚历克斯·科恩

您的库是相互依赖的:

Lapack requires Blas
Mumps  requires Blas and Metis
Ipopt  requires Mumps, Metis, and Lapack

这意味着链接它们的顺序应该相反:

ipopt
mumps
metis
lapack
blas 

如果您不想浪费时间来找出最佳顺序,而是让链接器找出来(这可能会大大降低构建速度),则可以使用

target_link_libraries(native-lib -Wl,-start-group blaps metis腮红ipopt -Wl,-end-group)

您还可以通过IMPORTED_LINK_INTERFACE_LIBRARIES教CMake有关导入的静态库之间的依赖关系,例如

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章