当前位置: 首页 > 知识库问答 >
问题:

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

佟云
2023-03-14
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

在共享的情况下,我使用的是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_'

失败: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:stack-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,--exclude-libs,libatomic.a,-sysroot c:/android/android-sdk/ndk-bundle/platforms/android-23/arch-arm64-wl,--build-id-wl l,-z,now-shared-wl,-soname,libnative-lib.so-o..........\build\mediumates\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)

但这也失败了。出于某种原因,在本例中,link命令甚至不包括它应该链接的库:

失败:cmd.exe/c“cd.&&c:\android\android-sdk\ndk-bundle\toolchains\llvm\prebuild\windows-x86_64\bin\clang++.exe-target=aarch64-none-linux-android=c://android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64-system c:undle/sysroot/usr/include/aarch64-linux-android-d__android_api__=23-g-dandroid-ffunction-sections-funwind-tables-fstack-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:-warn-shared-textel-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\meditiates\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 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”

共有1个答案

岳浩
2023-03-14

您的库是相互依赖的:

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

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

ipopt
mumps
metis
lapack
blas 

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

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

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
 类似资料:
  • 静态链接方法:静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来 静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库 动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这

  • 在编译Linux程序时,我们经常会看到动态链接和静态链接这两个术语。这两个术语中是我Linux的共享函数库(shared libraries)相关的。共享函数库就象Windows系统里的.dll文件,它里面包含有很多程序常用的函数。为了方便程序开发和减少程序的冗余,程序当中就不用包含每个常用函数的拷贝,只是在需要时调用系统中共享函数库中常函数功能即可。这种方式我们称之为动态链接(Dynamical

  • 使用clang链接AFN .a静态库 AFN静态库的生成不是重点, 以链接使用为主 一、准备 在staticLib文件夹下新建test.m文件, 代码如下 #import <Foundation/Foundation.h> #import <AFNetworking.h> int main() { AFHTTPSessionManager *manager = [AFHTTPSe

  • 问题内容: 我在Linux,GCC中使用Boost库。安装和构建Boost之后,我发现使用Regex和Thread的程序使用共享的Boost库。就我的目的而言,我需要静态链接。如何更改链接类型?我应该重新构建Boost,还是可以通过在自己的项目或Boost配置文件中定义一些常量来设置链接类型? 问题答案: 只需添加到您的构建调用即可。这是一个简单的示例会话: 请注意,静态二进制文件的大小为1.5m

  • 主要内容:静态链接库,动态链接库,总结我们知道,C、C++程序从源文件到生成可执行文件需经历 4 个阶段,分别为预处理、编译、汇编和链接,本节将重点围绕链接阶段,对静态链接库和动态链接库做详细的讲解。 有关链接操作的具体细节,感兴趣的读者可阅读《 到底什么是链接,它起到了什么作用?》和《 符号——链接的粘合剂》这两节。总的来说链接阶段要完成的工作,就是将同一项目中各源文件生成的目标文件以及程序中用到的库文件整合为一个可执行文件。 通过

  • 问题内容: 在Linux上的“ C”上, 我需要静态库来静态链接,还是需要足够的共享库?如果没有,为什么不呢?(它们不包含相同的数据吗?) 问题答案: 是的,您需要静态库来构建静态链接的可执行文件。 静态库是编译对象的捆绑包。静态链接到库时,实际上与获取该库的编译结果,将它们解压缩到当前项目中以及将它们当作自己的对象使用一样。 动态库已链接。这意味着一些信息,例如重定位,已经被修复并丢弃。 此外,