From 621e89a863152978834f2c2562971cca846f9b3e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 5 Nov 2023 20:23:52 -0700 Subject: [PATCH 1/6] add bootstrap.c for building from source without LLVM When a zig compiler without LLVM extensions is satisfactory, this greatly simplified build-from-source process can be used. This could be useful for users who only want to contribute to the standard library, for example. --- README.md | 14 ++++ bootstrap.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 bootstrap.c diff --git a/README.md b/README.md index 8fb01b711c..699cf9a025 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,20 @@ For more options, tips, and troubleshooting, please see the [Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source) page on the wiki. +## Building from Source without LLVM + +If you don't need your Zig compiler to have LLVM extensions enabled, you can +follow these instructions instead. + +In this case, the only system dependency is a C compiler. + +``` +cc -o bootstrap bootstrap.c +./bootstrap build +``` + +You can pass any options to this that you would pass to `zig build`. + ## Contributing Zig is Free and Open Source Software. We welcome bug reports and patches from diff --git a/bootstrap.c b/bootstrap.c new file mode 100644 index 0000000000..da8b10064f --- /dev/null +++ b/bootstrap.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include + +static const char *get_c_compiler(void) { + const char *cc = getenv("CC"); + return (cc == NULL) ? "cc" : cc; +} + +static void panic(const char *reason) { + fprintf(stderr, "%s\n", reason); + abort(); +} + +#if defined(__WIN32__) +#error TODO write the functionality for executing child process into this build script +#else + +#include +#include +#include + +static void run(char **argv) { + pid_t pid = fork(); + if (pid == -1) + panic("fork failed"); + if (pid == 0) { + // child + execvp(argv[0], argv); + exit(1); + } + + // parent + + int status; + waitpid(pid, &status, 0); + + if (!WIFEXITED(status)) + panic("child process crashed"); + + if (WEXITSTATUS(status) != 0) + panic("child process failed"); +} + +static void run_execv(char **argv) { + if (execv(argv[0], argv) == -1 && errno == ENOENT) return; + perror("execv failed"); +} +#endif + +static void print_and_run(const char **argv) { + fprintf(stderr, "%s", argv[0]); + for (const char **arg = argv + 1; *arg; arg += 1) { + fprintf(stderr, " %s", *arg); + } + fprintf(stderr, "\n"); + run((char **)argv); +} + +static const char *get_host_os(void) { +#if defined(__WIN32__) + return "windows"; +#elif defined(__APPLE__) + return "macos"; +#elif defined(__linux__) + return "linux"; +#else +#error TODO implement get_host_os in this build script for this target +#endif +} + +static const char *get_host_arch(void) { +#if defined(__x86_64__ ) + return "x86_64"; +#elif defined(__aarch64__) + return "aarch64"; +#else +#error TODO implement get_host_arch in this build script for this target +#endif +} + +static const char *get_host_triple(void) { + static char global_buffer[100]; + sprintf(global_buffer, "%s-%s", get_host_arch(), get_host_os()); + return global_buffer; +} + +int main(int argc, char **argv) { + argv[0] = "./zig2"; + run_execv(argv); + + const char *cc = get_c_compiler(); + const char *host_triple = get_host_triple(); + + { + const char *child_argv[] = { + cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL, + }; + print_and_run(child_argv); + } + { + const char *child_argv[] = { + "./zig-wasm2c", "stage1/zig1.wasm", "zig1.c", NULL, + }; + print_and_run(child_argv); + } + { + const char *child_argv[] = { + cc, "-o", "zig1", "zig1.c", "stage1/wasi.c", "-std=c99", "-Os", "-lm", NULL, + }; + print_and_run(child_argv); + } + { + FILE *f = fopen("config.zig", "wb"); + if (f == NULL) + panic("unable to open config.zig for writing"); + + const char *zig_version = "0.12.0-dev.bootstrap"; + + int written = fprintf(f, + "pub const have_llvm = false;\n" + "pub const llvm_has_m68k = false;\n" + "pub const llvm_has_csky = false;\n" + "pub const llvm_has_arc = false;\n" + "pub const llvm_has_xtensa = false;\n" + "pub const version: [:0]const u8 = \"%s\";\n" + "pub const semver = @import(\"std\").SemanticVersion.parse(version) catch unreachable;\n" + "pub const enable_logging: bool = false;\n" + "pub const enable_link_snapshots: bool = false;\n" + "pub const enable_tracy = false;\n" + "pub const value_tracing = false;\n" + "pub const skip_non_native = false;\n" + "pub const only_c = false;\n" + "pub const force_gpa = false;\n" + "pub const only_core_functionality = true;\n" + "pub const only_reduce = false;\n" + , zig_version); + if (written < 100) + panic("unable to write to config.zig file"); + if (fclose(f) != 0) + panic("unable to finish writing to config.zig file"); + } + + { + const char *child_argv[] = { + "./zig1", "lib", "build-exe", "src/main.zig", + "-ofmt=c", "-lc", "-OReleaseSmall", + "--name", "zig2", "-femit-bin=zig2.c", + "--mod", "build_options::config.zig", + "--mod", "aro::deps/aro/lib.zig", + "--deps", "build_options,aro", + "-target", host_triple, + NULL, + }; + print_and_run(child_argv); + } + + { + const char *child_argv[] = { + "./zig1", "lib", "build-obj", "lib/compiler_rt.zig", + "-ofmt=c", "-OReleaseSmall", + "--name", "compiler_rt", "-femit-bin=compiler_rt.c", + "--mod", "build_options::config.zig", + "--deps", "build_options", + "-target", host_triple, + NULL, + }; + print_and_run(child_argv); + } + + { + const char *child_argv[] = { + cc, "-o", "zig2", "zig2.c", "compiler_rt.c", + "-std=c99", "-O2", "-fno-stack-protector", + "-Wl,-z,stack-size=0x10000000", "-Istage1", NULL, + }; + print_and_run(child_argv); + } + + run_execv(argv); + panic("build script failed to create valid zig2 executable"); +} From 910143e54cc1abf8069bf3a9727d76f50342bf8a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 6 Nov 2023 13:18:04 -0700 Subject: [PATCH 2/6] README: make note of what features are missing without LLVM --- README.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 699cf9a025..8eaeab7b95 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,6 @@ page on the wiki. ## Building from Source without LLVM -If you don't need your Zig compiler to have LLVM extensions enabled, you can -follow these instructions instead. - In this case, the only system dependency is a C compiler. ``` @@ -76,10 +73,31 @@ cc -o bootstrap bootstrap.c ./bootstrap build ``` -You can pass any options to this that you would pass to `zig build`. +You can pass any options to this that you would pass to `zig build` (see +`--help` for options). + +[Without LLVM extensions](https://github.com/ziglang/zig/issues/16270), a Zig +compiler is missing these features: +- Release mode optimizations +- aarch64 machine code backend +- `@cImport` / `zig translate-c` +- Ability to compile C files +- Ability to compile assembly files +- [Some ELF linking features](https://github.com/ziglang/zig/issues/17749) +- [Most COFF/PE linking features](https://github.com/ziglang/zig/issues/17751) +- [Some WebAssembly linking features](https://github.com/ziglang/zig/issues/17750) +- [COFF linking](https://github.com/ziglang/zig/issues/17751) +- [Ability to output LLVM bitcode](https://github.com/ziglang/zig/issues/13265) +- [Windows resource file compilation](https://github.com/ziglang/zig/issues/17752) +- [Ability to create import libs from def files](https://github.com/ziglang/zig/issues/17807) +- [Automatic importlib file generation for Windows DLLs](https://github.com/ziglang/zig/issues/17753) +- [Ability to create static archives from object files](https://github.com/ziglang/zig/issues/9828) +- Ability to compile C++, Objective-C, and Objective-C++ files ## Contributing +[Donate monthly](https://ziglang.org/zsf/). + Zig is Free and Open Source Software. We welcome bug reports and patches from everyone. However, keep in mind that Zig governance is BDFN (Benevolent Dictator For Now) which means that Andrew Kelley has final say on the design From 3c921522b5ae8d0bcef48b14687a66872fd9b781 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 7 Nov 2023 21:08:44 -0700 Subject: [PATCH 3/6] bootstrap.c: update aro module --- bootstrap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bootstrap.c b/bootstrap.c index da8b10064f..a32b3d2a5f 100644 --- a/bootstrap.c +++ b/bootstrap.c @@ -148,7 +148,9 @@ int main(int argc, char **argv) { "-ofmt=c", "-lc", "-OReleaseSmall", "--name", "zig2", "-femit-bin=zig2.c", "--mod", "build_options::config.zig", - "--mod", "aro::deps/aro/lib.zig", + "--mod", "Builtins/Builtin.def::src/stubs/aro_builtins.zig", + "--mod", "Attribute/names.def::src/stubs/aro_names.zig", + "--mod", "aro:Builtins/Builtin.def,Attribute/names.def:deps/aro/lib.zig", "--deps", "build_options,aro", "-target", host_triple, NULL, From f45aac49033c1660be21301843e4aa950924899d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 9 Nov 2023 14:30:18 -0700 Subject: [PATCH 4/6] CI: test building from source without LLVM --- ci/x86_64-linux-debug.sh | 8 ++++++++ ci/x86_64-linux-release.sh | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/ci/x86_64-linux-debug.sh b/ci/x86_64-linux-debug.sh index 69cd569879..bbab0c564d 100755 --- a/ci/x86_64-linux-debug.sh +++ b/ci/x86_64-linux-debug.sh @@ -20,6 +20,14 @@ git config core.abbrev 9 git fetch --unshallow || true git fetch --tags +# Test building from source without LLVM. +git clean -fd +rm -rf zig-out +cc -o bootstrap bootstrap.c +./bootstrap build -Dno-lib +# In order to run these behavior tests we need to move the `@cImport` ones to somewhere else. +# ./zig-out/bin/zig test test/behavior.zig + export CC="$ZIG cc -target $TARGET -mcpu=$MCPU" export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU" diff --git a/ci/x86_64-linux-release.sh b/ci/x86_64-linux-release.sh index 421fb89ba7..61320ce0f9 100755 --- a/ci/x86_64-linux-release.sh +++ b/ci/x86_64-linux-release.sh @@ -20,6 +20,14 @@ git config core.abbrev 9 git fetch --unshallow || true git fetch --tags +# Test building from source without LLVM. +git clean -fd +rm -rf zig-out +cc -o bootstrap bootstrap.c +./bootstrap build -Dno-lib +# In order to run these behavior tests we need to move the `@cImport` ones to somewhere else. +# ./zig-out/bin/zig test test/behavior.zig + export CC="$ZIG cc -target $TARGET -mcpu=$MCPU" export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU" From 0dbaa8d3ae8f2892b60751d5a3c528ddb3b4fc3b Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 12 Nov 2023 14:31:23 -0500 Subject: [PATCH 5/6] zig.h: workaround for gcc `f128` miscompilations --- lib/zig.h | 18 ++++++++++++------ stage1/zig.h | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/zig.h b/lib/zig.h index 233c2961cb..acd7b1d700 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -61,6 +61,12 @@ typedef char bool; #define zig_gnuc #endif +#if defined(zig_gnuc) && (defined(__i386__) || defined(__x86_64__)) +#define zig_f128_has_miscompilations 1 +#else +#define zig_f128_has_miscompilations 0 +#endif + #if _MSC_VER #define zig_const_arr #define zig_callconv(c) __##c @@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80; #define zig_has_f128 1 #define zig_libc_name_f128(name) name##q #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) -#if FLT_MANT_DIG == 113 +#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113 typedef float zig_f128; #define zig_make_f128(fp, repr) fp##f -#elif DBL_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 typedef double zig_f128; #define zig_make_f128(fp, repr) fp -#elif LDBL_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 typedef long double zig_f128; #define zig_make_f128(fp, repr) fp##l -#elif FLT128_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 typedef _Float128 zig_f128; #define zig_make_f128(fp, repr) fp##f128 -#elif FLT64X_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 typedef _Float64x zig_f128; #define zig_make_f128(fp, repr) fp##f64x -#elif defined(__SIZEOF_FLOAT128__) +#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) typedef __float128 zig_f128; #define zig_make_f128(fp, repr) fp##q #undef zig_make_special_f128 diff --git a/stage1/zig.h b/stage1/zig.h index 233c2961cb..acd7b1d700 100644 --- a/stage1/zig.h +++ b/stage1/zig.h @@ -61,6 +61,12 @@ typedef char bool; #define zig_gnuc #endif +#if defined(zig_gnuc) && (defined(__i386__) || defined(__x86_64__)) +#define zig_f128_has_miscompilations 1 +#else +#define zig_f128_has_miscompilations 0 +#endif + #if _MSC_VER #define zig_const_arr #define zig_callconv(c) __##c @@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80; #define zig_has_f128 1 #define zig_libc_name_f128(name) name##q #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) -#if FLT_MANT_DIG == 113 +#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113 typedef float zig_f128; #define zig_make_f128(fp, repr) fp##f -#elif DBL_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 typedef double zig_f128; #define zig_make_f128(fp, repr) fp -#elif LDBL_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 typedef long double zig_f128; #define zig_make_f128(fp, repr) fp##l -#elif FLT128_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 typedef _Float128 zig_f128; #define zig_make_f128(fp, repr) fp##f128 -#elif FLT64X_MANT_DIG == 113 +#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 typedef _Float64x zig_f128; #define zig_make_f128(fp, repr) fp##f64x -#elif defined(__SIZEOF_FLOAT128__) +#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) typedef __float128 zig_f128; #define zig_make_f128(fp, repr) fp##q #undef zig_make_special_f128 From 557cb646918fd58e6a71e7be9fb49434e2930c18 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 12 Nov 2023 17:29:21 -0700 Subject: [PATCH 6/6] bootstrap.c: add -pthread if the compiler is gnu otherwise we get undefined symbol errors on pthread stuff --- bootstrap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bootstrap.c b/bootstrap.c index a32b3d2a5f..35ad33d266 100644 --- a/bootstrap.c +++ b/bootstrap.c @@ -175,7 +175,16 @@ int main(int argc, char **argv) { const char *child_argv[] = { cc, "-o", "zig2", "zig2.c", "compiler_rt.c", "-std=c99", "-O2", "-fno-stack-protector", - "-Wl,-z,stack-size=0x10000000", "-Istage1", NULL, + "-Istage1", +#if defined(__APPLE__) + "-Wl,-stack_size,0x10000000", +#else + "-Wl,-z,stack-size=0x10000000", +#endif +#if defined(__GNUC__) + "-pthread", +#endif + NULL, }; print_and_run(child_argv); }