Skip to content

Commit cd08f59

Browse files
committed
[GR-43070] Track warnings in Native Image build and list them (again) at the very end.
PullRequest: graal/21974
2 parents 6c9f79d + 6a75f11 commit cd08f59

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,4 +1711,19 @@ private static void validateEnableFallbackCompilation(HostedOptionKey<Boolean> o
17111711
public static boolean canEnableFallbackCompilation() {
17121712
return !EnableFallbackCompilation.getValue() && !useEconomyCompilerConfig();
17131713
}
1714+
1715+
@Option(help = "Passes the numbers of warnings that occurred in the driver phase to the builder.", type = OptionType.Debug, stability = OptionStability.STABLE) //
1716+
public static final HostedOptionKey<Integer> DriverWarningsCount = new HostedOptionKey<>(0);
1717+
1718+
@APIOption(name = "-Werror", defaultValue = "all")//
1719+
@Option(help = "Treat warnings as errors and terminate build.")//
1720+
public static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> TreatWarningsAsError = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build(), key -> {
1721+
key.getValue().getValuesWithOrigins().forEach(option -> {
1722+
if (!option.origin().commandLineLike()) {
1723+
throw UserError.abort("Option '%s' provided by %s can only be used on the command line.",
1724+
SubstrateOptionsParser.commandArgument(key, option.value()), option.origin());
1725+
}
1726+
});
1727+
});
1728+
17141729
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,8 @@ private int completeImageBuild() {
14921492
// allow native access for all modules on the image builder module path
14931493
var enableNativeAccessModules = getModulesFromPath(imageBuilderModulePath).keySet();
14941494
imageBuilderJavaArgs.add("--enable-native-access=" + String.join(",", enableNativeAccessModules));
1495+
// pass the number of warnings to the builder process
1496+
imageBuilderArgs.add(oH(SubstrateOptions.DriverWarningsCount) + LogUtils.getWarningsCount());
14951497

14961498
boolean useColorfulOutput = configureBuildOutput();
14971499

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
import java.util.stream.Stream;
5555

5656
import com.oracle.svm.core.RuntimeAssertionsSupport;
57+
import com.oracle.svm.core.util.UserError;
58+
import com.oracle.svm.util.LogUtils;
5759
import org.graalvm.nativeimage.ImageSingletons;
5860
import org.graalvm.nativeimage.hosted.Feature;
5961
import org.graalvm.nativeimage.impl.ImageSingletonsSupport;
@@ -795,7 +797,9 @@ public void printEpilog(Optional<String> optionalImageName, Optional<NativeImage
795797
l().a(outcomePrefix(buildOutcome)).a(" generating '").bold().a(imageName).reset().a("' ")
796798
.a(buildOutcome.successful() ? "in" : "after").a(" ").a(timeStats).a(".").println();
797799

800+
printWarningsCount();
798801
printErrorMessage(optionalUnhandledThrowable, parsedHostedOptions);
802+
checkTreatWarningsAsError();
799803
}
800804

801805
private static String outcomePrefix(NativeImageGeneratorRunner.BuildOutcome buildOutcome) {
@@ -806,6 +810,46 @@ private static String outcomePrefix(NativeImageGeneratorRunner.BuildOutcome buil
806810
};
807811
}
808812

813+
private void printWarningsCount() {
814+
int warningsCount = LogUtils.getWarningsCount() + SubstrateOptions.DriverWarningsCount.getValue();
815+
if (warningsCount == 0) {
816+
return;
817+
}
818+
819+
l().println();
820+
l().yellowBold().a("The build process encountered ").a(warningsCount).a(warningsCount == 1 ? " warning." : " warnings.").reset().println();
821+
l().println();
822+
}
823+
824+
private void checkTreatWarningsAsError() {
825+
if (SubstrateOptions.TreatWarningsAsError.getValue().contains("all")) {
826+
deleteBuiltArtifacts();
827+
throw UserError.abort("Build failed: Warnings are treated as errors because the -Werror flag is set.");
828+
}
829+
}
830+
831+
/**
832+
* Delete built artifacts. This is done e.g. in the -Werror case to ensure we don't "fail on
833+
* error" but still have built - but potentially broken - artifacts created.
834+
*/
835+
private void deleteBuiltArtifacts() {
836+
BuildArtifacts.singleton().forEach((artifactType, paths) -> {
837+
if (artifactType != ArtifactType.BUILD_INFO) {
838+
for (Path path : paths) {
839+
try {
840+
if (path.startsWith(SubstrateOptions.getImagePath())) {
841+
java.nio.file.Files.delete(path);
842+
} else {
843+
LogUtils.warning("Cleaning up due to -Werror failed: Cannot delete artifacts not in " + SubstrateOptions.getImagePath() + ". Invalid: " + path);
844+
}
845+
} catch (IOException ex) {
846+
LogUtils.warning("Cleaning up due to -Werror failed: cannot delete " + path + ": " + ex.getMessage());
847+
}
848+
}
849+
}
850+
});
851+
}
852+
809853
private void printErrorMessage(Optional<Throwable> optionalUnhandledThrowable, OptionValues parsedHostedOptions) {
810854
if (optionalUnhandledThrowable.isEmpty()) {
811855
return;

substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/LogUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929

3030
// Checkstyle: Allow raw info or warning printing - begin
3131
public class LogUtils {
32+
/**
33+
* Number of warnings seen during image build. Note this is limited to the current process, i.e.
34+
* there is a split between Driver and Builder.
35+
*/
36+
private static int warningsCount = 0;
37+
3238
/**
3339
* Print an info message.
3440
*/
@@ -66,6 +72,7 @@ public static void prefixInfo(String prefix, String format, Object... args) {
6672
*/
6773
public static void warning(String message) {
6874
System.out.println("Warning: " + message);
75+
warningsCount++;
6976
}
7077

7178
/**
@@ -87,4 +94,8 @@ public static void warning(String format, Object... args) {
8794
public static void warningDeprecatedEnvironmentVariable(String environmentVariableName) {
8895
warning("The " + environmentVariableName + " environment variable is deprecated and might be removed in a future release. Please refer to the GraalVM release notes.");
8996
}
97+
98+
public static int getWarningsCount() {
99+
return warningsCount;
100+
}
90101
}

0 commit comments

Comments
 (0)