使用NDK,Gradle&链接外部库Android Studio中的CMake [英] Linking external libraries using NDK, Gradle & CMake in Android Studio

查看:93
本文介绍了使用NDK,Gradle&链接外部库Android Studio中的CMake的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在经历了一段空白之后又回到了Android开发,而我以前的基于ANT的构建链似乎不再能与最新的SDK配合使用(这是一个单独的问题),因此我正在尝试以新的方式进行操作,基于gradle和CMake.

I've come back to Android development after a gap and my old ANT based build chain no longer seem to function (that's a separate issue) with the latest SDK, so I'm trying to do things the new way, which is based around gradle and CMake.

我有一些我的项目需要的预置的静态和动态第三方库,但是我无法成功链接它们.
据我所知,这些需要在" CMakeLists.txt "文件中指定,而不是在" build.gradle "文件中指定,但是我对这两个系统都是新手,所以如果我错了,请纠正我.

I have a number of pre-built static and dynamic 3rd party libraries that my project needs but I've been unable to link these successfully.
From what I can gather, these need to be specified in the 'CMakeLists.txt' file rather than the 'build.gradle' files but I'm new to both systems, so please correct me if I'm wrong.

这是我到目前为止尝试过的:

Here's what I've tried so far:

  • 首先,我尝试解析项目符号的位置.我尝试了一些变体,其中省略了"lib",.a"和"armeabi-v7a"(希望它能选择正确的CPU变体),但没有一个起作用

  • first, I try to resolve the location of bullet. I've tried variants where I omit the 'lib' the '.a' and the 'armeabi-v7a' (hoping it'd pick up the right CPU variant) but none have worked

 find_library(bullet_lib libBullet.a HINTS ${LIBBASE}bullet3/build3/Android/obj/local/armeabi-v7a)

我不确定这与 target_link_libraries

add_library(bullet_lib STATIC IMPORTED)

这发现内置库很好,但是我收到了"bullet"和其他第三方库的链接器错误

this finds the built-in libraries fine but I get linker errors for 'bullet' and other 3rd party libs

target_link_libraries(my_project_name android log EGL GLESv2 bullet_lib) 

$ {LIBBASE} 是第三方库的基本目录,似乎还可以,但是,这是另一回事:CMake错误似乎没有出现在android studio中!我可以通过在包含' CMakeLists.txt '文件的文件夹中运行 cmake.来解决出现问题的地方,但是我不确定我是否用正确的参数调用它:Android Studio对cmake所做的任何操作以及该文件目前对我来说都是一个黑匣子.

${LIBBASE} is the base dir for the 3rd party libraries and seems to be OK but, here's another thing: CMake errors don't seem to appear in android studio! I can sort of work out where it's having problems by running cmake . in the folder that contains the 'CMakeLists.txt' file but I'm not quite sure I'm calling that with the correct parameters: whatever Android Studio does with cmake and that file are a black box to me at this time.

我在android studio中只能看到的消息是链接器错误(它没有提到关于找不到库的CMake错误,这是这些链接器错误的原因:)

The only messages I can see in android studio are linker errors (it doesn't mention CMake errors about not finding the libraries, which is the cause of these linker errors:)

Build command failed.
Error while executing process E:\prog\Android\cmake\3.6.4111459\bin\cmake.exe with arguments {--build E:\prog\anthracite\gradle\AnthracitePlayerAPI21\app\.externalNativeBuild\cmake\debug\x86_64 --target anthracite-lib}
[1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\libanthracite-lib.so
FAILED: cmd.exe /C "cd . && E:\prog\Android\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=x86_64-none-linux-android --gcc-toolchain=E:/prog/Android/ndk-bundle/toolchains/x86_64-4.9/prebuilt/windows-x86_64 --sysroot=E:/prog/Android/ndk-bundle/sysroot -fPIC -isystem E:/prog/Android/ndk-bundle/sysroot/usr/include/x86_64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -std=c++11 -fexceptions -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot E:/prog/Android/ndk-bundle/platforms/android-21/arch-x86_64 -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,libanthracite-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\libanthracite-lib.so @CMakeFiles/anthracite-lib.rsp  && cd ."

E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:237: error: undefined reference to 'btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache*)'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:240: error: undefined reference to 'btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btDefaultCollisionConstructionInfo const&)'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:242: error: undefined reference to 'btCollisionDispatcher::btCollisionDispatcher(btCollisionConfiguration*)'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:243: error: undefined reference to 'btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:246: error: undefined reference to 'btDefaultSoftBodySolver::btDefaultSoftBodySolver()'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:247: error: undefined reference to 'btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher*, btBroadphaseInterface*, btConstraintSolver*, btCollisionConfiguration*, btSoftBodySolver*)'
E:\prog\anthracite\src/CCmpPhysicsScene3D.cpp:250: error: undefined reference to 'btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher*, btBroadphaseInterface*, btConstraintSolver*, btCollisionConfiguration*)'
E:\prog\anthracite\src/CCmpPhysJointHinge.cpp:117: error: undefined reference to 'btHingeConstraint::btHingeConstraint(btRigidBody&, btVector3 const&, btVector3 const&, bool)'

clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

并运行"cmake".从命令行给出:

And running 'cmake .' from the command line gives:

-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.17133.
CMake Warning at CMakeLists.txt:447 (message):
  resolved libraries:


CMake Warning at CMakeLists.txt:448 (message):
  e:/prog/libs/bullet3/build3/Android/obj/local/armeabi-v7a


CMake Warning at CMakeLists.txt:449 (message):
  bullet_lib-NOTFOUND



-- Configuring done
-- Generating done
-- Build files have been written to: E:/prog/anthracite/gradle/AnthracitePlayerAPI21/app

但是,如上所述,我不确定输出的准确性,因为对"cmake"的调用参数可能与Android Studio内部有很大不同.(例如,它默认为Windows构建,因此我不确定是否要查找".lib"库,而不是".a"或".so")

although, as I mentioned above, I'm not sure of the veracity of that output as the calling parameters to 'cmake' are likely to be quite different from inside Android Studio. (e.g it's defaulting to a windows build, so I'm not sure if it'd look for '.lib' libraries rather than '.a' or '.so')

此外,我在' CMakeLists.txt '文件中使用这些行来报告构建状态:

Also, I'm using these lines in my 'CMakeLists.txt' file to report the status of the build:

message(WARNING "resolved libraries:")
message(WARNING ${LIBBASE}bullet3/build3/Android/obj/local/armeabi-v7a)
message(WARNING ${bullet_lib})

无论如何,我显然丢失了一些东西,但是我还没有找到任何明确的指南.看起来很简单而且很明显(链接库),但是似乎很痛苦.我将不胜感激任何指针.

Anyway, I'm clearly missing something and I've not been able to find any clear guides regarding this. It seems a really simple and obvious thing to do (link a library) but it seems to be a massive pain. I'd be grateful for any pointers.

推荐答案

您必须注意ABI不兼容的问题.您正在为 x86_64 构建 libanthracite-lib.so ,因此您需要与 libBullet.a 相同的变体.如果您只需要 armeabi-v7a ,则必须在 build.gradle 中指定它,例如

You must take care of ABI incompatibility. You are building libanthracite-lib.so for x86_64, so you need the same variant of libBullet.a. If you only need armeabi-v7a, you must specify this in build.gradle, e.g.

android {
  externalNativeBuild {
    cmake {
      path 'CMakeLists.txt'
    }
  }
  defaultConfig {
     ndk {
        abiFilters 'armeabi-v7a'
    }
    externalNativeBuild {
      cmake {
         arguments '-DCMAKE_VERBOSE_MAKEFILE=ON'
      }
    }
  }
}

在您的 E:\ prog \ anthracite \ gradle \ AnthracitePlayerAPI21 \ app \ CMakeLists.txt

add_library(bullet_lib STATIC IMPORTED)
set_target_properties(bullet_lib PROPERTIES IMPORTED_LOCATION
 ${LIBBASE}/bullet3/build3/Android/obj/local/${ANDROID_ABI}/libBullet.a)
target_link_libraries(my_project_name bullet_lib android log EGL GLESv2) 

target_link_libraries 中库的顺序可能很重要,因此请在左侧保留静态库.

The order of libraries in target_link_libraries may be important, so keep static libs on the left.

我猜您使用 ndk-build 构建 libBullet.a .即使没有Java文件,也可以为AS项目创建一个单独的库模块(在 bullet_module 中调用),然后将其指向 Android.mk :

I guess you build libBullet.a with ndk-build. You can create a separate library module (let's call in bullet_module) to your AS Project, even if it has no Java files, and point it to the Android.mk:

apply plugin: 'com.android.library'

android {
  compileSdkVersion 27

  defaultConfig {
    ndk {
      abiFilters 'armeabi-v7a'
    }
    externalNativeBuild {
      ndkBuild {
        targets 'Bullet'
      }
    }
  }
  externalNativeBuild {
    ndkBuild {
      path "${LIBBASE}/bullet3/build3/Android/jni/Android.mk"
    }
  }
}

现在,您可以更改您的 CMakeLists.txt 来查看 bullet_module 构建的结果:

Now you can change your CMakeLists.txt to look at results of bullet_module build:

set_target_properties(bullet_lib PROPERTIES IMPORTED_LOCATION
  <path/to/bullet_module>/build/intermediates/ndkBuild/debug/obj/local/${ANDROID_ABI}/libBullet.a)

这篇关于使用NDK,Gradle&amp;链接外部库Android Studio中的CMake的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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