Skip to content
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

Prepare NBT for release of GraalVM for JDK 21. #496

Merged
merged 2 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .github/workflows/deploy-documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
ssh-key: "${{ secrets.SSH_PRIVATE_KEY }}"
- name: "🔧 Prepare environment"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
os: [ ubuntu-22.04 ]
steps:
- name: "☁ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
ssh-key: "${{ secrets.SSH_PRIVATE_KEY }}"
- name: "🔧 Prepare environment"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-graalvm-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: "🔧 Prepare environment"
uses: ./.github/actions/prepare-environment
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-junit-platform-native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: "🔧 Prepare environment"
uses: ./.github/actions/prepare-environment
with:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test-native-gradle-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: "🔧 Prepare environment"
uses: ./.github/actions/prepare-environment
with:
Expand All @@ -59,7 +59,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- uses: ./.github/actions/prepare-environment
with:
java-version: ${{ matrix.java-version }}
Expand All @@ -86,7 +86,7 @@ jobs:
os: [ windows-latest ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- uses: ./.github/actions/prepare-environment
with:
java-version: ${{ matrix.java-version }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-native-maven-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
os: [ ubuntu-20.04 ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- uses: ./.github/actions/prepare-environment
with:
java-version: ${{ matrix.java-version }}
Expand All @@ -57,7 +57,7 @@ jobs:
os: [ windows-latest ]
steps:
- name: "☁️ Checkout repository"
uses: actions/checkout@v2
uses: actions/checkout@v3
- uses: ./.github/actions/prepare-environment
with:
java-version: ${{ matrix.java-version }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ abstract class NativeTestArgumentProvider implements CommandLineArgumentProvider
"-cp", classpath.asPath,
"--no-fallback",
"--features=org.graalvm.junit.platform.JUnitPlatformFeature",
"-H:Name=native-image-tests",
"-H:Class=org.graalvm.junit.platform.NativeImageJUnitLauncher",
"-o", "native-image-tests",
"-Djunit.platform.listeners.uid.tracking.output.dir=${testIdsDir.get().asFile.absolutePath}"
]
if (agentOutputDir.isPresent()) {
Expand All @@ -110,12 +109,15 @@ abstract class NativeTestArgumentProvider implements CommandLineArgumentProvider
}

args << "-H:ConfigurationFileDirectories=${outputDir.absolutePath}/agentOutput"
args << "-H:+AllowIncompleteClasspath"
}

if (discovery.get()) {
args << "-DtestDiscovery"
}

// Main class comes last
args << "org.graalvm.junit.platform.NativeImageJUnitLauncher"

args.collect { it.toString() }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ abstract class NativeTestArgumentProvider implements CommandLineArgumentProvider
"-cp", classpath.asPath,
"--no-fallback",
"--features=org.graalvm.junit.platform.JUnitPlatformFeature",
"-H:Name=native-image-tests",
"-H:Class=org.graalvm.junit.platform.NativeImageJUnitLauncher",
"-o", "native-image-tests",
"-Djunit.platform.listeners.uid.tracking.output.dir=${testIdsDir.get().asFile.absolutePath}"
]
if (agentOutputDir.isPresent()) {
Expand All @@ -108,12 +107,15 @@ abstract class NativeTestArgumentProvider implements CommandLineArgumentProvider
}

args << "-H:ConfigurationFileDirectories=${outputDir.absolutePath}/agentOutput"
args << "-H:+AllowIncompleteClasspath"
}

if (discovery.get()) {
args << "-DtestDiscovery"
}

// Main class comes last
args << "org.graalvm.junit.platform.NativeImageJUnitLauncher"

args.collect { it.toString() }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class NativeImageUtils {

private static final Pattern graalvmVersionPattern = Pattern.compile("^(GraalVM|native-image) ([0-9]+)\\.([0-9]+)\\.([0-9]+).*");

private static final Pattern SAFE_SHELL_ARG = Pattern.compile("[A-Za-z0-9@%_\\-+=:,./]+");

public static void maybeCreateConfigureUtilSymlink(File configureUtilFile, Path nativeImageExecutablePath) {
if (!configureUtilFile.exists()) {
// possibly the symlink is missing
Expand Down Expand Up @@ -102,16 +104,22 @@ public static List<String> convertToArgsFile(List<String> cliArgs, Path outputDi
}
}


/**
* See https://github.com/oracle/graal/blob/f011d4d056a7ed78fe9669cc38062e6d09c14bed/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java#L1447C47-L1447C60.
*/
public static String escapeArg(String arg) {
if (!(arg.startsWith("\\Q") && arg.endsWith("\\E"))) {
arg = arg.replace("\\", "\\\\");
if (arg.contains(" ")) {
arg = "\"" + arg + "\"";
}
if (arg.isEmpty()) {
return "''";
}
return arg;
Matcher m = SAFE_SHELL_ARG.matcher(arg);
if (m.matches()) {
return arg;
}
return "'" + arg.replace("'", "'\"'\"'") + "'";
}


/**
*
* @param requiredVersion Required version can be {@code MAJOR}, {@code MAJOR.MINOR} or {@code MAJOR.MINOR.PATCH}
Expand Down Expand Up @@ -164,4 +172,12 @@ public static void checkVersion(String requiredVersion, String versionToCheck) {
}
}
}

public static int getMajorJDKVersion(String versionString) {
Matcher matcher = graalvmVersionPattern.matcher(versionString.trim());
if (matcher.matches()) {
return Integer.parseInt(matcher.group(2));
}
return -1;
}
}
1 change: 1 addition & 0 deletions docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ If you are using alternative build systems, see <<alternative-build-systems.adoc
=== Release 0.9.26

* Relax GraalVM version check for dev versions
* Prepare plugins for release of *GraalVM for JDK 21*. They no longer deploy any experimental options.

==== Gradle plugin

Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/snippets/gradle/groovy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ graalvmNative {
excludeConfig.put(file("path/to/artifact.jar"), listOf("^/META-INF/native-image/.*", "^/config/.*"))

// Advanced options
buildArgs.add('-H:Extra') // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
buildArgs.add('--link-at-build-time') // Passes '--link-at-build-time' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
jvmArgs.add('flag') // Passes 'flag' directly to the JVM running the native image builder

// Runtime options
Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/snippets/gradle/kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ graalvmNative {
excludeConfig.put(file("path/to/artifact.jar"), listOf("^/META-INF/native-image/.*", "^/config/.*"))

// Advanced options
buildArgs.add("-H:Extra") // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
buildArgs.add("--link-at-build-time") // Passes '--link-at-build-time' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
jvmArgs.add("flag") // Passes 'flag' directly to the JVM running the native image builder

// Runtime options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class JavaLibraryFunctionalTest extends AbstractFunctionalTest {
doesNotContain ':build'
}

outputContains "-H:+SharedLibrary"
outputContains "--shared"

and:
library.exists()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,26 @@ public class NativeImageCommandLineProvider implements CommandLineArgumentProvid

private final Provider<NativeImageOptions> options;
private final Provider<String> executableName;
private final Provider<String> outputDirectory;
private final Provider<String> workingDirectory;
private final Provider<String> outputDirectory;
private final Provider<RegularFile> classpathJar;
private final Provider<Boolean> useArgFile;
private final Provider<Integer> majorJDKVersion;

public NativeImageCommandLineProvider(Provider<NativeImageOptions> options,
Provider<String> executableName,
Provider<String> workingDirectory,
Provider<String> outputDirectory,
Provider<RegularFile> classpathJar,
Provider<Boolean> useArgFile) {
Provider<Boolean> useArgFile,
Provider<Integer> majorJDKVersion) {
this.options = options;
this.executableName = executableName;
this.workingDirectory = workingDirectory;
this.outputDirectory = outputDirectory;
this.classpathJar = classpathJar;
this.useArgFile = useArgFile;
this.majorJDKVersion = majorJDKVersion;
}

@Nested
Expand Down Expand Up @@ -119,13 +122,15 @@ public List<String> asArguments() {
appendBooleanOption(cliArgs, options.getVerbose(), "--verbose");
appendBooleanOption(cliArgs, options.getSharedLibrary(), "--shared");
appendBooleanOption(cliArgs, options.getQuickBuild(), "-Ob");
appendBooleanOption(cliArgs, options.getRichOutput(), "-H:+BuildOutputColorful");
appendBooleanOption(cliArgs, options.getRichOutput(), majorJDKVersion.getOrElse(-1) >= 21 ? "--color" : "-H:+BuildOutputColorful");
appendBooleanOption(cliArgs, options.getPgoInstrument(), "--pgo-instrument");

String targetOutputPath = getExecutableName().get();
if (getOutputDirectory().isPresent()) {
cliArgs.add("-H:Path=" + getOutputDirectory().get());
targetOutputPath = getOutputDirectory().get() + File.separator + targetOutputPath;
}
cliArgs.add("-H:Name=" + getExecutableName().get());
cliArgs.add("-o");
cliArgs.add(targetOutputPath);

options.getSystemProperties().get().forEach((n, v) -> {
if (v != null) {
Expand All @@ -145,9 +150,6 @@ public List<String> asArguments() {
if (!configFiles.isEmpty()) {
cliArgs.add("-H:ConfigurationFileDirectories=" + configFiles);
}
if (options.getMainClass().isPresent()) {
cliArgs.add("-H:Class=" + options.getMainClass().get());
}
if (Boolean.FALSE.equals(options.getPgoInstrument().get()) && options.getPgoProfilesDirectory().isPresent()) {
FileTree files = options.getPgoProfilesDirectory().get().getAsFileTree();
Set<File> profiles = files.filter(f -> f.getName().endsWith(".iprof")).getFiles();
Expand All @@ -156,12 +158,20 @@ public List<String> asArguments() {
}
}
cliArgs.addAll(options.getBuildArgs().get());

List<String> actualCliArgs;
if (useArgFile.getOrElse(true)) {
Path argFileDir = Paths.get(workingDirectory.get());
return NativeImageUtils.convertToArgsFile(cliArgs, argFileDir, argFileDir);
actualCliArgs = new ArrayList<>(NativeImageUtils.convertToArgsFile(cliArgs, argFileDir, argFileDir));
} else {
actualCliArgs = cliArgs;
}
return Collections.unmodifiableList(cliArgs);

/* Main class comes last. It is kept outside argument files as GraalVM releases before JDK 21 fail to detect the mainClass in these files. */
if (options.getMainClass().isPresent()) {
actualCliArgs.add(options.getMainClass().get());
}
return Collections.unmodifiableList(actualCliArgs);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public BuildNativeImageTask() {
getDisableToolchainDetection().convention(false);
}

private List<String> buildActualCommandLineArgs() {
private List<String> buildActualCommandLineArgs(int majorJDKVersion) {
getOptions().finalizeValue();
return new NativeImageCommandLineProvider(
getOptions(),
Expand All @@ -189,7 +189,8 @@ private List<String> buildActualCommandLineArgs() {
// a mapped value before the task was called, when we are actually calling it...
getProviders().provider(() -> getOutputDirectory().getAsFile().get().getAbsolutePath()),
getClasspathJar(),
getUseArgFile()).asArguments();
getUseArgFile(),
getProviders().provider(() -> majorJDKVersion)).asArguments();
}

// This property provides access to the service instance
Expand All @@ -203,18 +204,22 @@ public void exec() {
NativeImageOptions options = getOptions().get();
GraalVMLogger logger = GraalVMLogger.of(getLogger());

List<String> args = buildActualCommandLineArgs();
fniephaus marked this conversation as resolved.
Show resolved Hide resolved
if (options.getVerbose().get()) {
logger.lifecycle("Args are: " + args);
}
File executablePath = NativeImageExecutableLocator.findNativeImageExecutable(
options.getJavaLauncher(),
getDisableToolchainDetection(),
getGraalVMHome(),
getExecOperations(),
logger,
diagnostics);
checkRequiredVersionIfNeeded(executablePath, options);
String versionString = getVersionString(getExecOperations(), executablePath);
if (options.getRequiredVersion().isPresent()) {
NativeImageUtils.checkVersion(options.getRequiredVersion().get(), versionString);
}
int majorJDKVersion = NativeImageUtils.getMajorJDKVersion(versionString);
List<String> args = buildActualCommandLineArgs(majorJDKVersion);
if (options.getVerbose().get()) {
logger.lifecycle("Args are: " + args);
}
for (String diagnostic : diagnostics.getDiagnostics()) {
logger.lifecycle(diagnostic);
}
Expand All @@ -240,19 +245,14 @@ public void exec() {
}
}

private void checkRequiredVersionIfNeeded(File executablePath, NativeImageOptions options) {
if (!options.getRequiredVersion().isPresent()) {
return;
}
public static String getVersionString(ExecOperations execOperations, File executablePath) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ExecResult execResult = getExecOperations().exec(spec -> {
ExecResult execResult = execOperations.exec(spec -> {
spec.setStandardOutput(outputStream);
spec.args("--version");
spec.setExecutable(executablePath.getAbsolutePath());
});
execResult.assertNormalExitValue();
String versionToCheck = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
NativeImageUtils.checkVersion(options.getRequiredVersion().get(), versionToCheck);
return new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
}

}
Loading
Loading