Search in sources :

Example 1 with NativeImageKind

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;
}
Also used : NativeImageKind(com.oracle.svm.hosted.image.AbstractImage.NativeImageKind) OptionValues(org.graalvm.compiler.options.OptionValues) HashMap(java.util.HashMap) AnalysisError(com.oracle.graal.pointsto.util.AnalysisError) HostedOptionParser(com.oracle.svm.hosted.option.HostedOptionParser) CEntryPointData(com.oracle.svm.hosted.code.CEntryPointData) ParallelExecutionException(com.oracle.graal.pointsto.util.ParallelExecutionException) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) TimerCollection(com.oracle.graal.pointsto.util.TimerCollection) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding) UserException(com.oracle.svm.core.util.UserError.UserException) DebugContext(org.graalvm.compiler.debug.DebugContext) Method(java.lang.reflect.Method) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) JavaMainSupport(com.oracle.svm.core.JavaMainWrapper.JavaMainSupport) ParsingError(com.oracle.graal.pointsto.util.AnalysisError.ParsingError) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) Timer(com.oracle.graal.pointsto.util.Timer) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) ReflectionUtilError(com.oracle.svm.util.ReflectionUtil.ReflectionUtilError) CCharPointerPointer(org.graalvm.nativeimage.c.type.CCharPointerPointer) ForkJoinPool(java.util.concurrent.ForkJoinPool)

Aggregations

AnalysisError (com.oracle.graal.pointsto.util.AnalysisError)1 ParsingError (com.oracle.graal.pointsto.util.AnalysisError.ParsingError)1 ParallelExecutionException (com.oracle.graal.pointsto.util.ParallelExecutionException)1 Timer (com.oracle.graal.pointsto.util.Timer)1 StopTimer (com.oracle.graal.pointsto.util.Timer.StopTimer)1 TimerCollection (com.oracle.graal.pointsto.util.TimerCollection)1 JavaMainSupport (com.oracle.svm.core.JavaMainWrapper.JavaMainSupport)1 InterruptImageBuilding (com.oracle.svm.core.util.InterruptImageBuilding)1 UserException (com.oracle.svm.core.util.UserError.UserException)1 CEntryPointData (com.oracle.svm.hosted.code.CEntryPointData)1 NativeImageKind (com.oracle.svm.hosted.image.AbstractImage.NativeImageKind)1 HostedOptionParser (com.oracle.svm.hosted.option.HostedOptionParser)1 ReflectionUtilError (com.oracle.svm.util.ReflectionUtil.ReflectionUtilError)1 Method (java.lang.reflect.Method)1 HashMap (java.util.HashMap)1 ForkJoinPool (java.util.concurrent.ForkJoinPool)1 DebugContext (org.graalvm.compiler.debug.DebugContext)1 OptionValues (org.graalvm.compiler.options.OptionValues)1 GraalDebugHandlersFactory (org.graalvm.compiler.printer.GraalDebugHandlersFactory)1 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)1