use of com.oracle.svm.hosted.image.AbstractImage.NativeImageKind in project graal by oracle.
the class NativeImageGeneratorRunner method buildImage.
@SuppressWarnings("try")
private int buildImage(ImageClassLoader classLoader) {
if (!verifyValidJavaVersionAndPlatform()) {
return 1;
}
HostedOptionParser optionParser = classLoader.classLoaderSupport.getHostedOptionParser();
OptionValues parsedHostedOptions = classLoader.classLoaderSupport.getParsedHostedOptions();
String imageName = SubstrateOptions.Name.getValue(parsedHostedOptions);
TimerCollection timerCollection = new TimerCollection(imageName);
Timer totalTimer = timerCollection.get(TimerCollection.Registry.TOTAL);
if (NativeImageOptions.ListCPUFeatures.getValue(parsedHostedOptions)) {
printCPUFeatures(classLoader.platform);
return 0;
}
ForkJoinPool analysisExecutor = null;
ForkJoinPool compilationExecutor = null;
ProgressReporter reporter = new ProgressReporter(parsedHostedOptions);
boolean wasSuccessfulBuild = false;
try (StopTimer ignored = totalTimer.start()) {
Timer classlistTimer = timerCollection.get(TimerCollection.Registry.CLASSLIST);
try (StopTimer ignored1 = classlistTimer.start()) {
classLoader.initAllClasses();
}
DebugContext debug = new DebugContext.Builder(parsedHostedOptions, new GraalDebugHandlersFactory(GraalAccess.getOriginalSnippetReflection())).build();
if (imageName.length() == 0) {
throw UserError.abort("No output file name specified. Use '%s'.", SubstrateOptionsParser.commandArgument(SubstrateOptions.Name, "<output-file>"));
}
try {
// print the time here to avoid interactions with flags processing
classlistTimer.print();
Map<Method, CEntryPointData> entryPoints = new HashMap<>();
Pair<Method, CEntryPointData> mainEntryPointData = Pair.empty();
JavaMainSupport javaMainSupport = null;
NativeImageKind imageKind;
boolean isStaticExecutable = SubstrateOptions.StaticExecutable.getValue(parsedHostedOptions);
boolean isSharedLibrary = SubstrateOptions.SharedLibrary.getValue(parsedHostedOptions);
if (isStaticExecutable && isSharedLibrary) {
throw UserError.abort("Cannot pass both option: %s and %s", SubstrateOptionsParser.commandArgument(SubstrateOptions.SharedLibrary, "+"), SubstrateOptionsParser.commandArgument(SubstrateOptions.StaticExecutable, "+"));
} else if (isSharedLibrary) {
imageKind = NativeImageKind.SHARED_LIBRARY;
} else if (isStaticExecutable) {
imageKind = NativeImageKind.STATIC_EXECUTABLE;
} else {
imageKind = NativeImageKind.EXECUTABLE;
}
String className = SubstrateOptions.Class.getValue(parsedHostedOptions);
String moduleName = SubstrateOptions.Module.getValue(parsedHostedOptions);
if (imageKind.isExecutable && moduleName.isEmpty() && className.isEmpty()) {
throw UserError.abort("Must specify main entry point class when building %s native image. Use '%s'.", imageKind, SubstrateOptionsParser.commandArgument(SubstrateOptions.Class, "<fully-qualified-class-name>"));
}
reporter.printStart(imageName, imageKind);
if (!className.isEmpty() || !moduleName.isEmpty()) {
Method mainEntryPoint;
Class<?> mainClass;
try {
Object mainModule = null;
if (!moduleName.isEmpty()) {
mainModule = classLoader.findModule(moduleName).orElseThrow(() -> UserError.abort("Module " + moduleName + " for mainclass not found."));
}
if (className.isEmpty()) {
className = classLoader.getMainClassFromModule(mainModule).orElseThrow(() -> UserError.abort("module %s does not have a ModuleMainClass attribute, use -m <module>/<main-class>", moduleName));
}
mainClass = classLoader.forName(className, mainModule);
if (mainClass == null) {
throw UserError.abort(classLoader.getMainClassNotFoundErrorMessage(className));
}
} catch (ClassNotFoundException ex) {
throw UserError.abort(classLoader.getMainClassNotFoundErrorMessage(className));
}
String mainEntryPointName = SubstrateOptions.Method.getValue(parsedHostedOptions);
if (mainEntryPointName.isEmpty()) {
throw UserError.abort("Must specify main entry point method when building %s native image. Use '%s'.", imageKind, SubstrateOptionsParser.commandArgument(SubstrateOptions.Method, "<method-name>"));
}
try {
/*
* First look for an main method with the C-level signature for arguments.
*/
mainEntryPoint = mainClass.getDeclaredMethod(mainEntryPointName, int.class, CCharPointerPointer.class);
} catch (NoSuchMethodException ignored2) {
Method javaMainMethod;
try {
/*
* If no C-level main method was found, look for a Java-level main
* method and use our wrapper to invoke it.
*/
javaMainMethod = ReflectionUtil.lookupMethod(mainClass, mainEntryPointName, String[].class);
} catch (ReflectionUtilError ex) {
throw UserError.abort(ex.getCause(), "Method '%s.%s' is declared as the main entry point but it can not be found. " + "Make sure that class '%s' is on the classpath and that method '%s(String[])' exists in that class.", mainClass.getName(), mainEntryPointName, mainClass.getName(), mainEntryPointName);
}
if (javaMainMethod.getReturnType() != void.class) {
throw UserError.abort("Java main method '%s.%s(String[])' does not have the return type 'void'.", mainClass.getName(), mainEntryPointName);
}
final int mainMethodModifiers = javaMainMethod.getModifiers();
if (!Modifier.isStatic(mainMethodModifiers)) {
throw UserError.abort("Java main method '%s.%s(String[])' is not static.", mainClass.getName(), mainEntryPointName);
}
if (!Modifier.isPublic(mainMethodModifiers)) {
throw UserError.abort("Java main method '%s.%s(String[])' is not public.", mainClass.getName(), mainEntryPointName);
}
javaMainSupport = new JavaMainSupport(javaMainMethod);
mainEntryPoint = JavaMainWrapper.class.getDeclaredMethod("run", int.class, CCharPointerPointer.class);
}
CEntryPoint annotation = mainEntryPoint.getAnnotation(CEntryPoint.class);
if (annotation == null) {
throw UserError.abort("Entry point must have the '@%s' annotation", CEntryPoint.class.getSimpleName());
}
Class<?>[] pt = mainEntryPoint.getParameterTypes();
if (pt.length != 2 || pt[0] != int.class || pt[1] != CCharPointerPointer.class || mainEntryPoint.getReturnType() != int.class) {
throw UserError.abort("Main entry point must have signature 'int main(int argc, CCharPointerPointer argv)'.");
}
mainEntryPointData = Pair.create(mainEntryPoint, CEntryPointData.create(mainEntryPoint, imageKind.mainEntryPointName));
}
int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(parsedHostedOptions);
analysisExecutor = NativeImagePointsToAnalysis.createExecutor(debug, NativeImageOptions.getMaximumNumberOfAnalysisThreads(parsedHostedOptions));
compilationExecutor = NativeImagePointsToAnalysis.createExecutor(debug, maxConcurrentThreads);
generator = new NativeImageGenerator(classLoader, optionParser, mainEntryPointData, reporter);
generator.run(entryPoints, javaMainSupport, imageName, imageKind, SubstitutionProcessor.IDENTITY, compilationExecutor, analysisExecutor, optionParser.getRuntimeOptionNames(), timerCollection);
wasSuccessfulBuild = true;
} finally {
if (!wasSuccessfulBuild) {
reporter.printUnsuccessfulInitializeEnd();
}
}
} catch (InterruptImageBuilding e) {
if (analysisExecutor != null) {
analysisExecutor.shutdownNow();
}
if (compilationExecutor != null) {
compilationExecutor.shutdownNow();
}
throw e;
} catch (FallbackFeature.FallbackImageRequest e) {
if (FallbackExecutor.class.getName().equals(SubstrateOptions.Class.getValue())) {
NativeImageGeneratorRunner.reportFatalError(e, "FallbackImageRequest while building fallback image.");
return 1;
}
reportUserException(e, parsedHostedOptions, NativeImageGeneratorRunner::warn);
return 2;
} catch (ParsingError e) {
NativeImageGeneratorRunner.reportFatalError(e);
return 1;
} catch (UserException | AnalysisError e) {
reportUserError(e, parsedHostedOptions);
return 1;
} catch (ParallelExecutionException pee) {
boolean hasUserError = false;
for (Throwable exception : pee.getExceptions()) {
if (exception instanceof UserException) {
reportUserError(exception, parsedHostedOptions);
hasUserError = true;
} else if (exception instanceof AnalysisError && !(exception instanceof ParsingError)) {
reportUserError(exception, parsedHostedOptions);
hasUserError = true;
}
}
if (hasUserError) {
return 1;
}
if (pee.getExceptions().size() > 1) {
System.err.println(pee.getExceptions().size() + " fatal errors detected:");
}
for (Throwable exception : pee.getExceptions()) {
NativeImageGeneratorRunner.reportFatalError(exception);
}
return 1;
} catch (Throwable e) {
NativeImageGeneratorRunner.reportFatalError(e);
return 1;
} finally {
totalTimer.print();
if (imageName != null && generator != null) {
reporter.printEpilog(imageName, generator, wasSuccessfulBuild, parsedHostedOptions);
}
NativeImageGenerator.clearSystemPropertiesForImage();
ImageSingletonsSupportImpl.HostedManagement.clear();
}
return 0;
}
Aggregations