Skip to content

Commit 154c7b6

Browse files
committed
Allow support for --bundle-update
1 parent bdccb03 commit 154c7b6

File tree

3 files changed

+55
-32
lines changed

3 files changed

+55
-32
lines changed

substratevm/src/com.oracle.svm.driver/resources/HelpExtra.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Non-standard options help:
2626
an image will be built from the given bundle with the exact same
2727
arguments and files that have been passed to native-image originally to
2828
create the bundle.
29+
--bundle-update bundle-file
30+
same as --bundle-apply but given extra arguments add to the arguments
31+
provided by the bundle. After image build the additional arguments
32+
are incorporated into an updated bundle file.
2933

3034
-V<key>=<value> provide values for placeholders in native-image.properties files
3135

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/BundleSupport.java

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.nio.file.StandardCopyOption;
3636
import java.util.ArrayList;
3737
import java.util.Arrays;
38+
import java.util.Collection;
3839
import java.util.Collections;
3940
import java.util.HashMap;
4041
import java.util.List;
@@ -61,16 +62,19 @@ final class BundleSupport {
6162
static final String BUNDLE_OPTION = "--bundle";
6263

6364
enum BundleStatus {
64-
prepare(false, false),
65-
create(false, false),
66-
apply(true, true);
65+
prepare(false, false, true),
66+
create(false, false, true),
67+
update(false, true, true),
68+
apply(true, true, false);
6769

6870
final boolean hidden;
6971
final boolean loadBundle;
72+
final boolean writeBundle;
7073

71-
BundleStatus(boolean hidden, boolean loadBundle) {
74+
BundleStatus(boolean hidden, boolean loadBundle, boolean writeBundle) {
7275
this.hidden = hidden;
7376
this.loadBundle = loadBundle;
77+
this.writeBundle = writeBundle;
7478
}
7579

7680
boolean show() {
@@ -95,6 +99,7 @@ boolean show() {
9599
Map<Path, Path> pathSubstitutions = new HashMap<>();
96100

97101
private final List<String> buildArgs;
102+
private Collection<String> updatedBuildArgs;
98103

99104
private static final String bundleTempDirPrefix = "bundleRoot-";
100105
private static final String bundleFileExtension = ".nib";
@@ -130,26 +135,9 @@ static BundleSupport create(NativeImage nativeImage, String bundleArg, NativeIma
130135
bundleSupport = new BundleSupport(nativeImage, bundleStatus, bundleFilename);
131136
List<String> buildArgs = bundleSupport.getBuildArgs();
132137
for (int i = buildArgs.size() - 1; i >= 0; i--) {
133-
String buildArg = buildArgs.get(i);
134-
if (buildArg.startsWith(BUNDLE_OPTION)) {
135-
assert !BundleStatus.valueOf(buildArg.substring(BUNDLE_OPTION.length() + 1)).loadBundle;
136-
continue;
137-
}
138-
if (buildArg.startsWith(nativeImage.oHPath)) {
139-
continue;
140-
}
141-
if (buildArg.equals(DefaultOptionHandler.verboseOption)) {
142-
continue;
143-
}
144-
if (buildArg.startsWith("-Dllvm.bin.dir=")) {
145-
Optional<String> existing = nativeImage.config.getBuildArgs().stream().filter(arg -> arg.startsWith("-Dllvm.bin.dir=")).findFirst();
146-
if (existing.isPresent() && !existing.get().equals(buildArg)) {
147-
throw NativeImage.showError("Bundle native-image argument '" + buildArg + "' conflicts with existing '" + existing.get() + "'.");
148-
}
149-
continue;
150-
}
151-
args.push(buildArg);
138+
args.push(buildArgs.get(i));
152139
}
140+
bundleSupport.updatedBuildArgs = args.snapshot();
153141
} else {
154142
bundleSupport = new BundleSupport(nativeImage, bundleStatus);
155143
}
@@ -261,10 +249,6 @@ private BundleSupport(NativeImage nativeImage, BundleStatus status, String bundl
261249
}
262250
}
263251

264-
public boolean isBundleCreation() {
265-
return !status.loadBundle;
266-
}
267-
268252
public List<String> getBuildArgs() {
269253
return buildArgs;
270254
}
@@ -455,9 +439,7 @@ void complete() {
455439
}
456440

457441
try {
458-
if (isBundleCreation()) {
459-
writeBundle();
460-
}
442+
writeBundle();
461443
} finally {
462444
nativeImage.deleteAllFiles(rootDir);
463445
}
@@ -469,7 +451,19 @@ public void setBundleLocation(Path imagePath, String imageName) {
469451
}
470452

471453
void writeBundle() {
472-
assert isBundleCreation();
454+
if (!status.writeBundle) {
455+
return;
456+
}
457+
458+
String originalOutputDirName = outputDir.getFileName().toString() + originalDirExtension;
459+
Path originalOutputDir = rootDir.resolve(originalOutputDirName);
460+
if (Files.exists(originalOutputDir)) {
461+
nativeImage.deleteAllFiles(originalOutputDir);
462+
}
463+
Path metaInfDir = rootDir.resolve("META-INF");
464+
if (Files.exists(metaInfDir)) {
465+
nativeImage.deleteAllFiles(metaInfDir);
466+
}
473467

474468
Path pathCanonicalizationsFile = stageDir.resolve("path_canonicalizations.json");
475469
try (JsonWriter writer = new JsonWriter(pathCanonicalizationsFile)) {
@@ -488,8 +482,29 @@ void writeBundle() {
488482

489483
Path buildArgsFile = stageDir.resolve("build.json");
490484
try (JsonWriter writer = new JsonWriter(buildArgsFile)) {
485+
ArrayList<String> cleanBuildArgs = new ArrayList<>();
486+
for (String buildArg : updatedBuildArgs != null ? updatedBuildArgs : buildArgs) {
487+
if (buildArg.startsWith(BUNDLE_OPTION)) {
488+
assert !BundleStatus.valueOf(buildArg.substring(BUNDLE_OPTION.length() + 1)).loadBundle;
489+
continue;
490+
}
491+
if (buildArg.startsWith(nativeImage.oHPath)) {
492+
continue;
493+
}
494+
if (buildArg.equals(DefaultOptionHandler.verboseOption)) {
495+
continue;
496+
}
497+
if (buildArg.startsWith("-Dllvm.bin.dir=")) {
498+
Optional<String> existing = nativeImage.config.getBuildArgs().stream().filter(arg -> arg.startsWith("-Dllvm.bin.dir=")).findFirst();
499+
if (existing.isPresent() && !existing.get().equals(buildArg)) {
500+
throw NativeImage.showError("Bundle native-image argument '" + buildArg + "' conflicts with existing '" + existing.get() + "'.");
501+
}
502+
continue;
503+
}
504+
cleanBuildArgs.add(buildArg);
505+
}
491506
/* Printing as list with defined sort-order ensures useful diffs are possible */
492-
JsonPrinter.printCollection(writer, buildArgs, null, BundleSupport::printBuildArg);
507+
JsonPrinter.printCollection(writer, cleanBuildArgs, null, BundleSupport::printBuildArg);
493508
} catch (IOException e) {
494509
throw NativeImage.showError("Failed to write bundle-file " + pathSubstitutionsFile, e);
495510
}

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ public boolean isEmpty() {
176176
public int size() {
177177
return queue.size();
178178
}
179+
180+
public List<String> snapshot() {
181+
return new ArrayList<>(queue);
182+
}
179183
}
180184

181185
abstract static class OptionHandler<T extends NativeImage> {

0 commit comments

Comments
 (0)