graalvm / native-build-tools

Native-image plugins for various build tools
https://graalvm.github.io/native-build-tools/
Other
371 stars 61 forks source link

[Maven] Add ability to pass build arguments via command line #631

Open dnestoro opened 1 month ago

dnestoro commented 1 month ago

Is your feature request related to a problem? Please describe. As @alina-yur suggested: Right now there is no way to pass build args to builds that are invoked via Maven, such as for Spring apps. Currently this can only be done via Maven profiles, writing which is a lot of overhead for passing arguments

Describe the solution you'd like We need to provide a way to do something like mvn -Pnative native:compile -DbuildArg=<...>, so that arguments can be passed via command line. This should also support passing several arguments, andalso the argument -o for specifying the image name.

melix commented 1 month ago

In general this isn't such a good idea. Arguments passed by command line are by nature undocumented, opaque. Imagine build reproducibility: everything should be found in the build files, or it means that only god knows what was used to produce an artifact.

olpaw commented 1 month ago

everything should be found in the build files

I agree. That's what we have the bundle feature for (https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/Bundles.md). If you want a self-contained file that allows you to replay a NI build, this should be your first choice.

BTW, the above is already possible even without adding support for -DbuildArg=<...> by using the NATIVE_IMAGE_OPTIONS environment variable. See https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md#picked-up-native_image_options cc @fniephaus

alina-yur commented 1 month ago

Hello. My use case is that if I want to customize the build process of the same application, such as for benchmarking, when I need an instrumented version, a plain Native Image version, and a Native Image version with all optimizations, this is what I have to do at the moment:

    <profiles>
        <profile>
            <id>instrumented</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <configuration>
                            <imageName>demo-instrumented</imageName>
                            <buildArgs>
                                <buildArg>--pgo-instrument</buildArg>
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>optimized</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <configuration>
                            <imageName>demo-optimized</imageName>
                            <buildArgs>
                                <buildArg>--gc=G1</buildArg>
                                <buildArg>--pgo=${project.basedir}/default.iprof</buildArg>
                                <buildArg>-march=native</buildArg>
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>monitored</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <configuration>
                            <imageName>demo-monitored</imageName>
                            <buildArgs>
                                <buildArg>--pgo=${project.basedir}/default.iprof</buildArg>
                                <buildArg>-march=native</buildArg>
                                <buildArg>--enable-monitoring=heapdump,jfr,jvmstat</buildArg>
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

The same applies if I need to add SBOM, -Os, or any other customization while keeping a clean default version of the build for comparison.

fniephaus commented 1 month ago

the above is already possible even without adding support for -DbuildArg=<...> by using the NATIVE_IMAGE_OPTIONS environment variable.

That's correct. Nonetheless, the discoverability of this env var is relatively poor. In the context of the NBTs, we either need to document this more, or provide the ability to inject args via an user property. I would be in favor of a dedicated user property, for example -Dnative-image.build.args="--pgo-instrument", similar to exec:exec's -Dexec.args="-X myproject:dist", because that will feel most intuitive for Maven users.

olpaw commented 1 month ago

I would be in favor of a dedicated user property, for example -Dnative-image.build.args="--pgo-instrument", similar to exec:exec's -Dexec.args="-X myproject:dist", because that will feel most intuitive for Maven users.

Adding support for something like -Dnative-image.build.args=<extra-native-image-args> to the native-maven-plugin is fine for me. I was not suggesting it to be a bad idea. I was trying to make an argument that ways to influence the behavior of a tool for the sake on convenience/debugging are common and useful.

fniephaus commented 1 month ago

I was not suggesting it to be a bad idea.

And I was not suggesting that. ;) I think providing users with different ways to achieve the same is not always bad, at least they can choose what they want to use.