stage2: implement building & linking against libcxx and libcxxabi
This commit is contained in:
parent
974333faaf
commit
877e4248fc
@ -1,4 +1,3 @@
|
||||
* build & link against libcxx and libcxxabi
|
||||
* `zig build`
|
||||
* repair @cImport
|
||||
* make sure zig cc works
|
||||
|
@ -16,6 +16,7 @@ const build_options = @import("build_options");
|
||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
const glibc = @import("glibc.zig");
|
||||
const libunwind = @import("libunwind.zig");
|
||||
const libcxx = @import("libcxx.zig");
|
||||
const fatal = @import("main.zig").fatal;
|
||||
const Module = @import("Module.zig");
|
||||
const Cache = @import("Cache.zig");
|
||||
@ -69,10 +70,10 @@ rand: *std.rand.Random,
|
||||
|
||||
/// Populated when we build the libc++ static library. A Job to build this is placed in the queue
|
||||
/// and resolved before calling linker.flush().
|
||||
libcxx_static_lib: ?[]const u8 = null,
|
||||
libcxx_static_lib: ?CRTFile = null,
|
||||
/// Populated when we build the libc++abi static library. A Job to build this is placed in the queue
|
||||
/// and resolved before calling linker.flush().
|
||||
libcxxabi_static_lib: ?[]const u8 = null,
|
||||
libcxxabi_static_lib: ?CRTFile = null,
|
||||
/// Populated when we build the libunwind static library. A Job to build this is placed in the queue
|
||||
/// and resolved before calling linker.flush().
|
||||
libunwind_static_lib: ?CRTFile = null,
|
||||
@ -140,6 +141,8 @@ const Job = union(enum) {
|
||||
glibc_shared_objects,
|
||||
/// libunwind.a, usually needed when linking libc
|
||||
libunwind: void,
|
||||
libcxx: void,
|
||||
libcxxabi: void,
|
||||
/// needed when producing a dynamic library or executable
|
||||
libcompiler_rt: void,
|
||||
/// needed when not linking libc and using LLVM for code generation because it generates
|
||||
@ -770,10 +773,18 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
if (comp.wantBuildLibUnwindFromSource()) {
|
||||
try comp.work_queue.writeItem(.{ .libunwind = {} });
|
||||
}
|
||||
if (build_options.have_llvm and comp.bin_file.options.output_mode != .Obj and
|
||||
comp.bin_file.options.link_libcpp)
|
||||
{
|
||||
try comp.work_queue.writeItem(.libcxx);
|
||||
try comp.work_queue.writeItem(.libcxxabi);
|
||||
}
|
||||
if (build_options.is_stage1 and comp.bin_file.options.use_llvm) {
|
||||
try comp.work_queue.writeItem(.{ .stage1_module = {} });
|
||||
}
|
||||
if (is_exe_or_dyn_lib and comp.bin_file.options.use_llvm) {
|
||||
if (is_exe_or_dyn_lib and !comp.bin_file.options.is_compiler_rt_or_libc and
|
||||
build_options.is_stage1)
|
||||
{
|
||||
try comp.work_queue.writeItem(.{ .libcompiler_rt = {} });
|
||||
if (!comp.bin_file.options.link_libc) {
|
||||
try comp.work_queue.writeItem(.{ .zig_libc = {} });
|
||||
@ -811,6 +822,12 @@ pub fn destroy(self: *Compilation) void {
|
||||
if (self.libunwind_static_lib) |*crt_file| {
|
||||
crt_file.deinit(gpa);
|
||||
}
|
||||
if (self.libcxx_static_lib) |*crt_file| {
|
||||
crt_file.deinit(gpa);
|
||||
}
|
||||
if (self.libcxxabi_static_lib) |*crt_file| {
|
||||
crt_file.deinit(gpa);
|
||||
}
|
||||
if (self.compiler_rt_static_lib) |*crt_file| {
|
||||
crt_file.deinit(gpa);
|
||||
}
|
||||
@ -1109,6 +1126,18 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
|
||||
fatal("unable to build libunwind: {}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.libcxx => {
|
||||
libcxx.buildLibCXX(self) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build libcxx: {}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.libcxxabi => {
|
||||
libcxx.buildLibCXXABI(self) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
fatal("unable to build libcxxabi: {}", .{@errorName(err)});
|
||||
};
|
||||
},
|
||||
.libcompiler_rt => {
|
||||
self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {
|
||||
// TODO Expose this as a normal compile error rather than crashing here.
|
||||
|
239
src/libcxx.zig
239
src/libcxx.zig
@ -1,6 +1,13 @@
|
||||
//! TODO build libcxx and libcxxabi from source
|
||||
const std = @import("std");
|
||||
const path = std.fs.path;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
pub const libcxxabi_files = [_][]const u8{
|
||||
const target_util = @import("target.zig");
|
||||
const Compilation = @import("Compilation.zig");
|
||||
const build_options = @import("build_options");
|
||||
const trace = @import("tracy.zig").trace;
|
||||
|
||||
const libcxxabi_files = [_][]const u8{
|
||||
"src/abort_message.cpp",
|
||||
"src/cxa_aux_runtime.cpp",
|
||||
"src/cxa_default_handlers.cpp",
|
||||
@ -22,7 +29,7 @@ pub const libcxxabi_files = [_][]const u8{
|
||||
"src/stdlib_typeinfo.cpp",
|
||||
};
|
||||
|
||||
pub const libcxx_files = [_][]const u8{
|
||||
const libcxx_files = [_][]const u8{
|
||||
"src/algorithm.cpp",
|
||||
"src/any.cpp",
|
||||
"src/bind.cpp",
|
||||
@ -64,3 +71,229 @@ pub const libcxx_files = [_][]const u8{
|
||||
"src/variant.cpp",
|
||||
"src/vector.cpp",
|
||||
};
|
||||
|
||||
pub fn buildLibCXX(comp: *Compilation) !void {
|
||||
if (!build_options.have_llvm) {
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = &arena_allocator.allocator;
|
||||
|
||||
const root_name = "c++";
|
||||
const output_mode = .Lib;
|
||||
const link_mode = .Static;
|
||||
const target = comp.getTarget();
|
||||
const basename = try std.zig.binNameAlloc(arena, root_name, target, output_mode, link_mode, null);
|
||||
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = basename,
|
||||
};
|
||||
|
||||
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
|
||||
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
|
||||
var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);
|
||||
try c_source_files.ensureCapacity(libcxx_files.len);
|
||||
|
||||
for (libcxx_files) |cxx_src| {
|
||||
var cflags = std.ArrayList([]const u8).init(arena);
|
||||
|
||||
if (target.os.tag == .windows) {
|
||||
// Filesystem stuff isn't supported on Windows.
|
||||
if (std.mem.startsWith(u8, cxx_src, "src/filesystem/"))
|
||||
continue;
|
||||
} else {
|
||||
if (std.mem.startsWith(u8, cxx_src, "src/support/win32/"))
|
||||
continue;
|
||||
}
|
||||
|
||||
try cflags.append("-DNDEBUG");
|
||||
try cflags.append("-D_LIBCPP_BUILDING_LIBRARY");
|
||||
try cflags.append("-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER");
|
||||
try cflags.append("-DLIBCXX_BUILDING_LIBCXXABI");
|
||||
try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
try cflags.append("-D_LIBCPP_HAS_MUSL_LIBC");
|
||||
}
|
||||
|
||||
try cflags.append("-I");
|
||||
try cflags.append(cxx_include_path);
|
||||
|
||||
try cflags.append("-I");
|
||||
try cflags.append(cxxabi_include_path);
|
||||
|
||||
try cflags.append("-O3");
|
||||
try cflags.append("-DNDEBUG");
|
||||
if (target_util.supports_fpic(target)) {
|
||||
try cflags.append("-fPIC");
|
||||
}
|
||||
try cflags.append("-nostdinc++");
|
||||
try cflags.append("-fvisibility-inlines-hidden");
|
||||
try cflags.append("-std=c++14");
|
||||
try cflags.append("-Wno-user-defined-literals");
|
||||
|
||||
c_source_files.appendAssumeCapacity(.{
|
||||
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }),
|
||||
.extra_flags = cflags.items,
|
||||
});
|
||||
}
|
||||
|
||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||
// TODO use the global cache directory here
|
||||
.zig_cache_directory = comp.zig_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.target = target,
|
||||
.root_name = root_name,
|
||||
.root_pkg = null,
|
||||
.output_mode = output_mode,
|
||||
.rand = comp.rand,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
.optimize_mode = comp.bin_file.options.optimize_mode,
|
||||
.link_mode = link_mode,
|
||||
.want_sanitize_c = false,
|
||||
.want_stack_check = false,
|
||||
.want_valgrind = false,
|
||||
.want_pic = comp.bin_file.options.pic,
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = c_source_files.items,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_tokenize = comp.verbose_tokenize,
|
||||
.verbose_ast = comp.verbose_ast,
|
||||
.verbose_ir = comp.verbose_ir,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.link_libc = true,
|
||||
});
|
||||
defer sub_compilation.destroy();
|
||||
|
||||
try sub_compilation.updateSubCompilation();
|
||||
|
||||
assert(comp.libcxx_static_lib == null);
|
||||
comp.libcxx_static_lib = Compilation.CRTFile{
|
||||
.full_object_path = try sub_compilation.bin_file.options.directory.join(comp.gpa, &[_][]const u8{basename}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn buildLibCXXABI(comp: *Compilation) !void {
|
||||
if (!build_options.have_llvm) {
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = &arena_allocator.allocator;
|
||||
|
||||
const root_name = "c++abi";
|
||||
const output_mode = .Lib;
|
||||
const link_mode = .Static;
|
||||
const target = comp.getTarget();
|
||||
const basename = try std.zig.binNameAlloc(arena, root_name, target, output_mode, link_mode, null);
|
||||
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = basename,
|
||||
};
|
||||
|
||||
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
|
||||
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
|
||||
|
||||
var c_source_files: [libcxxabi_files.len]Compilation.CSourceFile = undefined;
|
||||
for (libcxxabi_files) |cxxabi_src, i| {
|
||||
var cflags = std.ArrayList([]const u8).init(arena);
|
||||
|
||||
try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL");
|
||||
try cflags.append("-D_LIBCPP_DISABLE_EXTERN_TEMPLATE");
|
||||
try cflags.append("-D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS");
|
||||
try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY");
|
||||
try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
try cflags.append("-D_LIBCPP_HAS_MUSL_LIBC");
|
||||
}
|
||||
|
||||
try cflags.append("-I");
|
||||
try cflags.append(cxxabi_include_path);
|
||||
|
||||
try cflags.append("-I");
|
||||
try cflags.append(cxx_include_path);
|
||||
|
||||
try cflags.append("-O3");
|
||||
try cflags.append("-DNDEBUG");
|
||||
if (target_util.supports_fpic(target)) {
|
||||
try cflags.append("-fPIC");
|
||||
}
|
||||
try cflags.append("-nostdinc++");
|
||||
try cflags.append("-fstrict-aliasing");
|
||||
try cflags.append("-funwind-tables");
|
||||
try cflags.append("-D_DEBUG");
|
||||
try cflags.append("-UNDEBUG");
|
||||
try cflags.append("-std=c++11");
|
||||
|
||||
c_source_files[i] = .{
|
||||
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }),
|
||||
.extra_flags = cflags.items,
|
||||
};
|
||||
}
|
||||
|
||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||
// TODO use the global cache directory here
|
||||
.zig_cache_directory = comp.zig_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.target = target,
|
||||
.root_name = root_name,
|
||||
.root_pkg = null,
|
||||
.output_mode = output_mode,
|
||||
.rand = comp.rand,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
.optimize_mode = comp.bin_file.options.optimize_mode,
|
||||
.link_mode = link_mode,
|
||||
.want_sanitize_c = false,
|
||||
.want_stack_check = false,
|
||||
.want_valgrind = false,
|
||||
.want_pic = comp.bin_file.options.pic,
|
||||
.emit_h = null,
|
||||
.strip = comp.bin_file.options.strip,
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.c_source_files = &c_source_files,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_tokenize = comp.verbose_tokenize,
|
||||
.verbose_ast = comp.verbose_ast,
|
||||
.verbose_ir = comp.verbose_ir,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.link_libc = true,
|
||||
});
|
||||
defer sub_compilation.destroy();
|
||||
|
||||
try sub_compilation.updateSubCompilation();
|
||||
|
||||
assert(comp.libcxxabi_static_lib == null);
|
||||
comp.libcxxabi_static_lib = Compilation.CRTFile{
|
||||
.full_object_path = try sub_compilation.bin_file.options.directory.join(comp.gpa, &[_][]const u8{basename}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
};
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ const build_options = @import("build_options");
|
||||
const trace = @import("tracy.zig").trace;
|
||||
|
||||
pub fn buildStaticLib(comp: *Compilation) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (!build_options.have_llvm) {
|
||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||
}
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = &arena_allocator.allocator;
|
||||
|
@ -1513,8 +1513,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
if (!is_obj) {
|
||||
// libc++ dep
|
||||
if (self.base.options.link_libcpp) {
|
||||
try argv.append(comp.libcxxabi_static_lib.?);
|
||||
try argv.append(comp.libcxx_static_lib.?);
|
||||
try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
|
||||
try argv.append(comp.libcxx_static_lib.?.full_object_path);
|
||||
}
|
||||
|
||||
// libc dep
|
||||
|
Loading…
x
Reference in New Issue
Block a user