@@ -1091,7 +1091,7 @@ private int completeImageBuild() {
1091
1091
addTargetArguments ();
1092
1092
1093
1093
String defaultLibC = OS .getCurrent () == OS .LINUX ? "glibc" : null ;
1094
- targetLibC = getHostedOptionFinalArgument (imageBuilderArgs , oHUseLibC ).map (ArgumentEntry ::value ).orElse (System .getProperty ("substratevm.HostLibC" , defaultLibC ));
1094
+ targetLibC = getHostedOptionArgument (imageBuilderArgs , oHUseLibC ).map (ArgumentEntry ::value ).orElse (System .getProperty ("substratevm.HostLibC" , defaultLibC ));
1095
1095
1096
1096
String clibrariesBuilderArg = config .getBuilderCLibrariesPaths ().stream ()
1097
1097
.flatMap (this ::resolveTargetSpecificPaths )
@@ -1166,7 +1166,7 @@ private int completeImageBuild() {
1166
1166
1167
1167
imageBuilderJavaArgs .addAll (getAgentArguments ());
1168
1168
1169
- mainClass = getHostedOptionFinalArgumentValue (imageBuilderArgs , oHClass );
1169
+ mainClass = getHostedOptionArgumentValue (imageBuilderArgs , oHClass );
1170
1170
buildExecutable = imageBuilderArgs .stream ().noneMatch (arg -> arg .startsWith (oHEnableSharedLibraryFlagPrefix ));
1171
1171
staticExecutable = imageBuilderArgs .stream ().anyMatch (arg -> arg .contains (oHEnableStaticExecutable ));
1172
1172
boolean listModules = imageBuilderArgs .stream ().anyMatch (arg -> arg .contains (oH + "+" + "ListModules" ));
@@ -1188,8 +1188,8 @@ private int completeImageBuild() {
1188
1188
1189
1189
if (!jarOptionMode ) {
1190
1190
/* Main-class from customImageBuilderArgs counts as explicitMainClass */
1191
- boolean explicitMainClass = getHostedOptionFinalArgumentValue (imageBuilderArgs , oHClass ) != null ;
1192
- mainClassModule = getHostedOptionFinalArgumentValue (imageBuilderArgs , oHModule );
1191
+ boolean explicitMainClass = getHostedOptionArgumentValue (imageBuilderArgs , oHClass ) != null ;
1192
+ mainClassModule = getHostedOptionArgumentValue (imageBuilderArgs , oHModule );
1193
1193
1194
1194
boolean hasMainClassModule = mainClassModule != null && !mainClassModule .isEmpty ();
1195
1195
boolean hasMainClass = mainClass != null && !mainClass .isEmpty ();
@@ -1207,11 +1207,11 @@ private int completeImageBuild() {
1207
1207
1208
1208
if (extraImageArgs .isEmpty ()) {
1209
1209
/* No explicit image name, define image name by other means */
1210
- if (getHostedOptionFinalArgumentValue (imageBuilderArgs , oHName ) == null ) {
1210
+ if (getHostedOptionArgumentValue (imageBuilderArgs , oHName ) == null ) {
1211
1211
/* Also no explicit image name given as customImageBuilderArgs */
1212
1212
if (explicitMainClass ) {
1213
1213
imageBuilderArgs .add (oH (SubstrateOptions .Name , "main-class lower case as image name" ) + mainClass .toLowerCase ());
1214
- } else if (getHostedOptionFinalArgumentValue (imageBuilderArgs , oHName ) == null ) {
1214
+ } else if (getHostedOptionArgumentValue (imageBuilderArgs , oHName ) == null ) {
1215
1215
if (hasMainClassModule ) {
1216
1216
imageBuilderArgs .add (oH (SubstrateOptions .Name , "image-name from module-name" ) + mainClassModule .toLowerCase ());
1217
1217
} else if (!listModules ) {
@@ -1236,9 +1236,9 @@ private int completeImageBuild() {
1236
1236
}
1237
1237
}
1238
1238
1239
- ArgumentEntry imageNameEntry = getHostedOptionFinalArgument (imageBuilderArgs , oHName ).orElseThrow ();
1239
+ ArgumentEntry imageNameEntry = getHostedOptionArgument (imageBuilderArgs , oHName ).orElseThrow ();
1240
1240
imageName = imageNameEntry .value ;
1241
- ArgumentEntry imagePathEntry = getHostedOptionFinalArgument (imageBuilderArgs , oHPath ).orElseThrow ();
1241
+ ArgumentEntry imagePathEntry = getHostedOptionArgument (imageBuilderArgs , oHPath ).orElseThrow ();
1242
1242
imagePath = Path .of (imagePathEntry .value );
1243
1243
Path imageNamePath = Path .of (imageName );
1244
1244
Path imageNamePathParent = imageNamePath .getParent ();
@@ -1307,7 +1307,7 @@ private int completeImageBuild() {
1307
1307
imageProvidedJars .forEach (this ::processClasspathNativeImageMetaInf );
1308
1308
1309
1309
if (!config .buildFallbackImage ()) {
1310
- Optional <ArgumentEntry > fallbackThresholdEntry = getHostedOptionFinalArgument (imageBuilderArgs , oHFallbackThreshold );
1310
+ Optional <ArgumentEntry > fallbackThresholdEntry = getHostedOptionArgument (imageBuilderArgs , oHFallbackThreshold );
1311
1311
if (fallbackThresholdEntry .isPresent () && fallbackThresholdEntry .get ().value .equals ("" + SubstrateOptions .ForceFallback )) {
1312
1312
/* Bypass regular build and proceed with fallback image building */
1313
1313
return ExitStatus .FALLBACK_IMAGE .getValue ();
@@ -1344,11 +1344,11 @@ private static String getLocationAgnosticArgPrefix(String argPrefix) {
1344
1344
return "^" + argPrefix .substring (0 , argPrefix .length () - 1 ) + "(@[^=]*)?=" ;
1345
1345
}
1346
1346
1347
- private static String getHostedOptionFinalArgumentValue (List <String > args , String argPrefix ) {
1348
- return getHostedOptionFinalArgument (args , argPrefix ).map (entry -> entry .value ).orElse (null );
1347
+ private static String getHostedOptionArgumentValue (List <String > args , String argPrefix ) {
1348
+ return getHostedOptionArgument (args , argPrefix ).map (entry -> entry .value ).orElse (null );
1349
1349
}
1350
1350
1351
- private static Optional <ArgumentEntry > getHostedOptionFinalArgument (List <String > args , String argPrefix ) {
1351
+ private static Optional <ArgumentEntry > getHostedOptionArgument (List <String > args , String argPrefix ) {
1352
1352
List <ArgumentEntry > values = getHostedOptionArgumentValues (args , argPrefix );
1353
1353
return values .isEmpty () ? Optional .empty () : Optional .of (values .get (values .size () - 1 ));
1354
1354
}
@@ -1371,7 +1371,7 @@ private static List<ArgumentEntry> getHostedOptionArgumentValues(List<String> ar
1371
1371
private record ArgumentEntry (int index , String value ) {
1372
1372
}
1373
1373
1374
- private static Boolean getHostedOptionFinalBooleanArgumentValue (List <String > args , OptionKey <Boolean > option ) {
1374
+ private static Boolean getHostedOptionBooleanArgumentValue (List <String > args , OptionKey <Boolean > option ) {
1375
1375
String locationAgnosticBooleanPattern = "^" + oH + "[+-]" + option .getName () + "(@[^=]*)?$" ;
1376
1376
Pattern pattern = Pattern .compile (locationAgnosticBooleanPattern );
1377
1377
Boolean result = null ;
@@ -1442,7 +1442,7 @@ private void addTargetArguments() {
1442
1442
* process (see comments for NativeImageGenerator.getTargetPlatform), we are parsing the
1443
1443
* --target argument here, and generating required internal arguments.
1444
1444
*/
1445
- targetPlatform = getHostedOptionFinalArgumentValue (imageBuilderArgs , oHTargetPlatform );
1445
+ targetPlatform = getHostedOptionArgumentValue (imageBuilderArgs , oHTargetPlatform );
1446
1446
if (targetPlatform == null ) {
1447
1447
return ;
1448
1448
}
@@ -2007,11 +2007,36 @@ List<String> apply(boolean strict) {
2007
2007
}
2008
2008
2009
2009
void addPlainImageBuilderArg (String plainArg , String origin ) {
2010
- addPlainImageBuilderArg (injectHostedOptionOrigin (plainArg , origin ));
2010
+ addPlainImageBuilderArg (plainArg , origin , true );
2011
+ }
2012
+
2013
+ void addPlainImageBuilderArg (String plainArg , String origin , boolean override ) {
2014
+ addPlainImageBuilderArg (injectHostedOptionOrigin (plainArg , origin ), override );
2011
2015
}
2012
2016
2013
2017
void addPlainImageBuilderArg (String plainArg ) {
2018
+ addPlainImageBuilderArg (plainArg , true );
2019
+ }
2020
+
2021
+ void addPlainImageBuilderArg (String plainArg , boolean override ) {
2014
2022
assert plainArg .startsWith (NativeImage .oH ) || plainArg .startsWith (NativeImage .oR );
2023
+ if (!override ) {
2024
+ int posValueSeparator = plainArg .indexOf ('=' );
2025
+ if (posValueSeparator > 0 ) {
2026
+ String argPrefix = plainArg .substring (0 , posValueSeparator );
2027
+ int posOriginSeparator = plainArg .indexOf ('@' );
2028
+ if (posOriginSeparator > 0 ) {
2029
+ argPrefix = argPrefix .substring (0 , posOriginSeparator );
2030
+ }
2031
+ String existingValue = getHostedOptionArgumentValue (imageBuilderArgs , argPrefix + '=' );
2032
+ if (existingValue != null ) {
2033
+ /* Respect the existing value. Do not append overriding value. */
2034
+ return ;
2035
+ }
2036
+ } else {
2037
+ VMError .shouldNotReachHere ("override=false currently only works for non-boolean options" );
2038
+ }
2039
+ }
2015
2040
imageBuilderArgs .add (plainArg );
2016
2041
}
2017
2042
@@ -2344,7 +2369,7 @@ private static boolean logRedirectedToFile() {
2344
2369
2345
2370
private boolean configureBuildOutput () {
2346
2371
boolean useColorfulOutput = false ;
2347
- String colorValue = getHostedOptionFinalArgumentValue (imageBuilderArgs , oHColor );
2372
+ String colorValue = getHostedOptionArgumentValue (imageBuilderArgs , oHColor );
2348
2373
if (colorValue != null ) { // use value set by user
2349
2374
if ("always" .equals (colorValue )) {
2350
2375
useColorfulOutput = true ;
@@ -2353,18 +2378,18 @@ private boolean configureBuildOutput() {
2353
2378
addPlainImageBuilderArg (oHColor + (useColorfulOutput ? "always" : "never" ), OptionOrigin .originDriver );
2354
2379
}
2355
2380
} else {
2356
- Boolean buildOutputColorfulValue = getHostedOptionFinalBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputColorful );
2381
+ Boolean buildOutputColorfulValue = getHostedOptionBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputColorful );
2357
2382
if (buildOutputColorfulValue != null ) {
2358
2383
useColorfulOutput = buildOutputColorfulValue ; // use value set by user
2359
2384
} else if (hasColorSupport ()) {
2360
2385
useColorfulOutput = true ;
2361
2386
addPlainImageBuilderArg (oHColor + "always" , OptionOrigin .originDriver );
2362
2387
}
2363
2388
}
2364
- if (getHostedOptionFinalBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputProgress ) == null && hasProgressSupport (imageBuilderArgs )) {
2389
+ if (getHostedOptionBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputProgress ) == null && hasProgressSupport (imageBuilderArgs )) {
2365
2390
addPlainImageBuilderArg (oHEnableBuildOutputProgress );
2366
2391
}
2367
- if (getHostedOptionFinalBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputLinks ) == null && (colorValue == null || "auto" .equals (colorValue )) && useColorfulOutput ) {
2392
+ if (getHostedOptionBooleanArgumentValue (imageBuilderArgs , SubstrateOptions .BuildOutputLinks ) == null && (colorValue == null || "auto" .equals (colorValue )) && useColorfulOutput ) {
2368
2393
addPlainImageBuilderArg (oHEnableBuildOutputLinks );
2369
2394
}
2370
2395
return useColorfulOutput ;
0 commit comments