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`
|
* `zig build`
|
||||||
* repair @cImport
|
* repair @cImport
|
||||||
* make sure zig cc works
|
* make sure zig cc works
|
||||||
|
@ -16,6 +16,7 @@ const build_options = @import("build_options");
|
|||||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||||
const glibc = @import("glibc.zig");
|
const glibc = @import("glibc.zig");
|
||||||
const libunwind = @import("libunwind.zig");
|
const libunwind = @import("libunwind.zig");
|
||||||
|
const libcxx = @import("libcxx.zig");
|
||||||
const fatal = @import("main.zig").fatal;
|
const fatal = @import("main.zig").fatal;
|
||||||
const Module = @import("Module.zig");
|
const Module = @import("Module.zig");
|
||||||
const Cache = @import("Cache.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
|
/// Populated when we build the libc++ static library. A Job to build this is placed in the queue
|
||||||
/// and resolved before calling linker.flush().
|
/// 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
|
/// 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().
|
/// 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
|
/// Populated when we build the libunwind static library. A Job to build this is placed in the queue
|
||||||
/// and resolved before calling linker.flush().
|
/// and resolved before calling linker.flush().
|
||||||
libunwind_static_lib: ?CRTFile = null,
|
libunwind_static_lib: ?CRTFile = null,
|
||||||
@ -140,6 +141,8 @@ const Job = union(enum) {
|
|||||||
glibc_shared_objects,
|
glibc_shared_objects,
|
||||||
/// libunwind.a, usually needed when linking libc
|
/// libunwind.a, usually needed when linking libc
|
||||||
libunwind: void,
|
libunwind: void,
|
||||||
|
libcxx: void,
|
||||||
|
libcxxabi: void,
|
||||||
/// needed when producing a dynamic library or executable
|
/// needed when producing a dynamic library or executable
|
||||||
libcompiler_rt: void,
|
libcompiler_rt: void,
|
||||||
/// needed when not linking libc and using LLVM for code generation because it generates
|
/// 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()) {
|
if (comp.wantBuildLibUnwindFromSource()) {
|
||||||
try comp.work_queue.writeItem(.{ .libunwind = {} });
|
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) {
|
if (build_options.is_stage1 and comp.bin_file.options.use_llvm) {
|
||||||
try comp.work_queue.writeItem(.{ .stage1_module = {} });
|
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 = {} });
|
try comp.work_queue.writeItem(.{ .libcompiler_rt = {} });
|
||||||
if (!comp.bin_file.options.link_libc) {
|
if (!comp.bin_file.options.link_libc) {
|
||||||
try comp.work_queue.writeItem(.{ .zig_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| {
|
if (self.libunwind_static_lib) |*crt_file| {
|
||||||
crt_file.deinit(gpa);
|
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| {
|
if (self.compiler_rt_static_lib) |*crt_file| {
|
||||||
crt_file.deinit(gpa);
|
crt_file.deinit(gpa);
|
||||||
}
|
}
|
||||||
@ -1109,6 +1126,18 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
|
|||||||
fatal("unable to build libunwind: {}", .{@errorName(err)});
|
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 => {
|
.libcompiler_rt => {
|
||||||
self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {
|
self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {
|
||||||
// TODO Expose this as a normal compile error rather than crashing here.
|
// 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/abort_message.cpp",
|
||||||
"src/cxa_aux_runtime.cpp",
|
"src/cxa_aux_runtime.cpp",
|
||||||
"src/cxa_default_handlers.cpp",
|
"src/cxa_default_handlers.cpp",
|
||||||
@ -22,7 +29,7 @@ pub const libcxxabi_files = [_][]const u8{
|
|||||||
"src/stdlib_typeinfo.cpp",
|
"src/stdlib_typeinfo.cpp",
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const libcxx_files = [_][]const u8{
|
const libcxx_files = [_][]const u8{
|
||||||
"src/algorithm.cpp",
|
"src/algorithm.cpp",
|
||||||
"src/any.cpp",
|
"src/any.cpp",
|
||||||
"src/bind.cpp",
|
"src/bind.cpp",
|
||||||
@ -64,3 +71,229 @@ pub const libcxx_files = [_][]const u8{
|
|||||||
"src/variant.cpp",
|
"src/variant.cpp",
|
||||||
"src/vector.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;
|
const trace = @import("tracy.zig").trace;
|
||||||
|
|
||||||
pub fn buildStaticLib(comp: *Compilation) !void {
|
pub fn buildStaticLib(comp: *Compilation) !void {
|
||||||
const tracy = trace(@src());
|
|
||||||
defer tracy.end();
|
|
||||||
|
|
||||||
if (!build_options.have_llvm) {
|
if (!build_options.have_llvm) {
|
||||||
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
return error.ZigCompilerNotBuiltWithLLVMExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||||
defer arena_allocator.deinit();
|
defer arena_allocator.deinit();
|
||||||
const arena = &arena_allocator.allocator;
|
const arena = &arena_allocator.allocator;
|
||||||
|
@ -1513,8 +1513,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
|||||||
if (!is_obj) {
|
if (!is_obj) {
|
||||||
// libc++ dep
|
// libc++ dep
|
||||||
if (self.base.options.link_libcpp) {
|
if (self.base.options.link_libcpp) {
|
||||||
try argv.append(comp.libcxxabi_static_lib.?);
|
try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
|
||||||
try argv.append(comp.libcxx_static_lib.?);
|
try argv.append(comp.libcxx_static_lib.?.full_object_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// libc dep
|
// libc dep
|
||||||
|
Loading…
x
Reference in New Issue
Block a user