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

Add an easy way to build from source without LLVM
This commit is contained in:
Andrew Kelley 2023-11-13 01:38:46 -05:00 committed by GitHub
commit caae40c216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 266 additions and 12 deletions

View File

@ -64,8 +64,40 @@ 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
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` (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

194
bootstrap.c Normal file
View File

@ -0,0 +1,194 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
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 <unistd.h>
#include <errno.h>
#include <sys/wait.h>
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", "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,
};
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",
"-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);
}
run_execv(argv);
panic("build script failed to create valid zig2 executable");
}

View File

@ -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"

View File

@ -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"

View File

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

View File

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