use util/build_gcc.script instead of BuildCrossCompiler

This commit is contained in:
nakst 2022-01-28 18:14:47 +00:00
parent 4ac89712e6
commit 4a31fe1850
2 changed files with 60 additions and 261 deletions

View File

@ -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);

View File

@ -34,7 +34,6 @@
#include <stdbool.h>
#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);