Skip to content

Add developer documentation #678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Documentation for Developers

This document describes how to set up and develop native-build-tools on your local machine.

## Environment

The project uses Gradle as its build system. At the very minimum, you should set `JAVA_HOME` to a [Gradle-compatible JDK](https://docs.gradle.org/current/userguide/compatibility.html).

Some build tasks require a GraalVM JDK (e.g., tests). You should set `GRAALVM_HOME` to an appropriate GraalVM JDK.

## IDE setup

The native-build-tools repo is set up as a multi-project Gradle project, with the Maven and Gradle plugins declared as subprojects of the root project.
To set the project up in your IDE (e.g., IntelliJ IDEA), import the root project and the IDE should automatically import the subprojects.

## Building & testing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@melix can you please verify this section, because I didn't use these commands in the past?


You can use the various commands in the [Gradle build lifecycle](https://docs.gradle.org/current/userguide/build_lifecycle.html) to build and test the project.
Some examples (all executed from the root of the repository):

```bash
# Build all projects
./gradlew assemble

# Build only the native-gradle-plugin (for example)
./gradlew :native-gradle-plugin:assemble

# Build and run all tests
./gradlew build
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See you in 10 days :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's in 10 days? 😱

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if you run all tests, all functional tests, all verification in a single build, on a single machine, you can grab a few cups of coffee :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 good call, we should be conscientious of the planet (and our users' time)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Build all projects
./gradlew assemble
# Build only the native-gradle-plugin (for example)
./gradlew :native-gradle-plugin:assemble
# Build and run all tests
./gradlew build
# Compile all projects
./gradlew assemble
# Run unit tests in all projects
./gradlew test
# Run functional tests in all projects
./gradlew funTest
# Compile only the native-gradle-plugin (for example)
./gradlew :native-gradle-plugin:assemble
# Build and run all tests, complete (and very long) build
./gradlew build

```


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two lines empty space

## Debugging plugin(s)
It is often useful to attach a debugger to the Gradle and Maven plugins during a project build.

For the Gradle plugin, this can be accomplished by passing debugger options to the Gradle daemon via `org.gradle.jvmargs`, for example:

```bash
JAVA_OPTS="-Dorg.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000" ./gradlew assemble
```

The Gradle daemon will suspend on start-up, wait for you to attach a debugger, and then remain attached for subsequent Gradle commands.

For the Maven plugin, simply use the `mvnDebug` command in place of the `mvn` command.

## Testing local changes with an existing project
A common development task is to modify a plugin and then test it with an existing project.

To do this, first modify the project as necessary, and then build and publish the plugins to the local Maven repository:
```bash
./gradlew publishToMavenLocal --no-parallel
```

Next, update the plugin version string in the project build files.
The version can be found manually by searching for the published artifacts in `~/.m2/repository/org/graalvm/buildtools/native/`, or alternatively by checking the `nativeBuildTools` property [here](gradle/libs.versions.toml).

For Gradle, the change looks like the following.
You may also need to direct Gradle to use the local Maven repository to resolve the plugin:
```bash
# build.gradle
plugins {
...
- id 'org.graalvm.buildtools.native' version '0.9.25'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need both this and SNAPSHOT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this as a "diff" code sample to show how the existing build.gradle file might change (in this case, replacing a real release with a snapshot release)

+ id 'org.graalvm.buildtools.native' version '0.10.5-SNAPSHOT'
}

repositories {
+ mavenLocal()
...
}

# settings.gradle
pluginManagement {
repositories {
+ mavenLocal()
...
}
}
```

For Maven, simply bump the version and it should try the local repository automatically:
```bash
# pom.xml
- <native.maven.plugin.version>0.9.25</native.maven.plugin.version>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, why do we need this and SNAPSHOT?

+ <native.maven.plugin.version>0.10.5-SNAPSHOT</native.maven.plugin.version>
```

Then, run your build as usual. Gradle should find the plugin in the local repository and use it for the build.



3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Repository which contains build tool plugins for interoperability with [GraalVM
End-user documentation about the plugins can be found [here](https://graalvm.github.io/native-build-tools/).

## Contributing

Documentation for common developer tasks can be found [here](DEVELOPING.md).

### Projects
* [native-maven-plugin](native-maven-plugin/README.md)
* [native-gradle-plugin](native-gradle-plugin/README.md)
Expand Down
6 changes: 4 additions & 2 deletions native-gradle-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ End-user documentation about the plugins can be found [here](https://graalvm.git

## Building

This plugin can be built with this command:
This plugin can be built with this command (from the root directory):

```bash
./gradlew publishToMavenLocal --no-parallel
./gradlew :native-gradle-plugin:publishToMavenLocal --no-parallel
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried this command if it works?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works. It publishes only the gradle plugin and not the maven one.

```

For more details, see the [Developer documentation](../DEVELOPING.md).

In order to run testing part of this plugin you need to get (or build) corresponding `junit-platform-native` artifact.

*You can also take a look at CI workflow [here](../.github/workflows/test-native-gradle-plugin.yml).*
8 changes: 5 additions & 3 deletions native-maven-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ End-user documentation about the plugins can be found [here](https://graalvm.git

## Building

This plugin follows standard Maven plugin conventions and can be built with this command:
This plugin can be built with this command (from the root directory):

```shell
./gradlew publishAllPublicationsToCommonRepository
```bash
./gradlew :native-maven-plugin:publishToMavenLocal --no-parallel
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried this command if it works?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it will work. Although personally I'd avoid polluting maven local and stick with the "common repository" (I usually add a local repository to Gradle/Maven builds to avoid the erratic behavior of maven local).

Copy link
Member Author

@DSouzaM DSouzaM Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@melix could you explain how to use the common repository? After grepping this repo I still don't really understand how it works.

I tried ./gradlew publishAllPublicationsToCommonRepository --no-parallel but my changes were not picked up
(presumably I need to use it in my project's build definition).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is nothing special here, publishAllPublicationsToCommonRepository will update the repository found in build/common-repo, and for sure you need to use it in your project definition. For example in Gradle you'd simply add a repository which points to build/common-repo, and in Maven you'd add a <repository>. You don't have to go that way, you can publish to Maven local, but I personally think it's a bad practice, because Maven local is polluted with dozens of libraries which may make us accidentally think that a build is working, when if you try it on a different machine, it would break.

```

For more details, see the [Developer documentation](../DEVELOPING.md).

*You can also take a look at CI workflow [here](../.github/workflows/test-native-maven-plugin.yml).*
Loading