authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-07 23:54:34-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-12-07 23:54:34-05:00
loga01d55e801c91b5f8b6beb1ae88640e16ffdf058
tree59d121b5f2889bf99dae0d03fa9604a47cb68cd9
parent5f7b97e84c7e2bc7682510e97996ad30147026d0
parent1afea36a16ba4963f2a4ad0b2efb5e18680305ac
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7309 from ziglang/build-stage1-with-only-zig

ability to build stage1 using only a zig tarball

20 files changed, 678 insertions(+), 354 deletions(-)

CMakeLists.txt+6-3
...@@ -63,9 +63,6 @@ endif()...@@ -63,9 +63,6 @@ endif()
6363
64if(ZIG_STATIC)64if(ZIG_STATIC)
65 set(ZIG_STATIC_LLVM "on")65 set(ZIG_STATIC_LLVM "on")
66 set(ZIG_LINK_MODE "Static")
67else()
68 set(ZIG_LINK_MODE "Dynamic")
69endif()66endif()
7067
71string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_LIBC_LIB_DIR_ESCAPED "${ZIG_LIBC_LIB_DIR}")68string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_LIBC_LIB_DIR_ESCAPED "${ZIG_LIBC_LIB_DIR}")
...@@ -594,6 +591,12 @@ else(MSVC)...@@ -594,6 +591,12 @@ else(MSVC)
594 set(EXE_CFLAGS "-std=c++14")591 set(EXE_CFLAGS "-std=c++14")
595endif(MSVC)592endif(MSVC)
596593
594if(ZIG_STATIC)
595 set(EXE_CFLAGS "${EXE_CFLAGS} -DZIG_LINK_MODE=Static")
596else()
597 set(EXE_CFLAGS "${EXE_CFLAGS} -DZIG_LINK_MODE=Dynamic")
598endif()
599
597if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")600if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
598 if(MSVC)601 if(MSVC)
599 set(EXE_CFLAGS "${EXE_CFLAGS} /w")602 set(EXE_CFLAGS "${EXE_CFLAGS} /w")
README.md+5-91
...@@ -14,98 +14,12 @@ A general-purpose programming language and toolchain for maintaining...@@ -14,98 +14,12 @@ A general-purpose programming language and toolchain for maintaining
14 * [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ)14 * [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ)
15 * [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects)15 * [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects)
1616
17## Building from Source17## Installation
1818
19[![Build Status](https://dev.azure.com/ziglang/zig/_apis/build/status/ziglang.zig?branchName=master)](https://dev.azure.com/ziglang/zig/_build/latest?definitionId=1&branchName=master)19 * [download a pre-built binary](https://ziglang.org/download/)
2020 * [install from a package manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager)
21Note that you can21 * [build from source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)
22[download a binary of the master branch](https://ziglang.org/download/#release-master) or 22 * [bootstrap zig for any target](https://github.com/ziglang/zig-bootstrap)
23[install Zig from a package manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager).
24
25### Stage 1: Build Zig from C++ Source Code
26
27This step must be repeated when you make changes to any of the C++ source code.
28
29#### Dependencies
30
31##### POSIX
32
33 * cmake >= 2.8.5
34 * gcc >= 5.0.0 or clang >= 3.6.0
35 * LLVM, Clang, LLD development libraries == 11.x, compiled with the same gcc or clang version above
36 - Use the system package manager, or [build from source](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#posix).
37
38##### Windows
39
40 * cmake >= 3.15.3
41 * Microsoft Visual Studio. Supported versions:
42 - 2017 (version 15.8)
43 - 2019 (version 16)
44 * LLVM, Clang, LLD development libraries == 11.x
45 - Use the [pre-built binaries](https://github.com/ziglang/zig/wiki/Building-Zig-on-Windows) or [build from source](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#windows).
46
47#### Instructions
48
49##### POSIX
50
51```
52mkdir build
53cd build
54cmake ..
55make install
56```
57
58Need help? [Troubleshooting Build Issues](https://github.com/ziglang/zig/wiki/Troubleshooting-Build-Issues)
59
60##### MacOS
61
62```
63brew install cmake llvm
64brew outdated llvm || brew upgrade llvm
65mkdir build
66cd build
67cmake .. -DCMAKE_PREFIX_PATH=$(brew --prefix llvm)
68make install
69```
70
71##### Windows
72
73See https://github.com/ziglang/zig/wiki/Building-Zig-on-Windows
74
75### Stage 2: Build Self-Hosted Zig from Zig Source Code
76
77Now we use the stage1 binary:
78
79```
80zig build --prefix $(pwd)/stage2 -Denable-llvm
81```
82
83This produces `stage2/bin/zig` which can be used for testing and development.
84Once it is feature complete, it will be used to build stage 3 - the final compiler
85binary.
86
87### Stage 3: Rebuild Self-Hosted Zig Using the Self-Hosted Compiler
88
89*Note: Stage 2 compiler is not yet able to build Stage 3. Building Stage 3 is
90not yet supported.*
91
92Once the self-hosted compiler can build itself, this will be the actual
93compiler binary that we will install to the system. Until then, users should
94use stage 1.
95
96#### Debug / Development Build
97
98```
99stage2/bin/zig build
100```
101
102This produces `zig-cache/bin/zig`.
103
104#### Release / Install Build
105
106```
107stage2/bin/zig build install -Drelease
108```
10923
110## License24## License
11125
build.zig+536-234
...@@ -53,7 +53,9 @@ pub fn build(b: *Builder) !void {...@@ -53,7 +53,9 @@ pub fn build(b: *Builder) !void {
53 const skip_compile_errors = b.option(bool, "skip-compile-errors", "Main test suite skips compile error tests") orelse false;53 const skip_compile_errors = b.option(bool, "skip-compile-errors", "Main test suite skips compile error tests") orelse false;
5454
55 const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;55 const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
56 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse false;56 const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
57 const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
58 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (is_stage1 or static_llvm);
57 const config_h_path_option = b.option([]const u8, "config_h", "Path to the generated config.h");59 const config_h_path_option = b.option([]const u8, "config_h", "Path to the generated config.h");
5860
59 b.installDirectory(InstallDirectoryOptions{61 b.installDirectory(InstallDirectoryOptions{
...@@ -76,7 +78,9 @@ pub fn build(b: *Builder) !void {...@@ -76,7 +78,9 @@ pub fn build(b: *Builder) !void {
76 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");78 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
77 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;79 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
7880
79 var exe = b.addExecutable("zig", "src/main.zig");81 const main_file = if (is_stage1) "src/stage1.zig" else "src/main.zig";
82
83 var exe = b.addExecutable("zig", main_file);
80 exe.install();84 exe.install();
81 exe.setBuildMode(mode);85 exe.setBuildMode(mode);
82 exe.setTarget(target);86 exe.setTarget(target);
...@@ -86,15 +90,126 @@ pub fn build(b: *Builder) !void {...@@ -86,15 +90,126 @@ pub fn build(b: *Builder) !void {
86 exe.addBuildOption(bool, "skip_non_native", skip_non_native);90 exe.addBuildOption(bool, "skip_non_native", skip_non_native);
87 exe.addBuildOption(bool, "have_llvm", enable_llvm);91 exe.addBuildOption(bool, "have_llvm", enable_llvm);
88 if (enable_llvm) {92 if (enable_llvm) {
89 const config_h_text = if (config_h_path_option) |config_h_path|93 const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);
90 try std.fs.cwd().readFileAlloc(b.allocator, toNativePathSep(b, config_h_path), max_config_h_bytes)94 if (is_stage1) {
91 else95 exe.addIncludeDir("src");
92 try findAndReadConfigH(b);96 exe.addIncludeDir("deps/SoftFloat-3e/source/include");
97 // This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
98 // of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
99 // is pointless.
100 exe.addPackagePath("compiler_rt", "src/empty.zig");
101 exe.defineCMacro("ZIG_LINK_MODE=Static");
102
103 const softfloat = b.addStaticLibrary("softfloat", null);
104 softfloat.setBuildMode(.ReleaseFast);
105 softfloat.setTarget(target);
106 softfloat.addIncludeDir("deps/SoftFloat-3e-prebuilt");
107 softfloat.addIncludeDir("deps/SoftFloat-3e/source/8086");
108 softfloat.addIncludeDir("deps/SoftFloat-3e/source/include");
109 softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
110 exe.linkLibrary(softfloat);
111
112 const exe_cflags = [_][]const u8{
113 "-std=c++14",
114 "-D__STDC_CONSTANT_MACROS",
115 "-D__STDC_FORMAT_MACROS",
116 "-D__STDC_LIMIT_MACROS",
117 "-D_GNU_SOURCE",
118 "-fvisibility-inlines-hidden",
119 "-fno-exceptions",
120 "-fno-rtti",
121 "-Werror=type-limits",
122 "-Wno-missing-braces",
123 "-Wno-comment",
124 };
125 exe.addCSourceFiles(&stage1_sources, &exe_cflags);
126 exe.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
127 if (cmake_cfg == null) {
128 // We need this because otherwise zig_clang_cc1_main.cpp ends up pulling
129 // in a dependency on llvm::cfg::Update<llvm::BasicBlock*>::dump() which is
130 // unavailable when LLVM is compiled in Release mode.
131 const zig_cpp_cflags = exe_cflags ++ [_][]const u8{"-DNDEBUG=1"};
132 exe.addCSourceFiles(&zig_cpp_sources, &zig_cpp_cflags);
133 }
134 }
135 if (cmake_cfg) |cfg| {
136 // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
137 // That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
138 // the information passed on to us from cmake.
139 if (cfg.cmake_prefix_path.len > 0) {
140 b.addSearchPrefix(cfg.cmake_prefix_path);
141 }
142 exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
143 cfg.cmake_binary_dir,
144 "zigcpp",
145 b.fmt("{s}{s}{s}", .{ exe.target.libPrefix(), "zigcpp", exe.target.staticLibSuffix() }),
146 }) catch unreachable);
147 assert(cfg.lld_include_dir.len != 0);
148 exe.addIncludeDir(cfg.lld_include_dir);
149 addCMakeLibraryList(exe, cfg.clang_libraries);
150 addCMakeLibraryList(exe, cfg.lld_libraries);
151 addCMakeLibraryList(exe, cfg.llvm_libraries);
152
153 const need_cpp_includes = tracy != null;
154
155 // System -lc++ must be used because in this code path we are attempting to link
156 // against system-provided LLVM, Clang, LLD.
157 if (exe.target.getOsTag() == .linux) {
158 // First we try to static link against gcc libstdc++. If that doesn't work,
159 // we fall back to -lc++ and cross our fingers.
160 addCxxKnownPath(b, cfg, exe, "libstdc++.a", "", need_cpp_includes) catch |err| switch (err) {
161 error.RequiredLibraryNotFound => {
162 exe.linkSystemLibrary("c++");
163 },
164 else => |e| return e,
165 };
93166
94 var ctx = parseConfigH(b, config_h_text);167 exe.linkSystemLibrary("pthread");
95 ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);168 } else if (exe.target.isFreeBSD()) {
169 try addCxxKnownPath(b, cfg, exe, "libc++.a", null, need_cpp_includes);
170 exe.linkSystemLibrary("pthread");
171 } else if (exe.target.isDarwin()) {
172 if (addCxxKnownPath(b, cfg, exe, "libgcc_eh.a", "", need_cpp_includes)) {
173 // Compiler is GCC.
174 try addCxxKnownPath(b, cfg, exe, "libstdc++.a", null, need_cpp_includes);
175 exe.linkSystemLibrary("pthread");
176 // TODO LLD cannot perform this link.
177 // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
178 // See https://github.com/ziglang/zig/issues/1535
179 } else |err| switch (err) {
180 error.RequiredLibraryNotFound => {
181 // System compiler, not gcc.
182 exe.linkSystemLibrary("c++");
183 },
184 else => |e| return e,
185 }
186 }
187
188 if (cfg.dia_guids_lib.len != 0) {
189 exe.addObjectFile(cfg.dia_guids_lib);
190 }
191 } else {
192 // Here we are -Denable-llvm but no cmake integration.
193 for (clang_libs) |lib_name| {
194 exe.linkSystemLibrary(lib_name);
195 }
96196
97 try configureStage2(b, exe, ctx, tracy != null);197 for (lld_libs) |lib_name| {
198 exe.linkSystemLibrary(lib_name);
199 }
200
201 for (llvm_libs) |lib_name| {
202 exe.linkSystemLibrary(lib_name);
203 }
204
205 // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.
206 exe.linkSystemLibrary("c++");
207
208 if (target.getOs().tag == .windows) {
209 exe.linkSystemLibrary("version");
210 exe.linkSystemLibrary("uuid");
211 }
212 }
98 }213 }
99 if (link_libc) {214 if (link_libc) {
100 exe.linkLibC();215 exe.linkLibC();
...@@ -141,12 +256,15 @@ pub fn build(b: *Builder) !void {...@@ -141,12 +256,15 @@ pub fn build(b: *Builder) !void {
141 break :v b.fmt("{}+{}{}", .{ version_string, git_sha_trimmed, dirty_suffix });256 break :v b.fmt("{}+{}{}", .{ version_string, git_sha_trimmed, dirty_suffix });
142 }257 }
143 };258 };
144 exe.addBuildOption([]const u8, "version", version);259 exe.addBuildOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
260
261 const semver = try std.SemanticVersion.parse(version);
262 exe.addBuildOption(std.SemanticVersion, "semver", semver);
145263
146 exe.addBuildOption([]const []const u8, "log_scopes", log_scopes);264 exe.addBuildOption([]const []const u8, "log_scopes", log_scopes);
147 exe.addBuildOption([]const []const u8, "zir_dumps", zir_dumps);265 exe.addBuildOption([]const []const u8, "zir_dumps", zir_dumps);
148 exe.addBuildOption(bool, "enable_tracy", tracy != null);266 exe.addBuildOption(bool, "enable_tracy", tracy != null);
149 exe.addBuildOption(bool, "is_stage1", false);267 exe.addBuildOption(bool, "is_stage1", is_stage1);
150 if (tracy) |tracy_path| {268 if (tracy) |tracy_path| {
151 const client_cpp = fs.path.join(269 const client_cpp = fs.path.join(
152 b.allocator,270 b.allocator,
...@@ -168,7 +286,7 @@ pub fn build(b: *Builder) !void {...@@ -168,7 +286,7 @@ pub fn build(b: *Builder) !void {
168 const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc");286 const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc");
169287
170 test_stage2.addBuildOption(bool, "skip_non_native", skip_non_native);288 test_stage2.addBuildOption(bool, "skip_non_native", skip_non_native);
171 test_stage2.addBuildOption(bool, "is_stage1", false);289 test_stage2.addBuildOption(bool, "is_stage1", is_stage1);
172 test_stage2.addBuildOption(bool, "have_llvm", enable_llvm);290 test_stage2.addBuildOption(bool, "have_llvm", enable_llvm);
173 test_stage2.addBuildOption(bool, "enable_qemu", is_qemu_enabled);291 test_stage2.addBuildOption(bool, "enable_qemu", is_qemu_enabled);
174 test_stage2.addBuildOption(bool, "enable_wine", is_wine_enabled);292 test_stage2.addBuildOption(bool, "enable_wine", is_wine_enabled);
...@@ -226,199 +344,10 @@ pub fn build(b: *Builder) !void {...@@ -226,199 +344,10 @@ pub fn build(b: *Builder) !void {
226 test_step.dependOn(docs_step);344 test_step.dependOn(docs_step);
227}345}
228346
229fn dependOnLib(b: *Builder, lib_exe_obj: anytype, dep: LibraryDep) void {
230 for (dep.libdirs.items) |lib_dir| {
231 lib_exe_obj.addLibPath(lib_dir);
232 }
233 const lib_dir = fs.path.join(
234 b.allocator,
235 &[_][]const u8{ dep.prefix, "lib" },
236 ) catch unreachable;
237 for (dep.system_libs.items) |lib| {
238 const static_bare_name = if (mem.eql(u8, lib, "curses"))
239 @as([]const u8, "libncurses.a")
240 else
241 b.fmt("lib{}.a", .{lib});
242 const static_lib_name = fs.path.join(
243 b.allocator,
244 &[_][]const u8{ lib_dir, static_bare_name },
245 ) catch unreachable;
246 const have_static = fileExists(static_lib_name) catch unreachable;
247 if (have_static) {
248 lib_exe_obj.addObjectFile(static_lib_name);
249 } else {
250 lib_exe_obj.linkSystemLibrary(lib);
251 }
252 }
253 for (dep.libs.items) |lib| {
254 lib_exe_obj.addObjectFile(lib);
255 }
256 for (dep.includes.items) |include_path| {
257 lib_exe_obj.addIncludeDir(include_path);
258 }
259}
260
261fn fileExists(filename: []const u8) !bool {
262 fs.cwd().access(filename, .{}) catch |err| switch (err) {
263 error.FileNotFound => return false,
264 else => return err,
265 };
266 return true;
267}
268
269fn addCppLib(b: *Builder, lib_exe_obj: anytype, cmake_binary_dir: []const u8, lib_name: []const u8) void {
270 lib_exe_obj.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
271 cmake_binary_dir,
272 "zigcpp",
273 b.fmt("{}{}{}", .{ lib_exe_obj.target.libPrefix(), lib_name, lib_exe_obj.target.staticLibSuffix() }),
274 }) catch unreachable);
275}
276
277const LibraryDep = struct {
278 prefix: []const u8,
279 libdirs: ArrayList([]const u8),
280 libs: ArrayList([]const u8),
281 system_libs: ArrayList([]const u8),
282 includes: ArrayList([]const u8),
283};
284
285fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
286 const shared_mode = try b.exec(&[_][]const u8{ llvm_config_exe, "--shared-mode" });
287 const is_static = mem.startsWith(u8, shared_mode, "static");
288 const libs_output = if (is_static)
289 try b.exec(&[_][]const u8{
290 llvm_config_exe,
291 "--libfiles",
292 "--system-libs",
293 })
294 else
295 try b.exec(&[_][]const u8{
296 llvm_config_exe,
297 "--libs",
298 });
299 const includes_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--includedir" });
300 const libdir_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--libdir" });
301 const prefix_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--prefix" });
302
303 var result = LibraryDep{
304 .prefix = mem.tokenize(prefix_output, " \r\n").next().?,
305 .libs = ArrayList([]const u8).init(b.allocator),
306 .system_libs = ArrayList([]const u8).init(b.allocator),
307 .includes = ArrayList([]const u8).init(b.allocator),
308 .libdirs = ArrayList([]const u8).init(b.allocator),
309 };
310 {
311 var it = mem.tokenize(libs_output, " \r\n");
312 while (it.next()) |lib_arg| {
313 if (mem.startsWith(u8, lib_arg, "-l")) {
314 try result.system_libs.append(lib_arg[2..]);
315 } else {
316 if (fs.path.isAbsolute(lib_arg)) {
317 try result.libs.append(lib_arg);
318 } else {
319 var lib_arg_copy = lib_arg;
320 if (mem.endsWith(u8, lib_arg, ".lib")) {
321 lib_arg_copy = lib_arg[0 .. lib_arg.len - 4];
322 }
323 try result.system_libs.append(lib_arg_copy);
324 }
325 }
326 }
327 }
328 {
329 var it = mem.tokenize(includes_output, " \r\n");
330 while (it.next()) |include_arg| {
331 if (mem.startsWith(u8, include_arg, "-I")) {
332 try result.includes.append(include_arg[2..]);
333 } else {
334 try result.includes.append(include_arg);
335 }
336 }
337 }
338 {
339 var it = mem.tokenize(libdir_output, " \r\n");
340 while (it.next()) |libdir| {
341 if (mem.startsWith(u8, libdir, "-L")) {
342 try result.libdirs.append(libdir[2..]);
343 } else {
344 try result.libdirs.append(libdir);
345 }
346 }
347 }
348 return result;
349}
350
351fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: bool) !void {
352 exe.addIncludeDir("src");
353 exe.addIncludeDir(ctx.cmake_binary_dir);
354 addCppLib(b, exe, ctx.cmake_binary_dir, "zigcpp");
355 assert(ctx.lld_include_dir.len != 0);
356 exe.addIncludeDir(ctx.lld_include_dir);
357 {
358 var it = mem.tokenize(ctx.lld_libraries, ";");
359 while (it.next()) |lib| {
360 exe.addObjectFile(lib);
361 }
362 }
363 {
364 var it = mem.tokenize(ctx.clang_libraries, ";");
365 while (it.next()) |lib| {
366 exe.addObjectFile(lib);
367 }
368 }
369 dependOnLib(b, exe, ctx.llvm);
370
371 // Boy, it sure would be nice to simply linkSystemLibrary("c++") and rely on zig's
372 // ability to provide libc++ right? Well thanks to C++ not having a stable ABI this
373 // will cause linker errors. It would work in the situation when `zig cc` is used to
374 // build LLVM, Clang, and LLD, however when depending on them as system libraries, system
375 // libc++ must be used.
376 const cross_compile = false; // TODO
377 if (cross_compile) {
378 // In this case we assume that zig cc was used to build the LLVM, Clang, LLD dependencies.
379 exe.linkSystemLibrary("c++");
380 } else {
381 if (exe.target.getOsTag() == .linux) {
382 // First we try to static link against gcc libstdc++. If that doesn't work,
383 // we fall back to -lc++ and cross our fingers.
384 addCxxKnownPath(b, ctx, exe, "libstdc++.a", "", need_cpp_includes) catch |err| switch (err) {
385 error.RequiredLibraryNotFound => {
386 exe.linkSystemLibrary("c++");
387 },
388 else => |e| return e,
389 };
390
391 exe.linkSystemLibrary("pthread");
392 } else if (exe.target.isFreeBSD()) {
393 try addCxxKnownPath(b, ctx, exe, "libc++.a", null, need_cpp_includes);
394 exe.linkSystemLibrary("pthread");
395 } else if (exe.target.isDarwin()) {
396 if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "", need_cpp_includes)) {
397 // Compiler is GCC.
398 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
399 exe.linkSystemLibrary("pthread");
400 // TODO LLD cannot perform this link.
401 // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
402 // See https://github.com/ziglang/zig/issues/1535
403 } else |err| switch (err) {
404 error.RequiredLibraryNotFound => {
405 // System compiler, not gcc.
406 exe.linkSystemLibrary("c++");
407 },
408 else => |e| return e,
409 }
410 }
411
412 if (ctx.dia_guids_lib.len != 0) {
413 exe.addObjectFile(ctx.dia_guids_lib);
414 }
415 }
416}
417
418fn addCxxKnownPath(347fn addCxxKnownPath(
419 b: *Builder,348 b: *Builder,
420 ctx: Context,349 ctx: CMakeConfig,
421 exe: anytype,350 exe: *std.build.LibExeObjStep,
422 objname: []const u8,351 objname: []const u8,
423 errtxt: ?[]const u8,352 errtxt: ?[]const u8,
424 need_cpp_includes: bool,353 need_cpp_includes: bool,
...@@ -449,52 +378,64 @@ fn addCxxKnownPath(...@@ -449,52 +378,64 @@ fn addCxxKnownPath(
449 }378 }
450}379}
451380
452const Context = struct {381fn addCMakeLibraryList(exe: *std.build.LibExeObjStep, list: []const u8) void {
382 var it = mem.tokenize(list, ";");
383 while (it.next()) |lib| {
384 if (mem.startsWith(u8, lib, "-l")) {
385 exe.linkSystemLibrary(lib["-l".len..]);
386 } else {
387 exe.addObjectFile(lib);
388 }
389 }
390}
391
392const CMakeConfig = struct {
453 cmake_binary_dir: []const u8,393 cmake_binary_dir: []const u8,
394 cmake_prefix_path: []const u8,
454 cxx_compiler: []const u8,395 cxx_compiler: []const u8,
455 llvm_config_exe: []const u8,
456 lld_include_dir: []const u8,396 lld_include_dir: []const u8,
457 lld_libraries: []const u8,397 lld_libraries: []const u8,
458 clang_libraries: []const u8,398 clang_libraries: []const u8,
399 llvm_libraries: []const u8,
459 dia_guids_lib: []const u8,400 dia_guids_lib: []const u8,
460 llvm: LibraryDep,
461};401};
462402
463const max_config_h_bytes = 1 * 1024 * 1024;403const max_config_h_bytes = 1 * 1024 * 1024;
464404
465fn findAndReadConfigH(b: *Builder) ![]const u8 {405fn findAndParseConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?CMakeConfig {
466 var check_dir = fs.path.dirname(b.zig_exe).?;406 const config_h_text: []const u8 = if (config_h_path_option) |config_h_path| blk: {
467 while (true) {407 break :blk fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable;
468 var dir = try fs.cwd().openDir(check_dir, .{});408 } else blk: {
469 defer dir.close();409 // TODO this should stop looking for config.h once it detects we hit the
470410 // zig source root directory.
471 const config_h_text = dir.readFileAlloc(b.allocator, "config.h", max_config_h_bytes) catch |err| switch (err) {411 var check_dir = fs.path.dirname(b.zig_exe).?;
472 error.FileNotFound => {412 while (true) {
473 const new_check_dir = fs.path.dirname(check_dir);413 var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;
474 if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) {414 defer dir.close();
475 std.debug.warn("Unable to find config.h file relative to Zig executable.\n", .{});415
476 std.debug.warn("`zig build` must be run using a Zig executable within the source tree.\n", .{});416 break :blk dir.readFileAlloc(b.allocator, "config.h", max_config_h_bytes) catch |err| switch (err) {
477 std.process.exit(1);417 error.FileNotFound => {
478 }418 const new_check_dir = fs.path.dirname(check_dir);
479 check_dir = new_check_dir.?;419 if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) {
480 continue;420 return null;
481 },421 }
482 else => |e| return e,422 check_dir = new_check_dir.?;
483 };423 continue;
484 return config_h_text;424 },
485 } else unreachable; // TODO should not need `else unreachable`.425 else => unreachable,
486}426 };
427 } else unreachable; // TODO should not need `else unreachable`.
428 };
487429
488fn parseConfigH(b: *Builder, config_h_text: []const u8) Context {430 var ctx: CMakeConfig = .{
489 var ctx: Context = .{
490 .cmake_binary_dir = undefined,431 .cmake_binary_dir = undefined,
432 .cmake_prefix_path = undefined,
491 .cxx_compiler = undefined,433 .cxx_compiler = undefined,
492 .llvm_config_exe = undefined,
493 .lld_include_dir = undefined,434 .lld_include_dir = undefined,
494 .lld_libraries = undefined,435 .lld_libraries = undefined,
495 .clang_libraries = undefined,436 .clang_libraries = undefined,
437 .llvm_libraries = undefined,
496 .dia_guids_lib = undefined,438 .dia_guids_lib = undefined,
497 .llvm = undefined,
498 };439 };
499440
500 const mappings = [_]struct { prefix: []const u8, field: []const u8 }{441 const mappings = [_]struct { prefix: []const u8, field: []const u8 }{
...@@ -502,6 +443,10 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) Context {...@@ -502,6 +443,10 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) Context {
502 .prefix = "#define ZIG_CMAKE_BINARY_DIR ",443 .prefix = "#define ZIG_CMAKE_BINARY_DIR ",
503 .field = "cmake_binary_dir",444 .field = "cmake_binary_dir",
504 },445 },
446 .{
447 .prefix = "#define ZIG_CMAKE_PREFIX_PATH ",
448 .field = "cmake_prefix_path",
449 },
505 .{450 .{
506 .prefix = "#define ZIG_CXX_COMPILER ",451 .prefix = "#define ZIG_CXX_COMPILER ",
507 .field = "cxx_compiler",452 .field = "cxx_compiler",
...@@ -519,8 +464,8 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) Context {...@@ -519,8 +464,8 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) Context {
519 .field = "clang_libraries",464 .field = "clang_libraries",
520 },465 },
521 .{466 .{
522 .prefix = "#define ZIG_LLVM_CONFIG_EXE ",467 .prefix = "#define ZIG_LLVM_LIBRARIES ",
523 .field = "llvm_config_exe",468 .field = "llvm_libraries",
524 },469 },
525 .{470 .{
526 .prefix = "#define ZIG_DIA_GUIDS_LIB ",471 .prefix = "#define ZIG_DIA_GUIDS_LIB ",
...@@ -550,3 +495,360 @@ fn toNativePathSep(b: *Builder, s: []const u8) []u8 {...@@ -550,3 +495,360 @@ fn toNativePathSep(b: *Builder, s: []const u8) []u8 {
550 };495 };
551 return duplicated;496 return duplicated;
552}497}
498
499const softfloat_sources = [_][]const u8{
500 "deps/SoftFloat-3e/source/8086/f128M_isSignalingNaN.c",
501 "deps/SoftFloat-3e/source/8086/s_commonNaNToF128M.c",
502 "deps/SoftFloat-3e/source/8086/s_commonNaNToF16UI.c",
503 "deps/SoftFloat-3e/source/8086/s_commonNaNToF32UI.c",
504 "deps/SoftFloat-3e/source/8086/s_commonNaNToF64UI.c",
505 "deps/SoftFloat-3e/source/8086/s_f128MToCommonNaN.c",
506 "deps/SoftFloat-3e/source/8086/s_f16UIToCommonNaN.c",
507 "deps/SoftFloat-3e/source/8086/s_f32UIToCommonNaN.c",
508 "deps/SoftFloat-3e/source/8086/s_f64UIToCommonNaN.c",
509 "deps/SoftFloat-3e/source/8086/s_propagateNaNF128M.c",
510 "deps/SoftFloat-3e/source/8086/s_propagateNaNF16UI.c",
511 "deps/SoftFloat-3e/source/8086/softfloat_raiseFlags.c",
512 "deps/SoftFloat-3e/source/f128M_add.c",
513 "deps/SoftFloat-3e/source/f128M_div.c",
514 "deps/SoftFloat-3e/source/f128M_eq.c",
515 "deps/SoftFloat-3e/source/f128M_eq_signaling.c",
516 "deps/SoftFloat-3e/source/f128M_le.c",
517 "deps/SoftFloat-3e/source/f128M_le_quiet.c",
518 "deps/SoftFloat-3e/source/f128M_lt.c",
519 "deps/SoftFloat-3e/source/f128M_lt_quiet.c",
520 "deps/SoftFloat-3e/source/f128M_mul.c",
521 "deps/SoftFloat-3e/source/f128M_mulAdd.c",
522 "deps/SoftFloat-3e/source/f128M_rem.c",
523 "deps/SoftFloat-3e/source/f128M_roundToInt.c",
524 "deps/SoftFloat-3e/source/f128M_sqrt.c",
525 "deps/SoftFloat-3e/source/f128M_sub.c",
526 "deps/SoftFloat-3e/source/f128M_to_f16.c",
527 "deps/SoftFloat-3e/source/f128M_to_f32.c",
528 "deps/SoftFloat-3e/source/f128M_to_f64.c",
529 "deps/SoftFloat-3e/source/f128M_to_i32.c",
530 "deps/SoftFloat-3e/source/f128M_to_i32_r_minMag.c",
531 "deps/SoftFloat-3e/source/f128M_to_i64.c",
532 "deps/SoftFloat-3e/source/f128M_to_i64_r_minMag.c",
533 "deps/SoftFloat-3e/source/f128M_to_ui32.c",
534 "deps/SoftFloat-3e/source/f128M_to_ui32_r_minMag.c",
535 "deps/SoftFloat-3e/source/f128M_to_ui64.c",
536 "deps/SoftFloat-3e/source/f128M_to_ui64_r_minMag.c",
537 "deps/SoftFloat-3e/source/f16_add.c",
538 "deps/SoftFloat-3e/source/f16_div.c",
539 "deps/SoftFloat-3e/source/f16_eq.c",
540 "deps/SoftFloat-3e/source/f16_isSignalingNaN.c",
541 "deps/SoftFloat-3e/source/f16_lt.c",
542 "deps/SoftFloat-3e/source/f16_mul.c",
543 "deps/SoftFloat-3e/source/f16_mulAdd.c",
544 "deps/SoftFloat-3e/source/f16_rem.c",
545 "deps/SoftFloat-3e/source/f16_roundToInt.c",
546 "deps/SoftFloat-3e/source/f16_sqrt.c",
547 "deps/SoftFloat-3e/source/f16_sub.c",
548 "deps/SoftFloat-3e/source/f16_to_f128M.c",
549 "deps/SoftFloat-3e/source/f16_to_f64.c",
550 "deps/SoftFloat-3e/source/f32_to_f128M.c",
551 "deps/SoftFloat-3e/source/f64_to_f128M.c",
552 "deps/SoftFloat-3e/source/f64_to_f16.c",
553 "deps/SoftFloat-3e/source/i32_to_f128M.c",
554 "deps/SoftFloat-3e/source/s_add256M.c",
555 "deps/SoftFloat-3e/source/s_addCarryM.c",
556 "deps/SoftFloat-3e/source/s_addComplCarryM.c",
557 "deps/SoftFloat-3e/source/s_addF128M.c",
558 "deps/SoftFloat-3e/source/s_addM.c",
559 "deps/SoftFloat-3e/source/s_addMagsF16.c",
560 "deps/SoftFloat-3e/source/s_addMagsF32.c",
561 "deps/SoftFloat-3e/source/s_addMagsF64.c",
562 "deps/SoftFloat-3e/source/s_approxRecip32_1.c",
563 "deps/SoftFloat-3e/source/s_approxRecipSqrt32_1.c",
564 "deps/SoftFloat-3e/source/s_approxRecipSqrt_1Ks.c",
565 "deps/SoftFloat-3e/source/s_approxRecip_1Ks.c",
566 "deps/SoftFloat-3e/source/s_compare128M.c",
567 "deps/SoftFloat-3e/source/s_compare96M.c",
568 "deps/SoftFloat-3e/source/s_countLeadingZeros16.c",
569 "deps/SoftFloat-3e/source/s_countLeadingZeros32.c",
570 "deps/SoftFloat-3e/source/s_countLeadingZeros64.c",
571 "deps/SoftFloat-3e/source/s_countLeadingZeros8.c",
572 "deps/SoftFloat-3e/source/s_eq128.c",
573 "deps/SoftFloat-3e/source/s_invalidF128M.c",
574 "deps/SoftFloat-3e/source/s_isNaNF128M.c",
575 "deps/SoftFloat-3e/source/s_le128.c",
576 "deps/SoftFloat-3e/source/s_lt128.c",
577 "deps/SoftFloat-3e/source/s_mul128MTo256M.c",
578 "deps/SoftFloat-3e/source/s_mul64To128M.c",
579 "deps/SoftFloat-3e/source/s_mulAddF128M.c",
580 "deps/SoftFloat-3e/source/s_mulAddF16.c",
581 "deps/SoftFloat-3e/source/s_mulAddF32.c",
582 "deps/SoftFloat-3e/source/s_mulAddF64.c",
583 "deps/SoftFloat-3e/source/s_negXM.c",
584 "deps/SoftFloat-3e/source/s_normRoundPackMToF128M.c",
585 "deps/SoftFloat-3e/source/s_normRoundPackToF16.c",
586 "deps/SoftFloat-3e/source/s_normRoundPackToF32.c",
587 "deps/SoftFloat-3e/source/s_normRoundPackToF64.c",
588 "deps/SoftFloat-3e/source/s_normSubnormalF128SigM.c",
589 "deps/SoftFloat-3e/source/s_normSubnormalF16Sig.c",
590 "deps/SoftFloat-3e/source/s_normSubnormalF32Sig.c",
591 "deps/SoftFloat-3e/source/s_normSubnormalF64Sig.c",
592 "deps/SoftFloat-3e/source/s_remStepMBy32.c",
593 "deps/SoftFloat-3e/source/s_roundMToI64.c",
594 "deps/SoftFloat-3e/source/s_roundMToUI64.c",
595 "deps/SoftFloat-3e/source/s_roundPackMToF128M.c",
596 "deps/SoftFloat-3e/source/s_roundPackToF16.c",
597 "deps/SoftFloat-3e/source/s_roundPackToF32.c",
598 "deps/SoftFloat-3e/source/s_roundPackToF64.c",
599 "deps/SoftFloat-3e/source/s_roundToI32.c",
600 "deps/SoftFloat-3e/source/s_roundToI64.c",
601 "deps/SoftFloat-3e/source/s_roundToUI32.c",
602 "deps/SoftFloat-3e/source/s_roundToUI64.c",
603 "deps/SoftFloat-3e/source/s_shiftLeftM.c",
604 "deps/SoftFloat-3e/source/s_shiftNormSigF128M.c",
605 "deps/SoftFloat-3e/source/s_shiftRightJam256M.c",
606 "deps/SoftFloat-3e/source/s_shiftRightJam32.c",
607 "deps/SoftFloat-3e/source/s_shiftRightJam64.c",
608 "deps/SoftFloat-3e/source/s_shiftRightJamM.c",
609 "deps/SoftFloat-3e/source/s_shiftRightM.c",
610 "deps/SoftFloat-3e/source/s_shortShiftLeft64To96M.c",
611 "deps/SoftFloat-3e/source/s_shortShiftLeftM.c",
612 "deps/SoftFloat-3e/source/s_shortShiftRightExtendM.c",
613 "deps/SoftFloat-3e/source/s_shortShiftRightJam64.c",
614 "deps/SoftFloat-3e/source/s_shortShiftRightJamM.c",
615 "deps/SoftFloat-3e/source/s_shortShiftRightM.c",
616 "deps/SoftFloat-3e/source/s_sub1XM.c",
617 "deps/SoftFloat-3e/source/s_sub256M.c",
618 "deps/SoftFloat-3e/source/s_subM.c",
619 "deps/SoftFloat-3e/source/s_subMagsF16.c",
620 "deps/SoftFloat-3e/source/s_subMagsF32.c",
621 "deps/SoftFloat-3e/source/s_subMagsF64.c",
622 "deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c",
623 "deps/SoftFloat-3e/source/softfloat_state.c",
624 "deps/SoftFloat-3e/source/ui32_to_f128M.c",
625 "deps/SoftFloat-3e/source/ui64_to_f128M.c",
626};
627
628const stage1_sources = [_][]const u8{
629 "src/stage1/analyze.cpp",
630 "src/stage1/ast_render.cpp",
631 "src/stage1/bigfloat.cpp",
632 "src/stage1/bigint.cpp",
633 "src/stage1/buffer.cpp",
634 "src/stage1/codegen.cpp",
635 "src/stage1/dump_analysis.cpp",
636 "src/stage1/errmsg.cpp",
637 "src/stage1/error.cpp",
638 "src/stage1/heap.cpp",
639 "src/stage1/ir.cpp",
640 "src/stage1/ir_print.cpp",
641 "src/stage1/mem.cpp",
642 "src/stage1/os.cpp",
643 "src/stage1/parser.cpp",
644 "src/stage1/range_set.cpp",
645 "src/stage1/stage1.cpp",
646 "src/stage1/target.cpp",
647 "src/stage1/tokenizer.cpp",
648 "src/stage1/util.cpp",
649 "src/stage1/softfloat_ext.cpp",
650};
651const optimized_c_sources = [_][]const u8{
652 "src/stage1/parse_f128.c",
653};
654const zig_cpp_sources = [_][]const u8{
655 // These are planned to stay even when we are self-hosted.
656 "src/zig_llvm.cpp",
657 "src/zig_clang.cpp",
658 "src/zig_clang_driver.cpp",
659 "src/zig_clang_cc1_main.cpp",
660 "src/zig_clang_cc1as_main.cpp",
661 // https://github.com/ziglang/zig/issues/6363
662 "src/windows_sdk.cpp",
663};
664
665const clang_libs = [_][]const u8{
666 "clangFrontendTool",
667 "clangCodeGen",
668 "clangFrontend",
669 "clangDriver",
670 "clangSerialization",
671 "clangSema",
672 "clangStaticAnalyzerFrontend",
673 "clangStaticAnalyzerCheckers",
674 "clangStaticAnalyzerCore",
675 "clangAnalysis",
676 "clangASTMatchers",
677 "clangAST",
678 "clangParse",
679 "clangSema",
680 "clangBasic",
681 "clangEdit",
682 "clangLex",
683 "clangARCMigrate",
684 "clangRewriteFrontend",
685 "clangRewrite",
686 "clangCrossTU",
687 "clangIndex",
688 "clangToolingCore",
689};
690const lld_libs = [_][]const u8{
691 "lldDriver",
692 "lldMinGW",
693 "lldELF",
694 "lldCOFF",
695 "lldMachO",
696 "lldWasm",
697 "lldReaderWriter",
698 "lldCore",
699 "lldYAML",
700 "lldCommon",
701};
702// This list can be re-generated with `llvm-config --libfiles` and then
703// reformatting using your favorite text editor. Note we do not execute
704// `llvm-config` here because we are cross compiling.
705const llvm_libs = [_][]const u8{
706 "LLVMXRay",
707 "LLVMWindowsManifest",
708 "LLVMSymbolize",
709 "LLVMDebugInfoPDB",
710 "LLVMOrcJIT",
711 "LLVMOrcError",
712 "LLVMJITLink",
713 "LLVMObjectYAML",
714 "LLVMMCA",
715 "LLVMLTO",
716 "LLVMPasses",
717 "LLVMCoroutines",
718 "LLVMObjCARCOpts",
719 "LLVMExtensions",
720 "LLVMLineEditor",
721 "LLVMLibDriver",
722 "LLVMInterpreter",
723 "LLVMFuzzMutate",
724 "LLVMMCJIT",
725 "LLVMExecutionEngine",
726 "LLVMRuntimeDyld",
727 "LLVMDWARFLinker",
728 "LLVMDlltoolDriver",
729 "LLVMOption",
730 "LLVMDebugInfoGSYM",
731 "LLVMCoverage",
732 "LLVMXCoreDisassembler",
733 "LLVMXCoreCodeGen",
734 "LLVMXCoreDesc",
735 "LLVMXCoreInfo",
736 "LLVMX86Disassembler",
737 "LLVMX86CodeGen",
738 "LLVMX86AsmParser",
739 "LLVMX86Desc",
740 "LLVMX86Info",
741 "LLVMWebAssemblyDisassembler",
742 "LLVMWebAssemblyCodeGen",
743 "LLVMWebAssemblyDesc",
744 "LLVMWebAssemblyAsmParser",
745 "LLVMWebAssemblyInfo",
746 "LLVMSystemZDisassembler",
747 "LLVMSystemZCodeGen",
748 "LLVMSystemZAsmParser",
749 "LLVMSystemZDesc",
750 "LLVMSystemZInfo",
751 "LLVMSparcDisassembler",
752 "LLVMSparcCodeGen",
753 "LLVMSparcAsmParser",
754 "LLVMSparcDesc",
755 "LLVMSparcInfo",
756 "LLVMRISCVDisassembler",
757 "LLVMRISCVCodeGen",
758 "LLVMRISCVAsmParser",
759 "LLVMRISCVDesc",
760 "LLVMRISCVUtils",
761 "LLVMRISCVInfo",
762 "LLVMPowerPCDisassembler",
763 "LLVMPowerPCCodeGen",
764 "LLVMPowerPCAsmParser",
765 "LLVMPowerPCDesc",
766 "LLVMPowerPCInfo",
767 "LLVMNVPTXCodeGen",
768 "LLVMNVPTXDesc",
769 "LLVMNVPTXInfo",
770 "LLVMMSP430Disassembler",
771 "LLVMMSP430CodeGen",
772 "LLVMMSP430AsmParser",
773 "LLVMMSP430Desc",
774 "LLVMMSP430Info",
775 "LLVMMipsDisassembler",
776 "LLVMMipsCodeGen",
777 "LLVMMipsAsmParser",
778 "LLVMMipsDesc",
779 "LLVMMipsInfo",
780 "LLVMLanaiDisassembler",
781 "LLVMLanaiCodeGen",
782 "LLVMLanaiAsmParser",
783 "LLVMLanaiDesc",
784 "LLVMLanaiInfo",
785 "LLVMHexagonDisassembler",
786 "LLVMHexagonCodeGen",
787 "LLVMHexagonAsmParser",
788 "LLVMHexagonDesc",
789 "LLVMHexagonInfo",
790 "LLVMBPFDisassembler",
791 "LLVMBPFCodeGen",
792 "LLVMBPFAsmParser",
793 "LLVMBPFDesc",
794 "LLVMBPFInfo",
795 "LLVMAVRDisassembler",
796 "LLVMAVRCodeGen",
797 "LLVMAVRAsmParser",
798 "LLVMAVRDesc",
799 "LLVMAVRInfo",
800 "LLVMARMDisassembler",
801 "LLVMARMCodeGen",
802 "LLVMARMAsmParser",
803 "LLVMARMDesc",
804 "LLVMARMUtils",
805 "LLVMARMInfo",
806 "LLVMAMDGPUDisassembler",
807 "LLVMAMDGPUCodeGen",
808 "LLVMMIRParser",
809 "LLVMipo",
810 "LLVMInstrumentation",
811 "LLVMVectorize",
812 "LLVMLinker",
813 "LLVMIRReader",
814 "LLVMAsmParser",
815 "LLVMFrontendOpenMP",
816 "LLVMAMDGPUAsmParser",
817 "LLVMAMDGPUDesc",
818 "LLVMAMDGPUUtils",
819 "LLVMAMDGPUInfo",
820 "LLVMAArch64Disassembler",
821 "LLVMMCDisassembler",
822 "LLVMAArch64CodeGen",
823 "LLVMCFGuard",
824 "LLVMGlobalISel",
825 "LLVMSelectionDAG",
826 "LLVMAsmPrinter",
827 "LLVMDebugInfoDWARF",
828 "LLVMCodeGen",
829 "LLVMTarget",
830 "LLVMScalarOpts",
831 "LLVMInstCombine",
832 "LLVMAggressiveInstCombine",
833 "LLVMTransformUtils",
834 "LLVMBitWriter",
835 "LLVMAnalysis",
836 "LLVMProfileData",
837 "LLVMObject",
838 "LLVMTextAPI",
839 "LLVMBitReader",
840 "LLVMCore",
841 "LLVMRemarks",
842 "LLVMBitstreamReader",
843 "LLVMAArch64AsmParser",
844 "LLVMMCParser",
845 "LLVMAArch64Desc",
846 "LLVMMC",
847 "LLVMDebugInfoCodeView",
848 "LLVMDebugInfoMSF",
849 "LLVMBinaryFormat",
850 "LLVMAArch64Utils",
851 "LLVMAArch64Info",
852 "LLVMSupport",
853 "LLVMDemangle",
854};
lib/std/build.zig+76-4
...@@ -1150,6 +1150,11 @@ const CSourceFile = struct {...@@ -1150,6 +1150,11 @@ const CSourceFile = struct {
1150 args: []const []const u8,1150 args: []const []const u8,
1151};1151};
11521152
1153const CSourceFiles = struct {
1154 files: []const []const u8,
1155 flags: []const []const u8,
1156};
1157
1153fn isLibCLibrary(name: []const u8) bool {1158fn isLibCLibrary(name: []const u8) bool {
1154 const libc_libraries = [_][]const u8{ "c", "m", "dl", "rt", "pthread" };1159 const libc_libraries = [_][]const u8{ "c", "m", "dl", "rt", "pthread" };
1155 for (libc_libraries) |libc_lib_name| {1160 for (libc_libraries) |libc_lib_name| {
...@@ -1297,6 +1302,7 @@ pub const LibExeObjStep = struct {...@@ -1297,6 +1302,7 @@ pub const LibExeObjStep = struct {
1297 SystemLib: []const u8,1302 SystemLib: []const u8,
1298 AssemblyFile: FileSource,1303 AssemblyFile: FileSource,
1299 CSourceFile: *CSourceFile,1304 CSourceFile: *CSourceFile,
1305 CSourceFiles: *CSourceFiles,
1300 };1306 };
13011307
1302 const IncludeDir = union(enum) {1308 const IncludeDir = union(enum) {
...@@ -1670,9 +1676,25 @@ pub const LibExeObjStep = struct {...@@ -1670,9 +1676,25 @@ pub const LibExeObjStep = struct {
1670 self.filter = text;1676 self.filter = text;
1671 }1677 }
16721678
1673 pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, args: []const []const u8) void {1679 /// Handy when you have many C/C++ source files and want them all to have the same flags.
1680 pub fn addCSourceFiles(self: *LibExeObjStep, files: []const []const u8, flags: []const []const u8) void {
1681 const c_source_files = self.builder.allocator.create(CSourceFiles) catch unreachable;
1682
1683 const flags_copy = self.builder.allocator.alloc([]u8, flags.len) catch unreachable;
1684 for (flags) |flag, i| {
1685 flags_copy[i] = self.builder.dupe(flag);
1686 }
1687
1688 c_source_files.* = .{
1689 .files = files,
1690 .flags = flags_copy,
1691 };
1692 self.link_objects.append(LinkObject{ .CSourceFiles = c_source_files }) catch unreachable;
1693 }
1694
1695 pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, flags: []const []const u8) void {
1674 self.addCSourceFileSource(.{1696 self.addCSourceFileSource(.{
1675 .args = args,1697 .args = flags,
1676 .source = .{ .path = file },1698 .source = .{ .path = file },
1677 });1699 });
1678 }1700 }
...@@ -1795,6 +1817,10 @@ pub const LibExeObjStep = struct {...@@ -1795,6 +1817,10 @@ pub const LibExeObjStep = struct {
1795 out.writeAll("};\n") catch unreachable;1817 out.writeAll("};\n") catch unreachable;
1796 return;1818 return;
1797 },1819 },
1820 [:0]const u8 => {
1821 out.print("pub const {z}: [:0]const u8 = \"{Z}\";\n", .{ name, value }) catch unreachable;
1822 return;
1823 },
1798 []const u8 => {1824 []const u8 => {
1799 out.print("pub const {z}: []const u8 = \"{Z}\";\n", .{ name, value }) catch unreachable;1825 out.print("pub const {z}: []const u8 = \"{Z}\";\n", .{ name, value }) catch unreachable;
1800 return;1826 return;
...@@ -1808,6 +1834,22 @@ pub const LibExeObjStep = struct {...@@ -1808,6 +1834,22 @@ pub const LibExeObjStep = struct {
1808 }1834 }
1809 return;1835 return;
1810 },1836 },
1837 std.builtin.Version => {
1838 out.print(
1839 \\pub const {z}: @import("builtin").Version = .{{
1840 \\ .major = {d},
1841 \\ .minor = {d},
1842 \\ .patch = {d},
1843 \\}};
1844 \\
1845 , .{
1846 name,
1847
1848 value.major,
1849 value.minor,
1850 value.patch,
1851 }) catch unreachable;
1852 },
1811 std.SemanticVersion => {1853 std.SemanticVersion => {
1812 out.print(1854 out.print(
1813 \\pub const {z}: @import("std").SemanticVersion = .{{1855 \\pub const {z}: @import("std").SemanticVersion = .{{
...@@ -2015,8 +2057,7 @@ pub const LibExeObjStep = struct {...@@ -2015,8 +2057,7 @@ pub const LibExeObjStep = struct {
2015 },2057 },
2016 },2058 },
2017 .SystemLib => |name| {2059 .SystemLib => |name| {
2018 try zig_args.append("--library");2060 try zig_args.append(builder.fmt("-l{s}", .{name}));
2019 try zig_args.append(name);
2020 },2061 },
2021 .AssemblyFile => |asm_file| {2062 .AssemblyFile => |asm_file| {
2022 if (prev_has_extra_flags) {2063 if (prev_has_extra_flags) {
...@@ -2026,6 +2067,7 @@ pub const LibExeObjStep = struct {...@@ -2026,6 +2067,7 @@ pub const LibExeObjStep = struct {
2026 }2067 }
2027 try zig_args.append(asm_file.getPath(builder));2068 try zig_args.append(asm_file.getPath(builder));
2028 },2069 },
2070
2029 .CSourceFile => |c_source_file| {2071 .CSourceFile => |c_source_file| {
2030 if (c_source_file.args.len == 0) {2072 if (c_source_file.args.len == 0) {
2031 if (prev_has_extra_flags) {2073 if (prev_has_extra_flags) {
...@@ -2042,6 +2084,25 @@ pub const LibExeObjStep = struct {...@@ -2042,6 +2084,25 @@ pub const LibExeObjStep = struct {
2042 }2084 }
2043 try zig_args.append(c_source_file.source.getPath(builder));2085 try zig_args.append(c_source_file.source.getPath(builder));
2044 },2086 },
2087
2088 .CSourceFiles => |c_source_files| {
2089 if (c_source_files.flags.len == 0) {
2090 if (prev_has_extra_flags) {
2091 try zig_args.append("-cflags");
2092 try zig_args.append("--");
2093 prev_has_extra_flags = false;
2094 }
2095 } else {
2096 try zig_args.append("-cflags");
2097 for (c_source_files.flags) |flag| {
2098 try zig_args.append(flag);
2099 }
2100 try zig_args.append("--");
2101 }
2102 for (c_source_files.files) |file| {
2103 try zig_args.append(builder.pathFromRoot(file));
2104 }
2105 },
2045 }2106 }
2046 }2107 }
20472108
...@@ -2304,6 +2365,17 @@ pub const LibExeObjStep = struct {...@@ -2304,6 +2365,17 @@ pub const LibExeObjStep = struct {
2304 }2365 }
2305 }2366 }
23062367
2368 for (builder.search_prefixes.items) |search_prefix| {
2369 try zig_args.append("-L");
2370 try zig_args.append(try fs.path.join(builder.allocator, &[_][]const u8{
2371 search_prefix, "lib",
2372 }));
2373 try zig_args.append("-isystem");
2374 try zig_args.append(try fs.path.join(builder.allocator, &[_][]const u8{
2375 search_prefix, "include",
2376 }));
2377 }
2378
2307 if (self.valgrind_support) |valgrind_support| {2379 if (self.valgrind_support) |valgrind_support| {
2308 if (valgrind_support) {2380 if (valgrind_support) {
2309 try zig_args.append("-fvalgrind");2381 try zig_args.append("-fvalgrind");
src/config.zig.in+7-1
...@@ -1,5 +1,11 @@...@@ -1,5 +1,11 @@
1pub const have_llvm = true;1pub const have_llvm = true;
2pub const version: []const u8 = "@ZIG_VERSION@";2pub const version: [:0]const u8 = "@ZIG_VERSION@";
3pub const semver: @import("std").SemanticVersion = .{
4 .major = @ZIG_VERSION_MAJOR@,
5 .minor = @ZIG_VERSION_MINOR@,
6 .patch = @ZIG_VERSION_PATCH@,
7 .build = "@ZIG_GIT_REV@",
8};
3pub const log_scopes: []const []const u8 = &[_][]const u8{};9pub const log_scopes: []const []const u8 = &[_][]const u8{};
4pub const zir_dumps: []const []const u8 = &[_][]const u8{};10pub const zir_dumps: []const []const u8 = &[_][]const u8{};
5pub const enable_tracy = false;11pub const enable_tracy = false;
src/empty.zig created
src/stage1.zig+14
...@@ -251,6 +251,20 @@ const Error = extern enum {...@@ -251,6 +251,20 @@ const Error = extern enum {
251 Locked,251 Locked,
252};252};
253253
254// ABI warning
255export fn stage2_version_string() [*:0]const u8 {
256 return build_options.version;
257}
258
259// ABI warning
260export fn stage2_version() Stage2SemVer {
261 return .{
262 .major = build_options.semver.major,
263 .minor = build_options.semver.minor,
264 .patch = build_options.semver.patch,
265 };
266}
267
254// ABI warning268// ABI warning
255export fn stage2_attach_segfault_handler() void {269export fn stage2_attach_segfault_handler() void {
256 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {270 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
src/stage1/analyze.cpp-1
...@@ -8,7 +8,6 @@...@@ -8,7 +8,6 @@
8#include "analyze.hpp"8#include "analyze.hpp"
9#include "ast_render.hpp"9#include "ast_render.hpp"
10#include "codegen.hpp"10#include "codegen.hpp"
11#include "config.h"
12#include "error.hpp"11#include "error.hpp"
13#include "ir.hpp"12#include "ir.hpp"
14#include "ir_print.hpp"13#include "ir_print.hpp"
src/stage1/codegen.cpp+6-7
...@@ -8,7 +8,6 @@...@@ -8,7 +8,6 @@
8#include "analyze.hpp"8#include "analyze.hpp"
9#include "ast_render.hpp"9#include "ast_render.hpp"
10#include "codegen.hpp"10#include "codegen.hpp"
11#include "config.h"
12#include "errmsg.hpp"11#include "errmsg.hpp"
13#include "error.hpp"12#include "error.hpp"
14#include "hash_map.hpp"13#include "hash_map.hpp"
...@@ -9051,7 +9050,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -9051,7 +9050,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
9051 buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n");9050 buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n");
9052 buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n");9051 buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n");
9053 buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");9052 buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");
9054 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", ZIG_LINK_MODE);9053 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", ZIG_QUOTE(ZIG_LINK_MODE));
9055 buf_appendf(contents, "pub const is_test = false;\n");9054 buf_appendf(contents, "pub const is_test = false;\n");
9056 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));9055 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
9057 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);9056 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
...@@ -9251,9 +9250,9 @@ static void init(CodeGen *g) {...@@ -9251,9 +9250,9 @@ static void init(CodeGen *g) {
9251 g->builder = LLVMCreateBuilder();9250 g->builder = LLVMCreateBuilder();
9252 g->dbuilder = ZigLLVMCreateDIBuilder(g->module, true);9251 g->dbuilder = ZigLLVMCreateDIBuilder(g->module, true);
92539252
9254 // Don't use ZIG_VERSION_STRING here, llvm misparses it when it includes9253 // Don't use the version string here, llvm misparses it when it includes the git revision.
9255 // the git revision.9254 Stage2SemVer semver = stage2_version();
9256 Buf *producer = buf_sprintf("zig %d.%d.%d", ZIG_VERSION_MAJOR, ZIG_VERSION_MINOR, ZIG_VERSION_PATCH);9255 Buf *producer = buf_sprintf("zig %d.%d.%d", semver.major, semver.minor, semver.patch);
9257 const char *flags = "";9256 const char *flags = "";
9258 unsigned runtime_version = 0;9257 unsigned runtime_version = 0;
92599258
...@@ -9551,9 +9550,9 @@ void codegen_build_object(CodeGen *g) {...@@ -9551,9 +9550,9 @@ void codegen_build_object(CodeGen *g) {
9551 }9550 }
95529551
9553 do_code_gen(g);9552 do_code_gen(g);
9554 codegen_add_time_event(g, "LLVM Emit Output");9553 codegen_add_time_event(g, "LLVM Emit Object");
9555 {9554 {
9556 const char *progress_name = "LLVM Emit Output";9555 const char *progress_name = "LLVM Emit Object";
9557 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,9556 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
9558 progress_name, strlen(progress_name), 0));9557 progress_name, strlen(progress_name), 0));
9559 }9558 }
src/stage1/config.h.in+4-3
...@@ -8,19 +8,20 @@...@@ -8,19 +8,20 @@
8#ifndef ZIG_CONFIG_H8#ifndef ZIG_CONFIG_H
9#define ZIG_CONFIG_H9#define ZIG_CONFIG_H
1010
11// Used by zig0.cpp
11#define ZIG_VERSION_MAJOR @ZIG_VERSION_MAJOR@12#define ZIG_VERSION_MAJOR @ZIG_VERSION_MAJOR@
12#define ZIG_VERSION_MINOR @ZIG_VERSION_MINOR@13#define ZIG_VERSION_MINOR @ZIG_VERSION_MINOR@
13#define ZIG_VERSION_PATCH @ZIG_VERSION_PATCH@14#define ZIG_VERSION_PATCH @ZIG_VERSION_PATCH@
14#define ZIG_VERSION_STRING "@ZIG_VERSION@"15#define ZIG_VERSION_STRING "@ZIG_VERSION@"
1516
16// Used for communicating build information to self hosted build.17// Used by build.zig for communicating build information to self hosted build.
17#define ZIG_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@"18#define ZIG_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@"
19#define ZIG_CMAKE_PREFIX_PATH "@CMAKE_PREFIX_PATH@"
18#define ZIG_CXX_COMPILER "@CMAKE_CXX_COMPILER@"20#define ZIG_CXX_COMPILER "@CMAKE_CXX_COMPILER@"
19#define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@"21#define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@"
20#define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@"22#define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@"
21#define ZIG_CLANG_LIBRARIES "@CLANG_LIBRARIES@"23#define ZIG_CLANG_LIBRARIES "@CLANG_LIBRARIES@"
22#define ZIG_LLVM_CONFIG_EXE "@LLVM_CONFIG_EXE@"24#define ZIG_LLVM_LIBRARIES "@LLVM_LIBRARIES@"
23#define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"25#define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"
24#define ZIG_LINK_MODE "@ZIG_LINK_MODE@"
2526
26#endif27#endif
src/stage1/dump_analysis.cpp+1-2
...@@ -7,7 +7,6 @@...@@ -7,7 +7,6 @@
77
8#include "dump_analysis.hpp"8#include "dump_analysis.hpp"
9#include "analyze.hpp"9#include "analyze.hpp"
10#include "config.h"
11#include "ir.hpp"10#include "ir.hpp"
12#include "codegen.hpp"11#include "codegen.hpp"
13#include "os.hpp"12#include "os.hpp"
...@@ -1237,7 +1236,7 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const...@@ -1237,7 +1236,7 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
1237 jw_begin_object(jw);1236 jw_begin_object(jw);
1238 {1237 {
1239 jw_object_field(jw, "zigVersion");1238 jw_object_field(jw, "zigVersion");
1240 jw_string(jw, ZIG_VERSION_STRING);1239 jw_string(jw, stage2_version_string());
12411240
1242 jw_object_field(jw, "builds");1241 jw_object_field(jw, "builds");
1243 jw_begin_array(jw);1242 jw_begin_array(jw);
src/stage1/heap.cpp-1
...@@ -8,7 +8,6 @@...@@ -8,7 +8,6 @@
8#include <new>8#include <new>
9#include <string.h>9#include <string.h>
1010
11#include "config.h"
12#include "heap.hpp"11#include "heap.hpp"
1312
14namespace heap {13namespace heap {
src/stage1/heap.hpp-1
...@@ -8,7 +8,6 @@...@@ -8,7 +8,6 @@
8#ifndef ZIG_HEAP_HPP8#ifndef ZIG_HEAP_HPP
9#define ZIG_HEAP_HPP9#define ZIG_HEAP_HPP
1010
11#include "config.h"
12#include "util_base.hpp"11#include "util_base.hpp"
13#include "mem.hpp"12#include "mem.hpp"
1413
src/stage1/mem.cpp-1
...@@ -5,7 +5,6 @@...@@ -5,7 +5,6 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8#include "config.h"
9#include "mem.hpp"8#include "mem.hpp"
10#include "heap.hpp"9#include "heap.hpp"
1110
src/stage1/mem.hpp-1
...@@ -12,7 +12,6 @@...@@ -12,7 +12,6 @@
12#include <stdio.h>12#include <stdio.h>
13#include <stdlib.h>13#include <stdlib.h>
1414
15#include "config.h"
16#include "util_base.hpp"15#include "util_base.hpp"
17#include "mem_type_info.hpp"16#include "mem_type_info.hpp"
1817
src/stage1/mem_type_info.hpp-2
...@@ -8,8 +8,6 @@...@@ -8,8 +8,6 @@
8#ifndef ZIG_MEM_TYPE_INFO_HPP8#ifndef ZIG_MEM_TYPE_INFO_HPP
9#define ZIG_MEM_TYPE_INFO_HPP9#define ZIG_MEM_TYPE_INFO_HPP
1010
11#include "config.h"
12
13namespace mem {11namespace mem {
1412
15struct TypeInfo {13struct TypeInfo {
src/stage1/stage2.h+6
...@@ -156,6 +156,12 @@ struct Stage2SemVer {...@@ -156,6 +156,12 @@ struct Stage2SemVer {
156 uint32_t patch;156 uint32_t patch;
157};157};
158158
159// ABI warning
160ZIG_EXTERN_C const char *stage2_version_string(void);
161
162// ABI warning
163ZIG_EXTERN_C Stage2SemVer stage2_version(void);
164
159// ABI warning165// ABI warning
160ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu,166ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu,
161 const char *dynamic_linker);167 const char *dynamic_linker);
src/stage1/util.hpp+3-1
...@@ -17,7 +17,9 @@...@@ -17,7 +17,9 @@
17#include <intrin.h> 17#include <intrin.h>
18#endif18#endif
1919
20#include "config.h"20#define ZIG_Q(x) #x
21#define ZIG_QUOTE(x) ZIG_Q(x)
22
21#include "util_base.hpp"23#include "util_base.hpp"
22#include "heap.hpp"24#include "heap.hpp"
23#include "mem.hpp"25#include "mem.hpp"
src/stage1/zig0.cpp+13
...@@ -18,6 +18,11 @@...@@ -18,6 +18,11 @@
18#include "buffer.hpp"18#include "buffer.hpp"
19#include "os.hpp"19#include "os.hpp"
2020
21// This is the only file allowed to include config.h because config.h is
22// only produced when building with cmake. When using the zig build system,
23// zig0.cpp is never touched.
24#include "config.h"
25
21#include <stdio.h>26#include <stdio.h>
22#include <string.h>27#include <string.h>
2328
...@@ -537,3 +542,11 @@ const char *stage2_add_link_lib(struct ZigStage1 *stage1,...@@ -537,3 +542,11 @@ const char *stage2_add_link_lib(struct ZigStage1 *stage1,
537{542{
538 return nullptr;543 return nullptr;
539}544}
545
546const char *stage2_version_string(void) {
547 return ZIG_VERSION_STRING;
548}
549
550struct Stage2SemVer stage2_version(void) {
551 return {ZIG_VERSION_MAJOR, ZIG_VERSION_MINOR, ZIG_VERSION_PATCH};
552}
src/zig_clang.h+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8#ifndef ZIG_ZIG_CLANG_H8#ifndef ZIG_ZIG_CLANG_H
9#define ZIG_ZIG_CLANG_H9#define ZIG_ZIG_CLANG_H
1010
11#include "stage2.h"11#include "stage1/stage2.h"
12#include <inttypes.h>12#include <inttypes.h>
13#include <stdbool.h>13#include <stdbool.h>
1414