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...@@ -64,8 +64,40 @@ For more options, tips, and troubleshooting, please see the
64[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)64[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)
65page on the wiki.65page 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
67## Contributing97## Contributing
6898
99[Donate monthly](https://ziglang.org/zsf/).
100
69Zig is Free and Open Source Software. We welcome bug reports and patches from101Zig is Free and Open Source Software. We welcome bug reports and patches from
70everyone. However, keep in mind that Zig governance is BDFN (Benevolent102everyone. However, keep in mind that Zig governance is BDFN (Benevolent
71Dictator For Now) which means that Andrew Kelley has final say on the design103Dictator 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...@@ -20,6 +20,14 @@ git config core.abbrev 9
20git fetch --unshallow || true20git fetch --unshallow || true
21git fetch --tags21git 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
23export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"31export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
24export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"32export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533
ci/x86_64-linux-release.sh+8
...@@ -20,6 +20,14 @@ git config core.abbrev 9...@@ -20,6 +20,14 @@ git config core.abbrev 9
20git fetch --unshallow || true20git fetch --unshallow || true
21git fetch --tags21git 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
23export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"31export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
24export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"32export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533
lib/zig.h+12-6
...@@ -61,6 +61,12 @@ typedef char bool;...@@ -61,6 +61,12 @@ typedef char bool;
61#define zig_gnuc61#define zig_gnuc
62#endif62#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
64#if _MSC_VER70#if _MSC_VER
65#define zig_const_arr71#define zig_const_arr
66#define zig_callconv(c) __##c72#define zig_callconv(c) __##c
...@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;...@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;
3155#define zig_has_f128 13161#define zig_has_f128 1
3156#define zig_libc_name_f128(name) name##q3162#define zig_libc_name_f128(name) name##q
3157#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)3163#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3158#if FLT_MANT_DIG == 1133164#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
3159typedef float zig_f128;3165typedef float zig_f128;
3160#define zig_make_f128(fp, repr) fp##f3166#define zig_make_f128(fp, repr) fp##f
3161#elif DBL_MANT_DIG == 1133167#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113
3162typedef double zig_f128;3168typedef double zig_f128;
3163#define zig_make_f128(fp, repr) fp3169#define zig_make_f128(fp, repr) fp
3164#elif LDBL_MANT_DIG == 1133170#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113
3165typedef long double zig_f128;3171typedef long double zig_f128;
3166#define zig_make_f128(fp, repr) fp##l3172#define zig_make_f128(fp, repr) fp##l
3167#elif FLT128_MANT_DIG == 1133173#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113
3168typedef _Float128 zig_f128;3174typedef _Float128 zig_f128;
3169#define zig_make_f128(fp, repr) fp##f1283175#define zig_make_f128(fp, repr) fp##f128
3170#elif FLT64X_MANT_DIG == 1133176#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113
3171typedef _Float64x zig_f128;3177typedef _Float64x zig_f128;
3172#define zig_make_f128(fp, repr) fp##f64x3178#define zig_make_f128(fp, repr) fp##f64x
3173#elif defined(__SIZEOF_FLOAT128__)3179#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)
3174typedef __float128 zig_f128;3180typedef __float128 zig_f128;
3175#define zig_make_f128(fp, repr) fp##q3181#define zig_make_f128(fp, repr) fp##q
3176#undef zig_make_special_f1283182#undef zig_make_special_f128
stage1/zig.h+12-6
...@@ -61,6 +61,12 @@ typedef char bool;...@@ -61,6 +61,12 @@ typedef char bool;
61#define zig_gnuc61#define zig_gnuc
62#endif62#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
64#if _MSC_VER70#if _MSC_VER
65#define zig_const_arr71#define zig_const_arr
66#define zig_callconv(c) __##c72#define zig_callconv(c) __##c
...@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;...@@ -3155,22 +3161,22 @@ typedef zig_u128 zig_f80;
3155#define zig_has_f128 13161#define zig_has_f128 1
3156#define zig_libc_name_f128(name) name##q3162#define zig_libc_name_f128(name) name##q
3157#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)3163#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3158#if FLT_MANT_DIG == 1133164#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
3159typedef float zig_f128;3165typedef float zig_f128;
3160#define zig_make_f128(fp, repr) fp##f3166#define zig_make_f128(fp, repr) fp##f
3161#elif DBL_MANT_DIG == 1133167#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113
3162typedef double zig_f128;3168typedef double zig_f128;
3163#define zig_make_f128(fp, repr) fp3169#define zig_make_f128(fp, repr) fp
3164#elif LDBL_MANT_DIG == 1133170#elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113
3165typedef long double zig_f128;3171typedef long double zig_f128;
3166#define zig_make_f128(fp, repr) fp##l3172#define zig_make_f128(fp, repr) fp##l
3167#elif FLT128_MANT_DIG == 1133173#elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113
3168typedef _Float128 zig_f128;3174typedef _Float128 zig_f128;
3169#define zig_make_f128(fp, repr) fp##f1283175#define zig_make_f128(fp, repr) fp##f128
3170#elif FLT64X_MANT_DIG == 1133176#elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113
3171typedef _Float64x zig_f128;3177typedef _Float64x zig_f128;
3172#define zig_make_f128(fp, repr) fp##f64x3178#define zig_make_f128(fp, repr) fp##f64x
3173#elif defined(__SIZEOF_FLOAT128__)3179#elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__)
3174typedef __float128 zig_f128;3180typedef __float128 zig_f128;
3175#define zig_make_f128(fp, repr) fp##q3181#define zig_make_f128(fp, repr) fp##q
3176#undef zig_make_special_f1283182#undef zig_make_special_f128