Gradle C 插件示例

Gradle C Plugin by Example

在我的本地文件系统上,我有以下 C 项目目录结构:

derpus/
    src/
        derpus/
            c/
                derpus.c
            headers/
    build.gradle

其中 derpus.c 是:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    puts("Derp!");
    return EXIT_SUCCESS;
}

我想使用 Gradle Native (C) Plugin 来管理 derpus 构建的全部范围。具体来说,我希望 Gradle 到:

  1. 生成一个 Gradle 包装器,以便我可以对所有构建调用使用 gradlew;和
  2. 通过gradlew编译并构建derpusderpus.exe;和
  3. 当我 运行 gradlew eclipse 时生成 Eclipse 项目信息,这样我就可以将项目导入 Eclipse(我已经预安装了 Eclipse CDT 插件)

这是我的 build.gradle:

apply plugin: 'c'
apply plugin: 'eclipse'

sources {
    c {
        source {
            srcDir "src/derpus/c"
            include "**/*.c"
        }
        exportedHeaders {
            srcDir "src/derpus/headers"
        }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

显然我应该能够 运行 gradle wrapper 处理第一项。但是至于编译和构建,在 C 插件文档中我没有真正看到一个命令或构建调用 实际上 运行 是一个编译和构建 !

至于第三项,使用 Eclipse 插件并通过 gradlew eclipse 调用它,我想知道是否还有其他需要做的事情才能使生成的 project/settings 配置与Eclipse CDT 插件需要什么才能与 C 程序一起工作。虽然我打算让 Gradle 处理我所有的构建,但我仍然想在 Eclipse 中完成我的所有开发,因此 CDT 附带的所有东西(语法突出显示、编译等)都很重要对我来说。

好的,我想通了所有 3 个问题,并认为我会 post 这个答案供未来的读者使用。

请注意:此解决方案对于以下现代 C 程序员来说确实可行:

  • 想在 Eclipse 中完成所有开发,利用现代IDE设施,如语法高亮显示、错误、goto 声明、打开调用层次结构、Eclipse 的调试器等.; 但是...
  • 想要一个像 Gradle 一样的现代的、非常棒的构建系统来完成所有 command-line/shell 构建

此外,因为我在 Windows,我选择使用 MinGW 进行 GCC 配置,所以如果你在 *nix 或 Mac,或者你更喜欢 Cygwin ,您将不得不进一步自定义此解决方案。

此外,我只验证了这适用于 Eclipse Luna,使用最新的 Eclipse CDT 插件 (8.6) 并使用 Gradle 2.3.

解决方案

首先我必须纠正我对 C 插件的使用,将我的 build.gradle 更改为如下所示:

apply plugin: 'c'
apply plugin: 'eclipse'

model {
    components {
        derpus(NativeExecutableSpec) {
            sources {
                c(CSourceSet) {
                    source {
                        srcDir "src/derpus/c"
                        include "**/*.c"
                    }
                    exportedHeaders {
                        srcDir "src/derpus/headers"
                    }
                }
            }
        }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

这让我 运行 gradle wrapper 没有任何错误。

接下来,我开始发现 Gradle 本机二进制文件文档 从未 提到 compiling/building 本机可执行文件的构建调用非常奇怪。我疯狂地猜测它可能正在利用 Gradle 的 "convention over configuration" 方法,我 运行 gradlew build - 瞧!巨大的成功。现在derpus/build/binaries/derpusExecutable下我有derpus.exe!到目前为止,还不错。

当您想现在将这个 Gradle 管理的项目导入 Eclipse,但 Eclipse CDT 提供现代 C [=107= 的所有正常功能时,真正令人头疼的是].

我从 运行ning gradlew eclipse 开始,它在 derpus/ 项目根目录下添加了以下文件:

  • .project
  • .settings/language.settings

我打开 Eclipse 并将其作为一个项目导入,但是我遇到了各种错误,当我将鼠标悬停在 derpus.c 文件中的 #include <stdio.h> 上并单击 F3 时, Eclipse 什么也没做。显然有些东西仍然没有配置正确。所以我开始了黑客攻击。

原来你只需要:

  • 当然,首先要确保 CDT 插件已安装并正常工作(哦!)
  • 在 Eclipse 中创建一个 "dummy" C 项目,这将允许您将 Eclipse CDT 生成的 settings/configs 复制并粘贴到您的 actual 项目
  • 修改您的实际 .project 文件以包含在虚拟项目的 .project 文件
  • 中生成的相同 <buildSpec /><natures /> 元素
  • 将虚拟项目的 .cproject 文件复制到实际项目的根目录,然后在文本编辑器中打开它。您想用实际项目的名称重命名虚拟项目名称的所有实例;在我的例子中有 3 个实例。在我的例子中,我的虚拟项目被命名为 dummy,而我的实际项目被命名为 derpus。所以我不得不在这个文件中将 dummy 的 3 个实例更改为 derpus
  • 重新启动 Eclipse

您的实际项目现在的行为方式与使用 CDT 插件创建的 C 项目完全相同。不要忘记删除你的 "dummy" 项目 ;-)

您可以在以下帮助下为项目添加 c++ 特性:

  1. 创建一个 gradle 项目
  2. select 项目
  3. 使用Eclipse->new->其他
  4. select c++ -> 转换为 c++ 项目
  5. 清理项目

刚刚尝试过(使用 Gradle 4.3),我想指出您可以将 model 部分简化为:

model {
    components {
        derpus(NativeExecutableSpec)
    }
}

因为源目录默认为"src/derpus/c"

此时,gradle 版本 6.2.2,新的 C++ 插件可以用于该任务。包装器任务默认存在。通过添加 eclipse 插件可以使用 Eclipse 任务。

plugins {
    id 'cpp-application'
    id 'eclipse'
}

application {
    binaries.configureEach {
        def compileTask = compileTask.get()
        compileTask.source.from fileTree(dir: "src/derpus/c", include: "**/*.c")
        if (toolChain instanceof VisualCpp) {
            compileTask.compilerArgs = ["/TC"]
        } else if (toolChain instanceof GccCompatibleToolChain) {
            compileTask.compilerArgs = ["-x", "c", "-std=c11"]
        }

        def linkTask = linkTask.get()
        if (toolChain instanceof GccCompatibleToolChain) {
            linkTask.linkerArgs = ["-nodefaultlibs", "-lc"]
        }
    }
}

参考:

https://github.com/gradle/native-samples/tree/master/c/application