main.spice
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2026 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | // Std imports | ||
| 4 | import "std/os/os"; | ||
| 5 | |||
| 6 | // Own imports | ||
| 7 | import "@/source-file"; | ||
| 8 | import "@/driver"; | ||
| 9 | import "@/global/global-resource-manager"; | ||
| 10 | import "@/util/system-util"; | ||
| 11 | import "@/util/compile-progress"; | ||
| 12 | |||
| 13 | /** | ||
| 14 | * Compile main source file. All files, that are included by the main source file will be resolved recursively. | ||
| 15 | * | ||
| 16 | * @param cliOptions Command line options | ||
| 17 | * @return Successful or not | ||
| 18 | */ | ||
| 19 | 763 | f<bool> compileProject(CliOptions& cliOptions) { | |
| 20 | // Instantiate GlobalResourceManager | ||
| 21 | 763 | GlobalResourceManager resourceManager = GlobalResourceManager(cliOptions); | |
| 22 | |||
| 23 | // Show the progress on the console. Enable it before the first source file is created, so that it is counted | ||
| 24 | 763 | if shouldShowCompileProgress(cliOptions) { | |
| 25 | ✗ | const bool runBackEnd = !cliOptions.lintOnly; // Lint-only mode does neither run the back end, nor link | |
| 26 | ✗ | const bool link = runBackEnd && cliOptions.outputContainer != OutputContainer::OBJECT_FILE; | |
| 27 | ✗ | const bool optimized = cliOptions.optLevel != OptLevel::O0; | |
| 28 | ✗ | const unsigned long jobCount = resourceManager.getCompileJobCount(); | |
| 29 | ✗ | resourceManager.compileProgress.enable(runBackEnd, link, optimized, cliOptions.useLTO, jobCount); | |
| 30 | ✗ | } | |
| 31 | |||
| 32 | // Create source file instance for main source file | ||
| 33 | 763 | SourceFile* mainSourceFile = resourceManager.createSourceFile(nil<SourceFile*>, String(MAIN_FILE_NAME), cliOptions.mainSourceFile, false); | |
| 34 | |||
| 35 | // Run compile pipeline for main source file. All dependent source files are triggered by their parents | ||
| 36 | 763 | mainSourceFile.runFrontEnd(); | |
| 37 | 763 | if resourceManager.abortCompilation { return true; } | |
| 38 | 763 | resourceManager.compileProgress.setPhase(COMPILE_PHASE_MIDDLE_END); | |
| 39 | 763 | mainSourceFile.runMiddleEnd(); | |
| 40 | 763 | if resourceManager.abortCompilation { return true; } | |
| 41 | |||
| 42 | // Lint-only mode stops here and reports findings without generating any code | ||
| 43 | 763 | if cliOptions.lintOnly { | |
| 44 | 3 | resourceManager.compileProgress.clear(); | |
| 45 | 3 | mainSourceFile.collectAndPrintLintFindings(); | |
| 46 | 3 | return true; | |
| 47 | } | ||
| 48 | |||
| 49 | // Compile additional C/C++ sources in the background, while the back end is running | ||
| 50 | 760 | if cliOptions.outputContainer != OutputContainer::OBJECT_FILE { | |
| 51 | 462 | resourceManager.linker.startAdditionalSourceCompilation(); | |
| 52 | 462 | } | |
| 53 | |||
| 54 | 760 | resourceManager.compileProgress.setPhase(COMPILE_PHASE_BACK_END); | |
| 55 | 760 | mainSourceFile.runBackEnd(); | |
| 56 | 760 | if resourceManager.abortCompilation { return true; } | |
| 57 | |||
| 58 | // Link the target executable (link object files to executable/library) | ||
| 59 | 760 | if cliOptions.outputContainer != OutputContainer::OBJECT_FILE { | |
| 60 | 462 | resourceManager.compileProgress.startLinking(); | |
| 61 | 462 | resourceManager.linker.prepare(); | |
| 62 | 462 | resourceManager.linker.run(); | |
| 63 | 462 | resourceManager.linker.cleanup(); | |
| 64 | 462 | resourceManager.compileProgress.finishLinking(); | |
| 65 | 462 | } | |
| 66 | |||
| 67 | // Remove the progress bar before printing the warnings | ||
| 68 | 760 | resourceManager.compileProgress.clear(); | |
| 69 | |||
| 70 | // Print compiler warnings | ||
| 71 | 760 | mainSourceFile.collectAndPrintWarnings(); | |
| 72 | |||
| 73 | 760 | return true; | |
| 74 | 763 | } | |
| 75 | |||
| 76 | /** | ||
| 77 | * Entry point to the Spice compiler | ||
| 78 | * | ||
| 79 | * @param argc Argument count | ||
| 80 | * @param argv Argument vector | ||
| 81 | * @return Return code | ||
| 82 | */ | ||
| 83 | 763 | f<int> main(int argc, string[] argv) { | |
| 84 | // Initialize command line parser | ||
| 85 | 763 | Driver driver; | |
| 86 | 763 | const int exitCode = driver.parse(argc, argv); | |
| 87 | 763 | if exitCode != EXIT_CODE_SUCCESS { | |
| 88 | ✗ | return exitCode; | |
| 89 | } | ||
| 90 | |||
| 91 | // Cancel here if we do not have to compile | ||
| 92 | 763 | if !driver.shouldCompile { | |
| 93 | ✗ | return EXIT_CODE_SUCCESS; | |
| 94 | } | ||
| 95 | |||
| 96 | 763 | driver.enrich(); // Prepare the cli options | |
| 97 | |||
| 98 | // Let the std TPDE bindings find the TPDE libraries, that release packages ship with the std | ||
| 99 | 763 | exportStdTPDEFlags(driver.cliOptions); | |
| 100 | |||
| 101 | // Kick off the compiling process | ||
| 102 | 763 | if !compileProject(driver.cliOptions) { | |
| 103 | ✗ | return EXIT_CODE_ERROR; | |
| 104 | } | ||
| 105 | |||
| 106 | // Execute | ||
| 107 | 763 | if driver.cliOptions.execute { | |
| 108 | ✗ | driver.runBinary(); | |
| 109 | ✗ | } | |
| 110 | |||
| 111 | 1526 | return EXIT_CODE_SUCCESS; | |
| 112 | 763 | } | |
| 113 |