Gradle:独立于 SDK 构建目标更改 NDK 构建目标
Gradle: change NDK build target independent from the SDK build target
过去我将 eclipse 用于 NDK 项目,Android.mk 文件非常适合使用 API 级别 9 编译 NDK,同时让应用程序 (SDK) 在 [=39= 上编译] 级别 22。但是,当使用带有 Android Studio 1.3 RC1 的实验性 Gradle 构建系统 (2.5) 时,这似乎是不可能的。
如何才能在 API 级别 9 上仅编译 NDK?
我的典型 Android.mk 文件如下所示:
APP_PLATFORM := android-9
APP_STL := stlport_static
APP_ABI := all
# Enable c++11 extentions in source code
APP_CPPFLAGS += -std=c++11
#Enable optimalization in release mode
APP_OPTIM := release
我的新 gradle 文件如下所示:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 22
buildToolsVersion = "23.0.0 rc3"
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "NativeLibrary"
cppFlags += "-I${file("src/main/jni/some_folder")}".toString()
cppFlags += "-std=c++11"
//What should be added here to compile the NDK on API 9???
CFlags += "-DNDEBUG"
CFlags += "-fvisibility=hidden"
cppFlags += "-fvisibility=hidden"
ldLibs += ["log"]
stl = "stlport_static"
}
android.buildTypes {
release {
isMinifyEnabled = true
proguardFiles += file('D:/path/proguard-rules.pro')
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:22.2.0'
}
我调查了 Gradle 源代码,似乎 NDK 构建目标与 compileSdkVersion 硬编码相同。有没有办法避免或改变这种行为?
NdkCompile.groovy(创建文件)
// target
IAndroidTarget target = getPlugin().loadedSdkParser.target
if (!target.isPlatform()) {
target = target.parent
}
commands.add("APP_PLATFORM=" + target.hashString())
Sdk.groovy(目标是从compileSdkVersion中获取的)
public SdkParser loadParser() {
checkNotNull(extension, "Extension has not been set")
// call getParser to ensure it's created.
SdkParser theParser = getParser()
if (!isSdkParserInitialized) {
String target = extension.getCompileSdkVersion()
if (target == null) {
throw new IllegalArgumentException("android.compileSdkVersion is missing!")
}
FullRevision buildToolsRevision = extension.buildToolsRevision
if (buildToolsRevision == null) {
throw new IllegalArgumentException("android.buildToolsVersion is missing!")
}
theParser.initParser(target, buildToolsRevision, logger)
isSdkParserInitialized = true
}
return theParser
}
model {
android {
compileSdkVersion = 22
buildToolsVersion '20'
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
好的,这是一个可怕的 hack,但它很容易。找到NDK,它应该在android-sdk/ndk-bundle。进入平台文件夹。将 android-21 重命名为其他名称。复制一份android-19,然后把android-21的三个64位文件夹复制进去,然后重命名为android-21。 Gradle 会认为它使用的是 android-21,并且它适用于 64 位目标,但对于 32 位目标它将使用 android 19。
我不是 100% 确定这是否安全,但我在几台设备上测试过它并且我现在有一个应用程序正在 Beta 测试中。我认为它比为 ndk-build 创建 gradle 任务更干净。每当 Google 修复实验性 gradle 时,除了重新安装 ndk 之外无需更改。
如果您使用的是实验性插件版本 0.4。你可以设置
android.ndk {
platformVersion = "19"
}
gradle 版本为 3.1.2
defaultConfig {
applicationId "com.xxx.player"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
abiFilters 'armeabi-v7a'
arguments "-DANDROID_PLATFORM=android-21" //config ANDROID_PLATFORM version on here
}
}
}
过去我将 eclipse 用于 NDK 项目,Android.mk 文件非常适合使用 API 级别 9 编译 NDK,同时让应用程序 (SDK) 在 [=39= 上编译] 级别 22。但是,当使用带有 Android Studio 1.3 RC1 的实验性 Gradle 构建系统 (2.5) 时,这似乎是不可能的。
如何才能在 API 级别 9 上仅编译 NDK?
我的典型 Android.mk 文件如下所示:
APP_PLATFORM := android-9
APP_STL := stlport_static
APP_ABI := all
# Enable c++11 extentions in source code
APP_CPPFLAGS += -std=c++11
#Enable optimalization in release mode
APP_OPTIM := release
我的新 gradle 文件如下所示:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 22
buildToolsVersion = "23.0.0 rc3"
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "NativeLibrary"
cppFlags += "-I${file("src/main/jni/some_folder")}".toString()
cppFlags += "-std=c++11"
//What should be added here to compile the NDK on API 9???
CFlags += "-DNDEBUG"
CFlags += "-fvisibility=hidden"
cppFlags += "-fvisibility=hidden"
ldLibs += ["log"]
stl = "stlport_static"
}
android.buildTypes {
release {
isMinifyEnabled = true
proguardFiles += file('D:/path/proguard-rules.pro')
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:22.2.0'
}
我调查了 Gradle 源代码,似乎 NDK 构建目标与 compileSdkVersion 硬编码相同。有没有办法避免或改变这种行为?
NdkCompile.groovy(创建文件)
// target
IAndroidTarget target = getPlugin().loadedSdkParser.target
if (!target.isPlatform()) {
target = target.parent
}
commands.add("APP_PLATFORM=" + target.hashString())
Sdk.groovy(目标是从compileSdkVersion中获取的)
public SdkParser loadParser() {
checkNotNull(extension, "Extension has not been set")
// call getParser to ensure it's created.
SdkParser theParser = getParser()
if (!isSdkParserInitialized) {
String target = extension.getCompileSdkVersion()
if (target == null) {
throw new IllegalArgumentException("android.compileSdkVersion is missing!")
}
FullRevision buildToolsRevision = extension.buildToolsRevision
if (buildToolsRevision == null) {
throw new IllegalArgumentException("android.buildToolsVersion is missing!")
}
theParser.initParser(target, buildToolsRevision, logger)
isSdkParserInitialized = true
}
return theParser
}
model {
android {
compileSdkVersion = 22
buildToolsVersion '20'
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
好的,这是一个可怕的 hack,但它很容易。找到NDK,它应该在android-sdk/ndk-bundle。进入平台文件夹。将 android-21 重命名为其他名称。复制一份android-19,然后把android-21的三个64位文件夹复制进去,然后重命名为android-21。 Gradle 会认为它使用的是 android-21,并且它适用于 64 位目标,但对于 32 位目标它将使用 android 19。
我不是 100% 确定这是否安全,但我在几台设备上测试过它并且我现在有一个应用程序正在 Beta 测试中。我认为它比为 ndk-build 创建 gradle 任务更干净。每当 Google 修复实验性 gradle 时,除了重新安装 ndk 之外无需更改。
如果您使用的是实验性插件版本 0.4。你可以设置
android.ndk {
platformVersion = "19"
}
gradle 版本为 3.1.2
defaultConfig {
applicationId "com.xxx.player"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
abiFilters 'armeabi-v7a'
arguments "-DANDROID_PLATFORM=android-21" //config ANDROID_PLATFORM version on here
}
}
}