如何在 Android/NDK 上将命令行参数从 gradlew.bat 传递到 Clang

How to pass command line arguments from gradlew.bat to Clang on Android/NDK

本文关键字:bat gradlew Clang 参数 命令行 Android NDK      更新时间:2023-10-16

我正在使用一个 jenkins 脚本,它像这样调用 gradle:

./gradlew --info assembleRelease

我们的很多构建设置都存在于 gradle 文件中,这基本上没问题,因为通常我们知道我们想要通过发布或调试性质为特定类型的构建指定的所有内容。

但是,我们有一个例外,这是我们想要在 Jenkins 中使用切换来控制的标志。此标志将打开或关闭C++宏定义"TEST_MACRO"。

在没有创建新的构建类型的情况下,我希望只传入 -DTEST_MACRO 标志或类似标志。我可以用 gradlew 做到这一点吗?

./gradlew --info assembleRelease -DTEST_MACRO=1

这会作为全局定义的C++预处理器定义进入我们的 clang 编译器吗?有没有办法在不需要构建更多变体的情况下做到这一点?(例如,我们实际的构建系统有"googleRelease","googleDebug","googleStage","amazonRelease","amazonDebug","amazonStage",我想避免仅仅为了一个额外的cpp定义而必须有2倍的现有配置变体,我们想要打开和关闭。

一种可能性是使用其值配置为更改编译器选项的项目属性。下面,您可以找到一个独立的示例构建(使用 Gradle 6.0.1 进行测试(。

如果您运行

./gradlew build -PTEST_MACRO=Foo
build/exe/main/debug/*

然后这将打印"你好,福!

如果您运行

./gradlew build
build/exe/main/debug/*

然后这将打印"你好,世界!

自包含示例构建

build.gradle

plugins {
id 'cpp-application'
}
tasks.withType(CppCompile).configureEach {
if (project.hasProperty('TEST_MACRO')) {
macros.put('TEST_MACRO', project.TEST_MACRO)
}
}

src/main/cpp/hello.cpp

#include <iostream>
#define XSTR(x) STR(x)
#define STR(x) #x
int main()
{
#ifdef TEST_MACRO
std::cout << "Hello, " << XSTR(TEST_MACRO) << "!n";
#else
std::cout << "Hello, World!n";
#endif
return 0;
}

赏金接受的答案让我大部分时间都在那里,但是管道 gradle -P 提供参数的方法对我来说有点不同。我无法让宏放正常运行,也许我把它放在了错误的地方。

对于任何无法让 macros.put 工作的人,我的建议是执行以下操作:

./gradlew build -PTARGET_SERVER=DEV

然后在您的build.gradle文件中,这是一个不完整的代码片段(需要您的minSdkVersion和所有其他相关的项目设置内容(,它将cFlag传递给编译的apk:

apply plugin: 'com.android.application'
android {
defaultConfig {
externalNativeBuild.ndkBuild {
if (project.hasProperty('TARGET_SERVER')) {
cFlags += '-DTARGET_SERVER=' + project.TARGET_SERVER
}
arguments '-j' + Runtime.runtime.availableProcessors(), 'NDK_TOOLCHAIN_VERSION=clang'
}
}
}