authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-11-13 01:38:46-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-11-13 01:38:46-05:00
logcaae40c216000be156f87c9e27cba3d0c45bb8c7
treedf72a728eb4440c4fb3745ffaceb33d34cb7f335
parent91b897ef581aec65dd7a080754ab09d2e176ed8f
parent557cb646918fd58e6a71e7be9fb49434e2930c18
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17892 from ziglang/bootstrap-without-llvm

Add an easy way to build from source without LLVM

6 files changed, 266 insertions(+), 12 deletions(-)

README.md+32
......@@ -64,8 +64,40 @@ For more options, tips, and troubleshooting, please see the
6464[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)
6565page on the wiki.
6666
67## Building from Source without LLVM
68
69In this case, the only system dependency is a C compiler.
70
71```
72cc -o bootstrap bootstrap.c
73./bootstrap build
74```
75
76You can pass any options to this that you would pass to `zig build` (see
77`--help` for options).
78
79[Without LLVM extensions](https://github.com/ziglang/zig/issues/16270), a Zig
80compiler is missing these features:
81- Release mode optimizations
82- aarch64 machine code backend
83- `@cImport` / `zig translate-c`
84- Ability to compile C files
85- Ability to compile assembly files
86- [Some ELF linking features](https://github.com/ziglang/zig/issues/17749)
87- [Most COFF/PE linking features](https://github.com/ziglang/zig/issues/17751)
88- [Some WebAssembly linking features](https://github.com/ziglang/zig/issues/17750)
89- [COFF linking](https://github.com/ziglang/zig/issues/17751)
90- [Ability to output LLVM bitcode](https://github.com/ziglang/zig/issues/13265)
91- [Windows resource file compilation](https://github.com/ziglang/zig/issues/17752)
92- [Ability to create import libs from def files](https://github.com/ziglang/zig/issues/17807)
93- [Automatic importlib file generation for Windows DLLs](https://github.com/ziglang/zig/issues/17753)
94- [Ability to create static archives from object files](https://github.com/ziglang/zig/issues/9828)
95- Ability to compile C++, Objective-C, and Objective-C++ files
96
6797## Contributing
6898
99[Donate monthly](https://ziglang.org/zsf/).
100
69101Zig is Free and Open Source Software. We welcome bug reports and patches from
70102everyone. However, keep in mind that Zig governance is BDFN (Benevolent
71103Dictator For Now) which means that Andrew Kelley has final say on the design
bootstrap.c created+194
......@@ -0,0 +1,194 @@
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <stdbool.h>
5
6static const char *get_c_compiler(void) {
7 const char *cc = getenv("CC");
8 return (cc == NULL) ? "cc" : cc;
9}
10
11static void panic(const char *reason) {
12 fprintf(stderr, "%s\n", reason);
13 abort();
14}
15
16#if defined(__WIN32__)
17#error TODO write the functionality for executing child process into this build script
18#else
19
20#include <unistd.h>
21#include <errno.h>
22#include <sys/wait.h>
23
24static void run(char **argv) {
25 pid_t pid = fork();
26 if (pid == -1)
27 panic("fork failed");
28 if (pid == 0) {
29 // child
30 execvp(argv[0], argv);
31 exit(1);
32 }
33
34 // parent
35
36 int status;
37 waitpid(pid, &status, 0);
38
39 if (!WIFEXITED(status))
40 panic("child process crashed");
41
42 if (WEXITSTATUS(status) != 0)
43 panic("child process failed");
44}
45
46static void run_execv(char **argv) {
47 if (execv(argv[0], argv) == -1 && errno == ENOENT) return;
48 perror("execv failed");
49}
50#endif
51
52static void print_and_run(const char **argv) {
53 fprintf(stderr, "%s", argv[0]);
54 for (const char **arg = argv + 1; *arg; arg += 1) {
55 fprintf(stderr, " %s", *arg);
56 }
57 fprintf(stderr, "\n");
58 run((char **)argv);
59}
60
61static const char *get_host_os(void) {
62#if defined(__WIN32__)
63 return "windows";
64#elif defined(__APPLE__)
65 return "macos";
66#elif defined(__linux__)
67 return "linux";
68#else
69#error TODO implement get_host_os in this build script for this target
70#endif
71}
72
73static const char *get_host_arch(void) {
74#if defined(__x86_64__ )
75 return "x86_64";
76#elif defined(__aarch64__)
77 return "aarch64";
78#else
79#error TODO implement get_host_arch in this build script for this target
80#endif
81}
82
83static const char *get_host_triple(void) {
84 static char global_buffer[100];
85 sprintf(global_buffer, "%s-%s", get_host_arch(), get_host_os());
86 return global_buffer;
87}
88
89int main(int argc, char **argv) {
90 argv[0] = "./zig2";
91 run_execv(argv);
92
93 const char *cc = get_c_compiler();
94 const char *host_triple = get_host_triple();
95
96 {
97 const char *child_argv[] = {
98 cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL,
99 };
100 print_and_run(child_argv);
101 }
102 {
103 const char *child_argv[] = {
104 "./zig-wasm2c", "stage1/zig1.wasm", "zig1.c", NULL,
105 };
106 print_and_run(child_argv);
107 }
108 {
109 const char *child_argv[] = {
110 cc, "-o", "zig1", "zig1.c", "stage1/wasi.c", "-std=c99", "-Os", "-lm", NULL,
111 };
112 print_and_run(child_argv);
113 }
114 {
115 FILE *f = fopen("config.zig", "wb");
116 if (f == NULL)
117 panic("unable to open config.zig for writing");
118
119 const char *zig_version = "0.12.0-dev.bootstrap";
120
121 int written = fprintf(f,
122 "pub const have_llvm = false;\n"
123 "pub const llvm_has_m68k = false;\n"
124 "pub const llvm_has_csky = false;\n"
125 "pub const llvm_has_arc = false;\n"
126 "pub const llvm_has_xtensa = false;\n"
127 "pub const version: [:0]const u8 = \"%s\";\n"
128 "pub const semver = @import(\"std\").SemanticVersion.parse(version) catch unreachable;\n"
129 "pub const enable_logging: bool = false;\n"
130 "pub const enable_link_snapshots: bool = false;\n"
131 "pub const enable_tracy = false;\n"
132 "pub const value_tracing = false;\n"
133 "pub const skip_non_native = false;\n"
134 "pub const only_c = false;\n"
135 "pub const force_gpa = false;\n"
136 "pub const only_core_functionality = true;\n"
137 "pub const only_reduce = false;\n"
138 , zig_version);
139 if (written < 100)
140 panic("unable to write to config.zig file");
141 if (fclose(f) != 0)
142 panic("unable to finish writing to config.zig file");
143 }
144
145 {
146 const char *child_argv[] = {
147 "./zig1", "lib", "build-exe", "src/main.zig",
148 "-ofmt=c", "-lc", "-OReleaseSmall",
149 "--name", "zig2", "-femit-bin=zig2.c",
150 "--mod", "build_options::config.zig",
151 "--mod", "Builtins/Builtin.def::src/stubs/aro_builtins.zig",
152 "--mod", "Attribute/names.def::src/stubs/aro_names.zig",
153 "--mod", "aro:Builtins/Builtin.def,Attribute/names.def:deps/aro/lib.zig",
154 "--deps", "build_options,aro",
155 "-target", host_triple,
156 NULL,
157 };
158 print_and_run(child_argv);
159 }
160
161 {
162 const char *child_argv[] = {
163 "./zig1", "lib", "build-obj", "lib/compiler_rt.zig",
164 "-ofmt=c", "-OReleaseSmall",
165 "--name", "compiler_rt", "-femit-bin=compiler_rt.c",
166 "--mod", "build_options::config.zig",
167 "--deps", "build_options",
168 "-target", host_triple,
169 NULL,
170 };
171 print_and_run(child_argv);
172 }
173
174 {
175 const char *child_argv[] = {
176 cc, "-o", "zig2", "zig2.c", "compiler_rt.c",
177 "-std=c99", "-O2", "-fno-stack-protector",
178 "-Istage1",
179#if defined(__APPLE__)
180 "-Wl,-stack_size,0x10000000",
181#else
182 "-Wl,-z,stack-size=0x10000000",
183#endif
184#if defined(__GNUC__)
185 "-pthread",
186#endif
187 NULL,
188 };
189 print_and_run(child_argv);
190 }
191
192 run_execv(argv);
193 panic("build script failed to create valid zig2 executable");
194}
ci/x86_64-linux-debug.sh+8
......@@ -20,6 +20,14 @@ git config core.abbrev 9
2020git fetch --unshallow || true
2121git fetch --tags
2222
23# Test building from source without LLVM.
24git clean -fd
25rm -rf zig-out
26cc -o bootstrap bootstrap.c
27./bootstrap build -Dno-lib
28# In order to run these behavior tests we need to move the `@cImport` ones to somewhere else.
29# ./zig-out/bin/zig test test/behavior.zig
30
2331export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
2432export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533
ci/x86_64-linux-release.sh+8
......@@ -20,6 +20,14 @@ git config core.abbrev 9
2020git fetch --unshallow || true
2121git fetch --tags
2222
23# Test building from source without LLVM.
24git clean -fd
25rm -rf zig-out
26cc -o bootstrap bootstrap.c
27./bootstrap build -Dno-lib
28# In order to run these behavior tests we need to move the `@cImport` ones to somewhere else.
29# ./zig-out/bin/zig test test/behavior.zig
30
2331export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
2432export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533
lib/zig.h+12-6
......@@ -61,6 +61,12 @@ typedef char bool;
6161#define zig_gnuc
6262#endif
6363
64#if defined(zig_gnuc) && (defined(__i386__) || defined(__x86_64__))
65#define zig_f128_has_miscompilations 1
66#else
67#define zig_f128_has_miscompilations 0
68#endif
69
6470#if _MSC_VER
6571#define zig_const_arr
6672#define zig_callconv(c) __##c
......@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;
31553161#define zig_has_f128 1
31563162#define zig_libc_name_f128(name) name##q
31573163#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3158#if FLT_MANT_DIG == 113
3164#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
31593165typedef float zig_f128;
31603166#define zig_make_f128(fp, repr) fp##f
3161#elif DBL_MANT_DIG == 113
3167#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113
31623168typedef double zig_f128;
31633169#define zig_make_f128(fp, repr) fp
3164#elif LDBL_MANT_DIG == 113
3170#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113
31653171typedef long double zig_f128;
31663172#define zig_make_f128(fp, repr) fp##l
3167#elif FLT128_MANT_DIG == 113
3173#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113
31683174typedef _Float128 zig_f128;
31693175#define zig_make_f128(fp, repr) fp##f128
3170#elif FLT64X_MANT_DIG == 113
3176#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113
31713177typedef _Float64x zig_f128;
31723178#define zig_make_f128(fp, repr) fp##f64x
3173#elif defined(__SIZEOF_FLOAT128__)
3179#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)
31743180typedef __float128 zig_f128;
31753181#define zig_make_f128(fp, repr) fp##q
31763182#undef zig_make_special_f128
stage1/zig.h+12-6
......@@ -61,6 +61,12 @@ typedef char bool;
6161#define zig_gnuc
6262#endif
6363
64#if defined(zig_gnuc) && (defined(__i386__) || defined(__x86_64__))
65#define zig_f128_has_miscompilations 1
66#else
67#define zig_f128_has_miscompilations 0
68#endif
69
6470#if _MSC_VER
6571#define zig_const_arr
6672#define zig_callconv(c) __##c
......@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;
31553161#define zig_has_f128 1
31563162#define zig_libc_name_f128(name) name##q
31573163#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3158#if FLT_MANT_DIG == 113
3164#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
31593165typedef float zig_f128;
31603166#define zig_make_f128(fp, repr) fp##f
3161#elif DBL_MANT_DIG == 113
3167#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113
31623168typedef double zig_f128;
31633169#define zig_make_f128(fp, repr) fp
3164#elif LDBL_MANT_DIG == 113
3170#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113
31653171typedef long double zig_f128;
31663172#define zig_make_f128(fp, repr) fp##l
3167#elif FLT128_MANT_DIG == 113
3173#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113
31683174typedef _Float128 zig_f128;
31693175#define zig_make_f128(fp, repr) fp##f128
3170#elif FLT64X_MANT_DIG == 113
3176#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113
31713177typedef _Float64x zig_f128;
31723178#define zig_make_f128(fp, repr) fp##f64x
3173#elif defined(__SIZEOF_FLOAT128__)
3179#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)
31743180typedef __float128 zig_f128;
31753181#define zig_make_f128(fp, repr) fp##q
31763182#undef zig_make_special_f128