Skip to content

Commit 006c61d

Browse files
committed
[GR-39043] [GR-38660] Introduce native-image driver command-line only options.
PullRequest: graal/11943
2 parents 2facc6d + d7158af commit 006c61d

File tree

5 files changed

+220
-139
lines changed

5 files changed

+220
-139
lines changed

substratevm/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ This changelog summarizes major changes to GraalVM Native Image.
99
* (GR-38965) Heap dumps are now supported in Community Edition.
1010
* (GR-38951) Add `-XX:+DumpHeapAndExit` option to dump the initial heap of a native executable.
1111
* (GR-37582) Run image-builder on module-path per default. Opt-out with env setting `USE_NATIVE_IMAGE_JAVA_PLATFORM_MODULE_SYSTEM=false`.
12+
* (GR-38660) Expose -H:Name=<outfile> as API option -o <outfile>
13+
* (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-*)
1214

1315
## Version 22.1.0
1416
* (GR-36568) Add "Quick build" mode, enabled through option `-Ob`, for quicker native image builds.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public static boolean parseOnce() {
9393
@Option(help = "Name of the main entry point method. Optional if --shared is used.")//
9494
public static final HostedOptionKey<String> Method = new HostedOptionKey<>("main");
9595

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

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.driver;
26+
27+
import java.io.File;
28+
import java.nio.file.Paths;
29+
import java.util.regex.Pattern;
30+
31+
import org.graalvm.compiler.options.OptionType;
32+
33+
import com.oracle.svm.core.option.OptionOrigin;
34+
import com.oracle.svm.core.option.OptionUtils;
35+
import com.oracle.svm.driver.NativeImage.ArgumentQueue;
36+
37+
class CmdLineOptionHandler extends NativeImage.OptionHandler<NativeImage> {
38+
39+
private static final String helpText = NativeImage.getResource("/Help.txt");
40+
private static final String helpExtraText = NativeImage.getResource("/HelpExtra.txt");
41+
42+
/* Defunct legacy options that we have to accept to maintain backward compatibility */
43+
private static final String verboseServerOption = "--verbose-server";
44+
private static final String serverOptionPrefix = "--server-";
45+
46+
private static final String javaRuntimeVersion = System.getProperty("java.runtime.version");
47+
48+
boolean useDebugAttach = false;
49+
50+
CmdLineOptionHandler(NativeImage nativeImage) {
51+
super(nativeImage);
52+
}
53+
54+
@Override
55+
boolean consume(ArgumentQueue args) {
56+
String headArg = args.peek();
57+
boolean consumed = consume(args, headArg);
58+
OptionOrigin origin = OptionOrigin.from(args.argumentOrigin);
59+
if (consumed && !origin.commandLineLike()) {
60+
String msg = String.format("Using '%s' provided by %s is only allowed on command line.", headArg, origin);
61+
throw NativeImage.showError(msg);
62+
}
63+
return consumed;
64+
}
65+
66+
private boolean consume(ArgumentQueue args, String headArg) {
67+
switch (headArg) {
68+
case "--help":
69+
args.poll();
70+
singleArgumentCheck(args, headArg);
71+
nativeImage.showMessage(helpText);
72+
nativeImage.showNewline();
73+
nativeImage.apiOptionHandler.printOptions(nativeImage::showMessage, false);
74+
nativeImage.showNewline();
75+
nativeImage.optionRegistry.showOptions(null, true, nativeImage::showMessage);
76+
nativeImage.showNewline();
77+
System.exit(0);
78+
return true;
79+
case "--version":
80+
args.poll();
81+
singleArgumentCheck(args, headArg);
82+
String message;
83+
if (NativeImage.IS_AOT) {
84+
message = System.getProperty("java.vm.version");
85+
} else {
86+
message = "native-image " + NativeImage.graalvmVersion + " " + NativeImage.graalvmConfig;
87+
}
88+
message += " (Java Version " + javaRuntimeVersion + ")";
89+
nativeImage.showMessage(message);
90+
System.exit(0);
91+
return true;
92+
case "--help-extra":
93+
args.poll();
94+
singleArgumentCheck(args, headArg);
95+
nativeImage.showMessage(helpExtraText);
96+
nativeImage.apiOptionHandler.printOptions(nativeImage::showMessage, true);
97+
nativeImage.showNewline();
98+
nativeImage.optionRegistry.showOptions(OptionUtils.MacroOptionKind.Macro, true, nativeImage::showMessage);
99+
nativeImage.showNewline();
100+
System.exit(0);
101+
return true;
102+
case "--configurations-path":
103+
args.poll();
104+
String configPath = args.poll();
105+
if (configPath == null) {
106+
NativeImage.showError(headArg + " requires a " + File.pathSeparator + " separated list of directories");
107+
}
108+
for (String configDir : configPath.split(File.pathSeparator)) {
109+
nativeImage.addMacroOptionRoot(nativeImage.canonicalize(Paths.get(configDir)));
110+
}
111+
return true;
112+
case "--exclude-config":
113+
args.poll();
114+
String excludeJar = args.poll();
115+
if (excludeJar == null) {
116+
NativeImage.showError(headArg + " requires two arguments: a jar regular expression and a resource regular expression");
117+
}
118+
String excludeConfig = args.poll();
119+
if (excludeConfig == null) {
120+
NativeImage.showError(headArg + " requires resource regular expression");
121+
}
122+
nativeImage.addExcludeConfig(Pattern.compile(excludeJar), Pattern.compile(excludeConfig));
123+
return true;
124+
case DefaultOptionHandler.verboseOption:
125+
args.poll();
126+
nativeImage.setVerbose(true);
127+
return true;
128+
case "--dry-run":
129+
args.poll();
130+
nativeImage.setDryRun(true);
131+
return true;
132+
case "--expert-options":
133+
args.poll();
134+
nativeImage.setPrintFlagsOptionQuery(OptionType.User.name());
135+
return true;
136+
case "--expert-options-all":
137+
args.poll();
138+
nativeImage.setPrintFlagsOptionQuery("");
139+
return true;
140+
case "--expert-options-detail":
141+
args.poll();
142+
String optionNames = args.poll();
143+
nativeImage.setPrintFlagsWithExtraHelpOptionQuery(optionNames);
144+
return true;
145+
case verboseServerOption:
146+
args.poll();
147+
NativeImage.showWarning("Ignoring server-mode native-image argument " + headArg + ".");
148+
return true;
149+
}
150+
151+
String debugAttach = "--debug-attach";
152+
if (headArg.startsWith(debugAttach)) {
153+
if (useDebugAttach) {
154+
throw NativeImage.showError("The " + debugAttach + " option can only be used once.");
155+
}
156+
useDebugAttach = true;
157+
String debugAttachArg = args.poll();
158+
String addressSuffix = debugAttachArg.substring(debugAttach.length());
159+
String address = addressSuffix.isEmpty() ? "8000" : addressSuffix.substring(1);
160+
/* Using agentlib to allow interoperability with other agents */
161+
nativeImage.addImageBuilderJavaArgs("-agentlib:jdwp=transport=dt_socket,server=y,address=" + address + ",suspend=y");
162+
/* Disable watchdog mechanism */
163+
nativeImage.addPlainImageBuilderArg(nativeImage.oHDeadlockWatchdogInterval + "0");
164+
return true;
165+
}
166+
167+
if (headArg.startsWith(serverOptionPrefix)) {
168+
args.poll();
169+
NativeImage.showWarning("Ignoring server-mode native-image argument " + headArg + ".");
170+
String serverOptionCommand = headArg.substring(serverOptionPrefix.length());
171+
if (!serverOptionCommand.startsWith("session=")) {
172+
/*
173+
* All but the --server-session=... option used to exit(0). We want to simulate that
174+
* behaviour for proper backward compatibility.
175+
*/
176+
System.exit(0);
177+
}
178+
return true;
179+
}
180+
181+
return false;
182+
}
183+
184+
private static void singleArgumentCheck(ArgumentQueue args, String arg) {
185+
if (!args.isEmpty()) {
186+
NativeImage.showError("Option " + arg + " cannot be combined with other options.");
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)