我已经为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_library
为link_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] 删除。
我来说两句