diff --git a/util/build.c b/util/build.c index 96601da..cccbade 100644 --- a/util/build.c +++ b/util/build.c @@ -696,220 +696,6 @@ bool AddCompilerToPath() { return true; } -void BuildCrossCompiler() { - if (!CallSystem("whoami | grep root")) { - printf("Error: Build should not be run as root.\n"); - exit(0); - } - - { - printf("\n"); - printf("To build Essence, you need a cross compiler. This will be built for you automatically.\n"); - printf("- You need to be connected to the internet. ~100MB will be downloaded.\n"); - printf("- You need ~3GB of drive space available.\n"); - printf("- You need ~8GB of RAM available.\n"); - printf("- This should take ~20 minutes on a modern computer.\n"); - printf("- This does *not* require root permissions.\n"); - printf("- You must fully update your system before building.\n\n"); - - bool missingPackages = false; - bool missingLibraries = false; - - if (CallSystem("which g++ > /dev/null 2>&1")) { printf("Error: Missing GCC/G++.\n"); missingPackages = true; } - if (CallSystem("which make > /dev/null 2>&1")) { printf("Error: Missing GNU Make.\n"); missingPackages = true; } - if (CallSystem("which bison > /dev/null 2>&1")) { printf("Error: Missing GNU Bison.\n"); missingPackages = true; } - if (CallSystem("which flex > /dev/null 2>&1")) { printf("Error: Missing Flex.\n"); missingPackages = true; } - if (CallSystem("which curl > /dev/null 2>&1")) { printf("Error: Missing curl.\n"); missingPackages = true; } - if (CallSystem("which nasm > /dev/null 2>&1")) { printf("Error: Missing nasm.\n"); missingPackages = true; } - if (CallSystem("which ctags > /dev/null 2>&1")) { printf("Error: Missing ctags.\n"); missingPackages = true; } - if (CallSystem("which xz > /dev/null 2>&1")) { printf("Error: Missing xz.\n"); missingPackages = true; } - if (CallSystem("which gzip > /dev/null 2>&1")) { printf("Error: Missing gzip.\n"); missingPackages = true; } - if (CallSystem("which tar > /dev/null 2>&1")) { printf("Error: Missing tar.\n"); missingPackages = true; } - if (CallSystem("which grep > /dev/null 2>&1")) { printf("Error: Missing grep.\n"); missingPackages = true; } - if (CallSystem("which sed > /dev/null 2>&1")) { printf("Error: Missing sed.\n"); missingPackages = true; } - if (CallSystem("which awk > /dev/null 2>&1")) { printf("Error: Missing awk.\n"); missingPackages = true; } - -#ifdef __APPLE__ - if (CallSystem("gcc -L/opt/homebrew/lib -lmpc 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU MPC.\n"); missingLibraries = true; } - if (CallSystem("gcc -L/opt/homebrew/lib -lmpfr 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU MPFR.\n"); missingLibraries = true; } - if (CallSystem("gcc -L/opt/homebrew/lib -lgmp 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU GMP.\n"); missingLibraries = true; } -#else - if (CallSystem("gcc -lmpc 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU MPC.\n"); missingLibraries = true; } - if (CallSystem("gcc -lmpfr 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU MPFR.\n"); missingLibraries = true; } - if (CallSystem("gcc -lgmp 2>&1 | grep -i undefined > /dev/null")) { printf("Error: Missing GNU GMP.\n"); missingLibraries = true; } -#endif - - if (missingPackages || missingLibraries) { - if (missingLibraries) { - printf("Make sure you install the *development* versions of MPC, MPFR and GMP.\n" - "Depending on your package manager, you might have to suffix the package name with \"-dev\" or \"-devel\".\n" - "For example, on Ubuntu, you can run: \"apt-get install libgmp-dev libmpc-dev libmpfr.dev\".\n"); - } - - exit(0); - } - - char installationFolder[4096]; - char sysrootFolder[4096]; - - int processorCount = sysconf(_SC_NPROCESSORS_CONF); - if (processorCount < 1) processorCount = 1; - if (processorCount > 16) processorCount = 16; - - printf("Type 'yes' if you have updated your system.\n"); - if (interactiveMode && !GetYes()) { printf("The build has been canceled.\n"); exit(0); } - - { - getcwd(installationFolder, 4096); - strcat(installationFolder, "/cross"); - getcwd(sysrootFolder, 4096); - strcat(sysrootFolder, "/root"); - strcpy(compilerPath, installationFolder); - strcat(compilerPath, "/bin"); - printf("\nType 'yes' to install the compiler into '%s'.\n", installationFolder); - if (interactiveMode && !GetYes()) { printf("The build has been canceled.\n"); exit(0); } - } - - if (!AddCompilerToPath()) { - goto fail; - } - - { - FILE *f = fopen("bin/running_makefiles", "r"); - - if (f) { - fclose(f); - printf("\nThe build system has detected a build was started, but was not completed.\n"); - printf("Type 'yes' to attempt to resume this build.\n"); - - if (GetYes()) { - printf("Resuming build...\n"); - StartSpinner(); - goto runMakefiles; - } - } - } - - CallSystemF("echo \"Started build of cross compiler index %d, with GCC " GCC_VERSION " and Binutils " BINUTILS_VERSION ". Using %d processors.\" > bin/build_cross.log", - CROSS_COMPILER_INDEX, processorCount); - - CallSystem("rm -rf cross bin/build-binutils bin/build-gcc bin/gcc-" GCC_VERSION " bin/binutils-" BINUTILS_VERSION); - - { - CallSystem("echo Preparing C standard library headers... >> bin/build_cross.log"); - CallSystem("mkdir -p root/" SYSTEM_FOLDER_NAME " root/Applications/POSIX/include root/Applications/POSIX/lib root/Applications/POSIX/bin"); - CallSystem("ports/musl/build.sh " TARGET_NAME ">> bin/build_cross.log 2>&1"); - } - - printf("Downloading and extracting source...\n"); - - if (CallSystem("ports/gcc/port.sh download-only")) { - goto fail; - } - - printf("Building GCC...\n"); - StartSpinner(); - - { - CallSystem("echo Running configure... >> bin/build_cross.log"); - if (CallSystem("mkdir bin/build-binutils")) goto fail; - if (CallSystem("mkdir bin/build-gcc")) goto fail; - if (chdir("bin/build-binutils")) goto fail; - if (CallSystemF("../binutils-src/configure --target=" TOOLCHAIN_PREFIX " --prefix=\"%s\" --with-sysroot=%s --disable-nls --disable-werror >> ../build_cross.log 2>&1", - installationFolder, sysrootFolder)) goto fail; - if (chdir("../..")) goto fail; - if (chdir("bin/build-gcc")) goto fail; - // Add --without-headers for a x86_64-elf build. - if (CallSystemF("../gcc-src/configure --target=" TOOLCHAIN_PREFIX " --prefix=\"%s\" --enable-languages=c,c++ --with-sysroot=%s --disable-nls >> ../build_cross.log 2>&1", - installationFolder, sysrootFolder)) goto fail; - if (chdir("../..")) goto fail; - } - - runMakefiles:; - - { - CallSystem("touch bin/running_makefiles"); - - CallSystem("echo Building Binutils... >> bin/build_cross.log"); - if (chdir("bin/build-binutils")) goto fail; - if (CallSystemF("make -j%d >> ../build_cross.log 2>&1", processorCount)) goto fail; - if (CallSystem("make install >> ../build_cross.log 2>&1")) goto fail; - if (chdir("../..")) goto fail; - - CallSystem("echo Building GCC... >> bin/build_cross.log"); - if (chdir("bin/build-gcc")) goto fail; - if (CallSystemF("make all-gcc -j%d >> ../build_cross.log 2>&1", processorCount)) goto fail; - if (CallSystem("make all-target-libgcc >> ../build_cross.log 2>&1")) goto fail; - if (CallSystem("make install-gcc >> ../build_cross.log 2>&1")) goto fail; - if (CallSystem("make install-target-libgcc >> ../build_cross.log 2>&1")) goto fail; - if (chdir("../..")) goto fail; - } - - { - CallSystem("echo Removing debug symbols... >> bin/build_cross.log"); - CallSystemF("strip %s/bin/* >> bin/build_cross.log 2>&1", installationFolder); - CallSystemF("strip %s/libexec/gcc/" TOOLCHAIN_PREFIX "/" GCC_VERSION "/* >> bin/build_cross.log 2>&1", installationFolder); - } - - { - CallSystem("echo Modifying headers... >> bin/build_cross.log"); - char path[65536]; - sprintf(path, "%s/lib/gcc/" TOOLCHAIN_PREFIX "/" GCC_VERSION "/include/mm_malloc.h", installationFolder); - FILE *file = fopen(path, "w"); - if (!file) { - printf("Couldn't modify header files\n"); - goto fail; - } else { - fprintf(file, "/*Removed*/\n"); - fclose(file); - } - } - - StopSpinner(); - - { - BuildUtilities(); - - if (!BuildAPIDependencies()) { - goto fail; - } - - FILE *f = fopen("bin/build.ini", "wb"); - OutputStartOfBuildINI(f, false); - fprintf(f, "[general]\nwithout_kernel=1\n"); - fclose(f); - if (CallSystem("bin/build_core standard bin/build.ini")) goto fail; - } - - StartSpinner(); - - { - if (chdir("bin/build-gcc")) goto fail; - if (CallSystemF("make -j%d all-target-libstdc++-v3 >> ../build_cross.log 2>&1", processorCount)) goto fail; - if (CallSystem("make install-target-libstdc++-v3 >> ../build_cross.log 2>&1")) goto fail; - if (chdir("../..")) goto fail; - } - - { - CallSystem("echo Cleaning up... >> bin/build_cross.log"); - CallSystem("rm -rf bin/binutils-src bin/gcc-src bin/gmp-src bin/mpc-src bin/mpfr-src"); - CallSystem("rm -rf bin/build-binutils bin/build-gcc"); - CallSystem("rm bin/running_makefiles"); - } - - StopSpinner(); - - printf(ColorHighlight "\nThe cross compiler has built successfully.\n" ColorNormal); - foundValidCrossCompiler = true; - } - - return; - fail:; - StopSpinner(); - printf("\nThe build has failed. A log is available in " ColorHighlight "bin/build_cross.log" ColorNormal ".\n"); - exit(0); -} - void SaveConfig() { FILE *f = fopen("bin/build_config.ini", "wb"); fprintf(f, "accepted_license=%d\ncompiler_path=%s\n" @@ -1353,8 +1139,7 @@ void DoCommand(const char *l) { LoadOptions(); Compile(COMPILE_FOR_EMULATOR, atoi(GetOptionString("Emulator.PrimaryDriveMB")), NULL); } else if (0 == strcmp(l, "build-cross")) { - BuildCrossCompiler(); - SaveConfig(); + CallSystem("bin/script util/build_gcc.script"); printf("Please restart the build system.\n"); exit(0); } else if (0 == strcmp(l, "build-utilities") || 0 == strcmp(l, "u")) { @@ -1750,8 +1535,8 @@ void DoCommand(const char *l) { DoCommand("setup-pre-built-toolchain"); AddCompilerToPath(); #else - BuildCrossCompiler(); - SaveConfig(); + CallSystem("bin/script util/build_gcc.script"); + exit(0); #endif } else if (0 == strcmp(l, "help") || 0 == strcmp(l, "h") || 0 == strcmp(l, "?")) { printf(ColorHighlight "\n=== Common Commands ===\n" ColorNormal); diff --git a/util/script.c b/util/script.c index 57ff133..7870956 100644 --- a/util/script.c +++ b/util/script.c @@ -34,7 +34,6 @@ #include #define T_ERROR (0) - #define T_EOF (1) #define T_IDENTIFIER (2) #define T_STRING_LITERAL (3) @@ -321,47 +320,62 @@ void *FileLoad(const char *path, size_t *length); // --------------------------------- Base module. -#define BASE_MODULE_SOURCE \ - "void PrintStdErr(str x) #extcall;" \ - "void PrintStdErrWarning(str x) #extcall;" \ - "void PrintStdErrHighlight(str x) #extcall;" \ - "str ConsoleGetLine() #extcall;" \ - "str StringTrim(str x) #extcall;" \ - "int StringToByte(str x) #extcall;" \ - "bool SystemShellExecute(str x) #extcall;" /* Returns true on success. */ \ - "bool SystemShellExecuteWithWorkingDirectory(str wd, str x) #extcall;" /* Returns true on success. */ \ - "str SystemShellEvaluate(str x) #extcall;" \ - "int SystemGetProcessorCount() #extcall;" \ - "str SystemGetEnvironmentVariable(str name) #extcall;" \ - "bool SystemSetEnvironmentVariable(str name, str value) #extcall;" \ - "bool PathExists(str x) #extcall;" \ - "bool PathCreateDirectory(str x) #extcall;" /* TODO Replace the return value with a enum. */ \ - "bool PathDelete(str x) #extcall;" /* TODO Replace the return value with a enum. */ \ - "bool PathDeleteRecursively(str x) #extcall;" \ - "bool PathMove(str source, str destination) #extcall;" \ - "str PathGetDefaultPrefix() #extcall;" \ - "bool PathSetDefaultPrefixToScriptSourceDirectory() #extcall;" \ - "str FileReadAll(str path) #extcall;" /* TODO Returning an error? */ \ - "bool FileWriteAll(str path, str x) #extcall;" /* TODO Returning an error? */ \ - "bool FileCopy(str source, str destination) #extcall;" \ - "bool PersistRead(str path) #extcall;" \ - \ - "bool StringContains(str haystack, str needle) {" \ - " for int i = 0; i <= haystack:len() - needle:len(); i += 1 {" \ - " bool match = true;" \ - " for int j = 0; j < needle:len(); j += 1 { if haystack[i + j] != needle[j] match = false; }" \ - " if match { return true; }" \ - " }" \ - "" \ - " return false;" \ - "}" \ - ""\ - "bool CharacterIsAlnum(str c) {" \ - " int b = StringToByte(c);" \ - " return (b >= StringToByte(\"A\") && b <= StringToByte(\"Z\")) || (b >= StringToByte(\"a\") && b <= StringToByte(\"z\"))" \ - " || (b >= StringToByte(\"0\") && b <= StringToByte(\"9\"));" \ - "}" \ +char baseModuleSource[] = { + // Logging: + "void PrintStdErr(str x) #extcall;" + "void PrintStdErrWarning(str x) #extcall;" + "void PrintStdErrHighlight(str x) #extcall;" + + // String operations: + + "str StringTrim(str x) #extcall;" + "int StringToByte(str x) #extcall;" + "bool StringContains(str haystack, str needle) {" + " for int i = 0; i <= haystack:len() - needle:len(); i += 1 {" + " bool match = true;" + " for int j = 0; j < needle:len(); j += 1 { if haystack[i + j] != needle[j] match = false; }" + " if match { return true; }" + " }" + "" + " return false;" + "}" + "bool CharacterIsAlnum(str c) {" + " int b = StringToByte(c);" + " return (b >= StringToByte(\"A\") && b <= StringToByte(\"Z\")) || (b >= StringToByte(\"a\") && b <= StringToByte(\"z\"))" + " || (b >= StringToByte(\"0\") && b <= StringToByte(\"9\"));" + "}" + + // Miscellaneous: + + "int SystemGetProcessorCount() #extcall;" + + // File system access: + + "bool PathExists(str x) #extcall;" + "bool PathCreateDirectory(str x) #extcall;" // TODO Replace the return value with a enum. + "bool PathDelete(str x) #extcall;" // TODO Replace the return value with a enum. + "bool PathDeleteRecursively(str x) #extcall;" + "bool PathMove(str source, str destination) #extcall;" + "str PathGetDefaultPrefix() #extcall;" + "bool PathSetDefaultPrefixToScriptSourceDirectory() #extcall;" + "str FileReadAll(str path) #extcall;" // TODO Returning an error? + "bool FileWriteAll(str path, str x) #extcall;" // TODO Returning an error? + "bool FileCopy(str source, str destination) #extcall;" + + // Persistent variables: + + "bool PersistRead(str path) #extcall;" + + // Command line: + + "str ConsoleGetLine() #extcall;" + "str SystemGetEnvironmentVariable(str name) #extcall;" + "bool SystemSetEnvironmentVariable(str name, str value) #extcall;" + "bool SystemShellExecute(str x) #extcall;" // Returns true on success. + "bool SystemShellExecuteWithWorkingDirectory(str wd, str x) #extcall;" // Returns true on success. + "str SystemShellEvaluate(str x) #extcall;" +}; // --------------------------------- External function calls. @@ -1631,8 +1645,8 @@ bool ASTSetScopes(Tokenizer *tokenizer, ExecutionContext *context, Node *node, S if (node->firstChild->token.textBytes == 15 && 0 == MemoryCompare(node->firstChild->token.text, "__base_module__", node->firstChild->token.textBytes)) { - fileData = BASE_MODULE_SOURCE; - t.inputBytes = sizeof(BASE_MODULE_SOURCE) - 1; + fileData = baseModuleSource; + t.inputBytes = sizeof(baseModuleSource) - 1; t.isBaseModule = true; } else { fileData = FileLoad(path, &t.inputBytes);