使用NDK、Gradle和;Android Studio中的CMake

使用NDK、Gradle和;Android Studio中的CMake,android,c++,android-studio,cmake,android-ndk,Android,C++,Android Studio,Cmake,Android Ndk,在一段时间后,我又回到了Android开发领域,我以前基于ANT的构建链在最新的SDK中似乎不再起作用(这是一个单独的问题),因此我尝试以新的方式做事情,这是基于gradle和CMake的 我有许多项目需要的预构建静态和动态第三方库,但我无法成功链接这些库。 据我所知,这些需要在“CMakeLists.txt”文件中指定,而不是在“build.gradle”文件中指定,但我对这两个系统都是新手,因此如果我错了,请纠正我 以下是我迄今为止所尝试的: 首先,我试图确定子弹的位置。我曾经尝试过省略'

在一段时间后,我又回到了Android开发领域,我以前基于ANT的构建链在最新的SDK中似乎不再起作用(这是一个单独的问题),因此我尝试以新的方式做事情,这是基于gradle和CMake的

我有许多项目需要的预构建静态和动态第三方库,但我无法成功链接这些库。
据我所知,这些需要在“CMakeLists.txt”文件中指定,而不是在“build.gradle”文件中指定,但我对这两个系统都是新手,因此如果我错了,请纠正我

以下是我迄今为止所尝试的:

  • 首先,我试图确定子弹的位置。我曾经尝试过省略'lib'、.a'和'armeabi-v7a'的变体(希望它能选择正确的CPU变体),但都没有成功

     find_library(bullet_lib libBullet.a HINTS ${LIBBASE}bullet3/build3/Android/obj/local/armeabi-v7a)
    
    我不确定这与
    target\u link\u库中包含的库有何不同

    add_library(bullet_lib STATIC IMPORTED)
    
    这会发现内置库很好,但“bullet”和其他第三方LIB会出现链接器错误

    target_link_libraries(my_project_name android log EGL GLESv2 bullet_lib) 
    
${LIBBASE}
是第三方库的基本目录,看起来还可以,但还有一件事:CMake错误似乎不会出现在android studio中!我可以通过在包含“CMakeLists.txt”文件的文件夹中运行
cmake.
来找出它的问题所在,但我不确定我是否使用正确的参数来调用它:无论Android Studio对cmake做了什么,这个文件现在对我来说都是一个黑匣子

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

从命令行运行“cmake.”可以得到:

-- 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”)

此外,我在“CMakeLists.txt”文件中使用以下行来报告构建的状态:

message(WARNING "resolved libraries:")
message(WARNING ${LIBBASE}bullet3/build3/Android/obj/local/armeabi-v7a)
message(WARNING ${bullet_lib})
不管怎么说,我显然遗漏了一些东西,我还没有找到任何关于这方面的明确指南。这似乎是一件非常简单和明显的事情(链接一个库),但这似乎是一个巨大的痛苦。
如果有任何建议,我将不胜感激。

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

android {
  externalNativeBuild {
    cmake {
      path 'CMakeLists.txt'
    }
  }
  defaultConfig {
     ndk {
        abiFilters 'armeabi-v7a'
    }
    externalNativeBuild {
      cmake {
         arguments '-DCMAKE_VERBOSE_MAKEFILE=ON'
      }
    }
  }
}
在您的
E:\prog\anthracoite\gradle\anthracoiteplayerapi21\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\u link\u libraries
中库的顺序可能很重要,因此请将静态库保留在左侧

我猜你用ndk build构建libBullet.a。您可以为您的AS项目创建一个单独的库模块(让我们调用bullet_模块),即使它没有Java文件,并将其指向
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_模块的生成结果:

set_target_properties(bullet_lib PROPERTIES IMPORTED_LOCATION
  <path/to/bullet_module>/build/intermediates/ndkBuild/debug/obj/local/${ANDROID_ABI}/libBullet.a)
设置目标属性(项目符号库属性导入位置
/build/intermediates/ndkBuild/debug/obj/local/${ANDROID_ABI}/libBullet.a)

我在问题帖中没有看到任何错误消息。我遗漏了什么吗?不,对不起:我没有添加它们。它们是来自clang的链接器错误:它没有说明无法从Android Studio内部找到库(正如我所说,Android Studio似乎没有报告CMake错误,这不是很有帮助)。我将用链接器错误更新我的帖子。如果您使用此路径添加预构建库,此示例可能会有所帮助:它显示了如何(使用CMake)链接预构建(外部)库。这取决于您想走哪条路,最终您可能会转到ndk构建路径来跟踪您的代码等。在
添加库(bullet\u lib STATIC IMPORTED)
之后,您需要为具有
设置目标属性的库文件添加位置(lib PROPERTIES导入了_LOCATION
,并将目标设置为包含头文件。您可能会发现这很有用:。嗨,Alex,根据您在另一个论坛上的建议,我一直在使用我以前使用的android.mk构建文件,该文件以前使用您的建议在下面运行。我还没有得到此构建(有关我当前的链接器问题,请参阅)但我离这更近了。我也会尝试让它与CMake一起工作。谢谢你的帮助:我似乎已经忘记了我学到的关于android NDK开发的知识的一半!好吧,如果你能(几乎)build
libanthracoite lib。因此,使用ndk build,显然更容易避免单独的模块、预构建的库等。使用ndk build进行任何事情都要干净得多,并且具有“自然”的库依赖关系。
set_target_properties(bullet_lib PROPERTIES IMPORTED_LOCATION
  <path/to/bullet_module>/build/intermediates/ndkBuild/debug/obj/local/${ANDROID_ABI}/libBullet.a)