Skip to content

Commit

Permalink
[GR-39043] [GR-38660] Introduce native-image driver command-line only…
Browse files Browse the repository at this point in the history
… options.

PullRequest: graal/11943
  • Loading branch information
olpaw committed Jun 10, 2022
2 parents 2facc6d + d7158af commit 006c61d
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 139 deletions.
2 changes: 2 additions & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-38965) Heap dumps are now supported in Community Edition.
* (GR-38951) Add `-XX:+DumpHeapAndExit` option to dump the initial heap of a native executable.
* (GR-37582) Run image-builder on module-path per default. Opt-out with env setting `USE_NATIVE_IMAGE_JAVA_PLATFORM_MODULE_SYSTEM=false`.
* (GR-38660) Expose -H:Name=<outfile> as API option -o <outfile>
* (GR-39043) Make certain native-image options command-line only and ensure they get processed before other options (--exclude-config --configurations-path --version --help --help-extra --dry-run --debug-attach --expert-options --expert-options-all --expert-options-detail --verbose-server --server-*)

## Version 22.1.0
* (GR-36568) Add "Quick build" mode, enabled through option `-Ob`, for quicker native image builds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public static boolean parseOnce() {
@Option(help = "Name of the main entry point method. Optional if --shared is used.")//
public static final HostedOptionKey<String> Method = new HostedOptionKey<>("main");

@APIOption(name = "-o", valueSeparator = APIOption.WHITESPACE_SEPARATOR)//
@Option(help = "Name of the output file to be generated", type = OptionType.User)//
public static final HostedOptionKey<String> Name = new HostedOptionKey<>("");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.driver;

import java.io.File;
import java.nio.file.Paths;
import java.util.regex.Pattern;

import org.graalvm.compiler.options.OptionType;

import com.oracle.svm.core.option.OptionOrigin;
import com.oracle.svm.core.option.OptionUtils;
import com.oracle.svm.driver.NativeImage.ArgumentQueue;

class CmdLineOptionHandler extends NativeImage.OptionHandler<NativeImage> {

private static final String helpText = NativeImage.getResource("/Help.txt");
private static final String helpExtraText = NativeImage.getResource("/HelpExtra.txt");

/* Defunct legacy options that we have to accept to maintain backward compatibility */
private static final String verboseServerOption = "--verbose-server";
private static final String serverOptionPrefix = "--server-";

private static final String javaRuntimeVersion = System.getProperty("java.runtime.version");

boolean useDebugAttach = false;

CmdLineOptionHandler(NativeImage nativeImage) {
super(nativeImage);
}

@Override
boolean consume(ArgumentQueue args) {
String headArg = args.peek();
boolean consumed = consume(args, headArg);
OptionOrigin origin = OptionOrigin.from(args.argumentOrigin);
if (consumed && !origin.commandLineLike()) {
String msg = String.format("Using '%s' provided by %s is only allowed on command line.", headArg, origin);
throw NativeImage.showError(msg);
}
return consumed;
}

private boolean consume(ArgumentQueue args, String headArg) {
switch (headArg) {
case "--help":
args.poll();
singleArgumentCheck(args, headArg);
nativeImage.showMessage(helpText);
nativeImage.showNewline();
nativeImage.apiOptionHandler.printOptions(nativeImage::showMessage, false);
nativeImage.showNewline();
nativeImage.optionRegistry.showOptions(null, true, nativeImage::showMessage);
nativeImage.showNewline();
System.exit(0);
return true;
case "--version":
args.poll();
singleArgumentCheck(args, headArg);
String message;
if (NativeImage.IS_AOT) {
message = System.getProperty("java.vm.version");
} else {
message = "native-image " + NativeImage.graalvmVersion + " " + NativeImage.graalvmConfig;
}
message += " (Java Version " + javaRuntimeVersion + ")";
nativeImage.showMessage(message);
System.exit(0);
return true;
case "--help-extra":
args.poll();
singleArgumentCheck(args, headArg);
nativeImage.showMessage(helpExtraText);
nativeImage.apiOptionHandler.printOptions(nativeImage::showMessage, true);
nativeImage.showNewline();
nativeImage.optionRegistry.showOptions(OptionUtils.MacroOptionKind.Macro, true, nativeImage::showMessage);
nativeImage.showNewline();
System.exit(0);
return true;
case "--configurations-path":
args.poll();
String configPath = args.poll();
if (configPath == null) {
NativeImage.showError(headArg + " requires a " + File.pathSeparator + " separated list of directories");
}
for (String configDir : configPath.split(File.pathSeparator)) {
nativeImage.addMacroOptionRoot(nativeImage.canonicalize(Paths.get(configDir)));
}
return true;
case "--exclude-config":
args.poll();
String excludeJar = args.poll();
if (excludeJar == null) {
NativeImage.showError(headArg + " requires two arguments: a jar regular expression and a resource regular expression");
}
String excludeConfig = args.poll();
if (excludeConfig == null) {
NativeImage.showError(headArg + " requires resource regular expression");
}
nativeImage.addExcludeConfig(Pattern.compile(excludeJar), Pattern.compile(excludeConfig));
return true;
case DefaultOptionHandler.verboseOption:
args.poll();
nativeImage.setVerbose(true);
return true;
case "--dry-run":
args.poll();
nativeImage.setDryRun(true);
return true;
case "--expert-options":
args.poll();
nativeImage.setPrintFlagsOptionQuery(OptionType.User.name());
return true;
case "--expert-options-all":
args.poll();
nativeImage.setPrintFlagsOptionQuery("");
return true;
case "--expert-options-detail":
args.poll();
String optionNames = args.poll();
nativeImage.setPrintFlagsWithExtraHelpOptionQuery(optionNames);
return true;
case verboseServerOption:
args.poll();
NativeImage.showWarning("Ignoring server-mode native-image argument " + headArg + ".");
return true;
}

String debugAttach = "--debug-attach";
if (headArg.startsWith(debugAttach)) {
if (useDebugAttach) {
throw NativeImage.showError("The " + debugAttach + " option can only be used once.");
}
useDebugAttach = true;
String debugAttachArg = args.poll();
String addressSuffix = debugAttachArg.substring(debugAttach.length());
String address = addressSuffix.isEmpty() ? "8000" : addressSuffix.substring(1);
/* Using agentlib to allow interoperability with other agents */
nativeImage.addImageBuilderJavaArgs("-agentlib:jdwp=transport=dt_socket,server=y,address=" + address + ",suspend=y");
/* Disable watchdog mechanism */
nativeImage.addPlainImageBuilderArg(nativeImage.oHDeadlockWatchdogInterval + "0");
return true;
}

if (headArg.startsWith(serverOptionPrefix)) {
args.poll();
NativeImage.showWarning("Ignoring server-mode native-image argument " + headArg + ".");
String serverOptionCommand = headArg.substring(serverOptionPrefix.length());
if (!serverOptionCommand.startsWith("session=")) {
/*
* All but the --server-session=... option used to exit(0). We want to simulate that
* behaviour for proper backward compatibility.
*/
System.exit(0);
}
return true;
}

return false;
}

private static void singleArgumentCheck(ArgumentQueue args, String arg) {
if (!args.isEmpty()) {
NativeImage.showError("Option " + arg + " cannot be combined with other options.");
}
}
}
Loading

0 comments on commit 006c61d

Please sign in to comment.