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

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

我正在使用一个调用 gradle 的 jenkins 脚本,如下所示:

./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 定义我们想要打开和关闭的现有配置的 2x 变化。)

一种可能是使用 project property whose value is configured to change the compiler options。在下面,您可以找到一个独立的示例构建(使用 Gradle 6.0.1 测试)。

如果你运行

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

然后这将打印“Hello, Foo!”。

如果你运行

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

然后这将打印“Hello, World!”。

独立示例构建

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 正常运行,也许我放错了地方。

我对无法 macros.put 工作的人的建议是:

./gradlew build -PTARGET_SERVER=DEV

然后在您的 build.gradle 文件中,这是相关部分的不完整片段(需要您的 minSdkVersion 和所有其他相关项目设置内容),它将 cFlags 传递给编译的 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'
        }
    }
}