Skip to content

Commit caae40c

Browse files
authored
Merge pull request #17892 from ziglang/bootstrap-without-llvm
Add an easy way to build from source without LLVM
2 parents 91b897e + 557cb64 commit caae40c

File tree

6 files changed

+266
-12
lines changed

6 files changed

+266
-12
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
6565
page on the wiki.
6666

67+
## Building from Source without LLVM
68+
69+
In this case, the only system dependency is a C compiler.
70+
71+
```
72+
cc -o bootstrap bootstrap.c
73+
./bootstrap build
74+
```
75+
76+
You 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
80+
compiler 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+
69101
Zig is Free and Open Source Software. We welcome bug reports and patches from
70102
everyone. However, keep in mind that Zig governance is BDFN (Benevolent
71103
Dictator For Now) which means that Andrew Kelley has final say on the design

bootstrap.c

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
#include <stdbool.h>
5+
6+
static const char *get_c_compiler(void) {
7+
const char *cc = getenv("CC");
8+
return (cc == NULL) ? "cc" : cc;
9+
}
10+
11+
static 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+
24+
static 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+
46+
static void run_execv(char **argv) {
47+
if (execv(argv[0], argv) == -1 && errno == ENOENT) return;
48+
perror("execv failed");
49+
}
50+
#endif
51+
52+
static 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+
61+
static 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+
73+
static 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+
83+
static 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+
89+
int 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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ git config core.abbrev 9
2020
git fetch --unshallow || true
2121
git fetch --tags
2222

23+
# Test building from source without LLVM.
24+
git clean -fd
25+
rm -rf zig-out
26+
cc -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+
2331
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
2432
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533

ci/x86_64-linux-release.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ git config core.abbrev 9
2020
git fetch --unshallow || true
2121
git fetch --tags
2222

23+
# Test building from source without LLVM.
24+
git clean -fd
25+
rm -rf zig-out
26+
cc -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+
2331
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
2432
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
2533

lib/zig.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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
31593165
typedef 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
31623168
typedef 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
31653171
typedef 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
31683174
typedef _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
31713177
typedef _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__)
31743180
typedef __float128 zig_f128;
31753181
#define zig_make_f128(fp, repr) fp##q
31763182
#undef zig_make_special_f128

stage1/zig.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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
31593165
typedef 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
31623168
typedef 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
31653171
typedef 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
31683174
typedef _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
31713177
typedef _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__)
31743180
typedef __float128 zig_f128;
31753181
#define zig_make_f128(fp, repr) fp##q
31763182
#undef zig_make_special_f128

0 commit comments

Comments
 (0)