gpt4 book ai didi

Android Studio 14 原生开发 + CrystaX NDK

转载 作者:太空宇宙 更新时间:2023-11-03 12:05:35 25 4
gpt4 key购买 nike

我正在尝试将一个巨大的跨平台 C++11 (iOS+Android) 应用程序项目迁移到 Android Studio 14。我正在使用 CrystaX NDK 进行提升和 C++14。在他们网站的博客上有一个官方的 Android Studio + CrystaX 教程 here但它已经过时了。

我已经下载了用于 Android Studio 1.4 的官方 hello-jni 示例,并尝试将其调整为与 CrystaX NDK 一起使用。这些是我的 Gradle 2.5 设置:

项目build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
}
}

allprojects {
repositories {
jcenter()
}
}

module build.gradle

apply plugin: 'com.android.model.application'

model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"

defaultConfig.with {
applicationId = "com.tableair.app"
minSdkVersion.apiLevel = 4
targetSdkVersion.apiLevel = 23
}
}

compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}

/*
* native build settings
*/
android.ndk {
moduleName = "tableair-framework"
cppFlags += "-std=c++11"
cppFlags += "-Werror"
ldLibs = ["android", "log", "GLESv2", "crystax"]
stl = "gnustl_static"
/*
* Other ndk flags configurable here are
* cppFlags += "-fno-rtti"
* cppFlags += "-fno-exceptions"
* ldLibs = ["android", "log"]
* stl = "system"
*/
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
android.productFlavors {
// for detailed abiFilter descriptions, refer to "Supported ABIs" @
// https://developer.android.com/ndk/guides/abis.html#sa
create("arm") {
ndk.abiFilters += "armeabi"
}
create("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create("arm8") {
ndk.abiFilters += "arm64-v8a"
}
create("x86") {
ndk.abiFilters += "x86"
}
create("x86-64") {
ndk.abiFilters += "x86_64"
}
create("mips") {
ndk.abiFilters += "mips"
}
create("mips-64") {
ndk.abiFilters += "mips64"
}
// To include all cpu architectures, leaves abiFilters empty
create("all")
}
}

local.properties

ndk.dir=/Users/vilius/Software/Android/crystax-ndk-10.2.1
sdk.dir=/Users/vilius/Library/Android/sdk

当我尝试运行应用程序时。我收到此错误:

....
:app:generateAllDebugAndroidTestSources UP-TO-DATE
:app:copyArm64-v8aDebugAllTableair-frameworkSharedLibraryGdbServer UP-TO-DATE
:app:createArm64-v8aDebugAllTableair-frameworkSharedLibraryGdbsetup
:app:compileArm64-v8aDebugAllTableair-frameworkSharedLibraryTableair-frameworkMainC UP-TO-DATE
:app:linkArm64-v8aDebugAllTableair-frameworkSharedLibrary
/Users/vilius/Software/Android/crystax-ndk-10.2.1/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld: cannot find -lcrystax
/Users/vilius/Software/Android/crystax-ndk-10.2.1/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld: cannot find -lcrystax
Error:error: ld returned 1 exit status
Error:Execution failed for task ':app:linkArm64-v8aDebugAllTableair-frameworkSharedLibrary'.
> A build operation failed.
Linker failed while linking libtableair-framework.so.
See the complete log at: file:///Users/vilius/TableAir/Mobile/app/android-studio-project/app/build/tmp/linkArm64-v8aDebugAllTableair-frameworkSharedLibrary/output.txt

.../output.txt 显示与消息窗口中完全相同的信息。

有人对这个问题有想法吗?

最佳答案

是的,示例 here 有点过时,因此我们计划很快发布新文章,更新如何使用 CrystaX NDK 和新的实验性 Gradle 插件的描述。同时,你可以看看我已经推送到github的example。该示例中最有趣的部分是应用程序的 build.gradle,因此为方便起见,我将其复制到此处:

import org.gradle.internal.os.OperatingSystem;

apply plugin: 'com.android.model.application'

final APP_ABIS = ["armeabi", "armeabi-v7a", "x86"]
final BOOST_SHARED_LIBS = ["boost_serialization"]

model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"

defaultConfig.with {
applicationId = "net.crystax.testboost2"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = compileSdkVersion.asType(Integer)
versionCode = 1
versionName = "1.0"
}

}

compileOptions.with {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}

android.ndk {
moduleName = "test-boost2"
cppFlags += "-std=c++11"
cppFlags += "-fexceptions"
cppFlags += "-frtti"
cppFlags += "-Werror"
cppFlags += "-I" + getBoostIncDir()
ldLibs.addAll BOOST_SHARED_LIBS
ldLibs += "log"
stl = "gnustl_shared"
}

android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}

android.productFlavors {
APP_ABIS.each { abi ->
create(getFlavorName(abi)) {
ndk.with {
abiFilters += abi
getPrebuiltLibPaths(abi).each { path ->
ldFlags += "-L" + path
}
}
}
}
}

}

tasks.all {
task ->
if (task.name.startsWith('link')) {
task.dependsOn copyNativeLibs, stripNativeLibs
}
}

task copyNativeLibs {
["debug", "release"].each { buildType ->
APP_ABIS.each { abi ->
def libs = [:]
BOOST_SHARED_LIBS.each { name ->
libs[name] = "${getBoostLibDir(abi)}/lib${name}.so"
}
libs.crystax = getLibCrystax(abi)

libs.each { name, file ->
dependsOn tasks.create(name: "copy-native-library-${name}-${abi}-${buildType}", type: Copy) {
from file
into getTargetLibDir(abi, buildType)
}
}
}
}
}

task stripNativeLibs(dependsOn: copyNativeLibs) {
["debug", "release"].each { buildType ->
APP_ABIS.each { abi ->
def libs = []
libs.addAll(BOOST_SHARED_LIBS)
libs += "crystax"

libs.each { name ->
dependsOn tasks.create(name: "strip-native-library-${name}-${abi}-${buildType}", type: Exec) {
commandLine getStripExecutable(abi), "--strip-unneeded", "${getTargetLibDir(abi, buildType)}/lib${name}.so"
}
}

}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}

def getNdkDir() {
if (System.env.ANDROID_NDK_ROOT != null)
return System.env.ANDROID_NDK_ROOT

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkdir = properties.getProperty('ndk.dir', null)
if (ndkdir == null)
throw new GradleException("""\
NDK location not found.
Define location with ndk.dir in the local.properties file
or with an ANDROID_NDK_ROOT environment variable.""")

return ndkdir
}

def getCrystaxNdkDir() {
def ndkDir = getNdkDir()
if (!(new File(ndkDir, "sources/crystax").exists()))
throw new GradleException("""\
'${ndkDir}' is not a CrystaX NDK.
Edit ndk.dir in local.properties or set ANDROID_NDK_ROOT
environment variable pointing to CrystaX NDK""")

return ndkDir
}

def getFlavorName(abi) {
switch (abi) {
case "armeabi":
return "arm";
case "armeabi-v7a":
return "arm7"
case "arm64-v8a":
return "arm64"
default:
return abi.replaceAll('-', '_')
}
}

def getToolchainName(abi) {
switch (abi) {
case ~/^armeabi.*/:
return "arm-linux-androideabi"
case ~/^arm64.*/:
return "aarch64-linux-android"
case "mips":
return "mipsel-linux-android"
case "mips64":
return "mips64el-linux-android"
case ["x86", "x86_64"]:
return abi
default:
throw new GradleException("Unsupported ABI: '${abi}'")
}
}

def getToolchainPrefix(abi) {
switch (abi) {
case ~/^armeabi.*/:
return "arm-linux-androideabi"
case ~/^arm64.*/:
return "aarch64-linux-android"
case "mips":
return "mipsel-linux-android"
case "mips64":
return "mips64el-linux-android"
case "x86":
return "i686-linux-android"
case "x86_64":
return "x86_64-linux-android"
default:
throw new GradleException("Unsupported ABI: '${abi}'")
}
}

def getHostOS() {
if (OperatingSystem.current().isLinux())
return "linux"
if (OperatingSystem.current().isMacOsX())
return "darwin"
if (OperatingSystem.current().isWindows())
return "windows"
throw new GradleException("Unsupported host OS")
}

def getHostArch() {
def arch = System.getProperty("os.arch")
switch (arch) {
case ["x86_64", "amd64"]:
return "x86_64"
case ~/^i[3456]86/:
case "x86":
return "x86"
default:
throw new GradleException("Can't detect host's CPU architecture: '${arch}'")
}
}

def getHostTag() {
def tag = getHostOS()
def arch = getHostArch()
if (tag != "windows" || arch != "x86")
tag += "-${arch}"
return tag
}

def getStripExecutable(abi) {
def ndk = getCrystaxNdkDir()
def toolchainName = getToolchainName(abi)
def toolchainPrefix = getToolchainPrefix(abi)
def hostTag = getHostTag()
def strip = "${ndk}/toolchains/${toolchainName}-4.9/prebuilt/${hostTag}/bin/${toolchainPrefix}-strip"
if (OperatingSystem.current().isWindows())
strip = strip.replaceAll('/', '\\\\') + '.exe'
return strip
}

def getPrebuiltLibPaths(abi) {
def paths = []
paths += getBoostLibDir(abi)
paths += getLibCrystaxDir(abi)
return paths
}

def getTargetLibDir(abi, buildType) {
return "${buildDir}/intermediates/binaries/${buildType}/${getFlavorName(abi)}/lib/${abi}"
}

def getLibCrystaxDir(abi) {
return "${getCrystaxNdkDir()}/sources/crystax/libs/${abi}"
}

def getLibCrystax(abi) {
return "${getLibCrystaxDir(abi)}/libcrystax.so"
}

def getBoostDir() {
return "${getCrystaxNdkDir()}/sources/boost/1.58.0"
}

def getBoostIncDir() {
return "${getBoostDir()}/include"
}

def getBoostLibDir(abi) {
return "${getBoostDir()}/libs/${abi}"
}

我已经用 Android Studio 1.4 和 gradle experimental plugin 0.2.0 测试过了。

实际上,自定义copyNativeLibs 任务只需要将共享库包含到apk 中;如果您链接静态库,则根本不需要 copyNativeLibs

更新:我添加了 stripNativeLibs 任务只是因为我意识到 APK 包含了带有调试信息的未剥离的库,这使得它的大小太大而没有任何实际需要

关于Android Studio 14 原生开发 + CrystaX NDK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32911106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com