aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig238
1 files changed, 10 insertions, 228 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 4f4c5f46ef..58413f7c9e 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -19,7 +19,7 @@ const link = @import("link.zig");
const tracy = @import("tracy.zig");
const trace = tracy.trace;
const build_options = @import("build_options");
-const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
+const LibCInstallation = std.zig.LibCInstallation;
const glibc = @import("glibc.zig");
const musl = @import("musl.zig");
const mingw = @import("mingw.zig");
@@ -1232,7 +1232,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
const link_libc = options.config.link_libc;
- const libc_dirs = try detectLibCIncludeDirs(
+ const libc_dirs = try std.zig.LibCDirs.detect(
arena,
options.zig_lib_directory.path.?,
options.root_mod.resolved_target.result,
@@ -1250,7 +1250,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
// only relevant differences would be things like `#define` constants being
// different in the MinGW headers vs the MSVC headers, but any such
// differences would likely be a MinGW bug.
- const rc_dirs = b: {
+ const rc_dirs: std.zig.LibCDirs = b: {
// Set the includes to .none here when there are no rc files to compile
var includes = if (options.rc_source_files.len > 0) options.rc_includes else .none;
const target = options.root_mod.resolved_target.result;
@@ -1265,7 +1265,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
}
}
while (true) switch (includes) {
- .any, .msvc => break :b detectLibCIncludeDirs(
+ .any, .msvc => break :b std.zig.LibCDirs.detect(
arena,
options.zig_lib_directory.path.?,
.{
@@ -1287,13 +1287,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
}
return err;
},
- .gnu => break :b try detectLibCFromBuilding(arena, options.zig_lib_directory.path.?, .{
+ .gnu => break :b try std.zig.LibCDirs.detectFromBuilding(arena, options.zig_lib_directory.path.?, .{
.cpu = target.cpu,
.os = target.os,
.abi = .gnu,
.ofmt = target.ofmt,
}),
- .none => break :b LibCDirs{
+ .none => break :b .{
.libc_include_dir_list = &[0][]u8{},
.libc_installation = null,
.libc_framework_dir_list = &.{},
@@ -1772,7 +1772,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
// If we need to build glibc for the target, add work items for it.
// We go through the work queue so that building can be done in parallel.
if (comp.wantBuildGLibCFromSource()) {
- if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
+ if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
if (glibc.needsCrtiCrtn(target)) {
try comp.work_queue.write(&[_]Job{
@@ -1787,7 +1787,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
});
}
if (comp.wantBuildMuslFromSource()) {
- if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
+ if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
try comp.work_queue.ensureUnusedCapacity(6);
if (musl.needsCrtiCrtn(target)) {
@@ -1808,7 +1808,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
}
if (comp.wantBuildWasiLibcFromSource()) {
- if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
+ if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
// worst-case we need all components
try comp.work_queue.ensureUnusedCapacity(comp.wasi_emulated_libs.len + 2);
@@ -1825,7 +1825,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
}
if (comp.wantBuildMinGWFromSource()) {
- if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
+ if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };
try comp.work_queue.ensureUnusedCapacity(2);
@@ -5830,224 +5830,6 @@ test "classifyFileExt" {
try std.testing.expectEqual(FileExt.zig, classifyFileExt("foo.zig"));
}
-const LibCDirs = struct {
- libc_include_dir_list: []const []const u8,
- libc_installation: ?*const LibCInstallation,
- libc_framework_dir_list: []const []const u8,
- sysroot: ?[]const u8,
- darwin_sdk_layout: ?link.File.MachO.SdkLayout,
-};
-
-fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8) !LibCDirs {
- const s = std.fs.path.sep_str;
- const list = try arena.alloc([]const u8, 1);
- list[0] = try std.fmt.allocPrint(
- arena,
- "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-macos-any",
- .{zig_lib_dir},
- );
- return LibCDirs{
- .libc_include_dir_list = list,
- .libc_installation = null,
- .libc_framework_dir_list = &.{},
- .sysroot = null,
- .darwin_sdk_layout = .vendored,
- };
-}
-
-pub fn detectLibCIncludeDirs(
- arena: Allocator,
- zig_lib_dir: []const u8,
- target: Target,
- is_native_abi: bool,
- link_libc: bool,
- libc_installation: ?*const LibCInstallation,
-) !LibCDirs {
- if (!link_libc) {
- return LibCDirs{
- .libc_include_dir_list = &[0][]u8{},
- .libc_installation = null,
- .libc_framework_dir_list = &.{},
- .sysroot = null,
- .darwin_sdk_layout = null,
- };
- }
-
- if (libc_installation) |lci| {
- return detectLibCFromLibCInstallation(arena, target, lci);
- }
-
- // If linking system libraries and targeting the native abi, default to
- // using the system libc installation.
- if (is_native_abi and !target.isMinGW()) {
- const libc = try arena.create(LibCInstallation);
- libc.* = LibCInstallation.findNative(.{ .allocator = arena, .target = target }) catch |err| switch (err) {
- error.CCompilerExitCode,
- error.CCompilerCrashed,
- error.CCompilerCannotFindHeaders,
- error.UnableToSpawnCCompiler,
- error.DarwinSdkNotFound,
- => |e| {
- // We tried to integrate with the native system C compiler,
- // however, it is not installed. So we must rely on our bundled
- // libc files.
- if (target_util.canBuildLibC(target)) {
- return detectLibCFromBuilding(arena, zig_lib_dir, target);
- }
- return e;
- },
- else => |e| return e,
- };
- return detectLibCFromLibCInstallation(arena, target, libc);
- }
-
- // If not linking system libraries, build and provide our own libc by
- // default if possible.
- if (target_util.canBuildLibC(target)) {
- return detectLibCFromBuilding(arena, zig_lib_dir, target);
- }
-
- // If zig can't build the libc for the target and we are targeting the
- // native abi, fall back to using the system libc installation.
- // On windows, instead of the native (mingw) abi, we want to check
- // for the MSVC abi as a fallback.
- const use_system_abi = if (builtin.target.os.tag == .windows)
- target.abi == .msvc
- else
- is_native_abi;
-
- if (use_system_abi) {
- const libc = try arena.create(LibCInstallation);
- libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, .target = target });
- return detectLibCFromLibCInstallation(arena, target, libc);
- }
-
- return LibCDirs{
- .libc_include_dir_list = &[0][]u8{},
- .libc_installation = null,
- .libc_framework_dir_list = &.{},
- .sysroot = null,
- .darwin_sdk_layout = null,
- };
-}
-
-fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const LibCInstallation) !LibCDirs {
- var list = try std.ArrayList([]const u8).initCapacity(arena, 5);
- var framework_list = std.ArrayList([]const u8).init(arena);
-
- list.appendAssumeCapacity(lci.include_dir.?);
-
- const is_redundant = mem.eql(u8, lci.sys_include_dir.?, lci.include_dir.?);
- if (!is_redundant) list.appendAssumeCapacity(lci.sys_include_dir.?);
-
- if (target.os.tag == .windows) {
- if (std.fs.path.dirname(lci.sys_include_dir.?)) |sys_include_dir_parent| {
- // This include path will only exist when the optional "Desktop development with C++"
- // is installed. It contains headers, .rc files, and resources. It is especially
- // necessary when working with Windows resources.
- const atlmfc_dir = try std.fs.path.join(arena, &[_][]const u8{ sys_include_dir_parent, "atlmfc", "include" });
- list.appendAssumeCapacity(atlmfc_dir);
- }
- if (std.fs.path.dirname(lci.include_dir.?)) |include_dir_parent| {
- const um_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_parent, "um" });
- list.appendAssumeCapacity(um_dir);
-
- const shared_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_parent, "shared" });
- list.appendAssumeCapacity(shared_dir);
- }
- }
- if (target.os.tag == .haiku) {
- const include_dir_path = lci.include_dir orelse return error.LibCInstallationNotAvailable;
- const os_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_path, "os" });
- list.appendAssumeCapacity(os_dir);
- // Errors.h
- const os_support_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_path, "os/support" });
- list.appendAssumeCapacity(os_support_dir);
-
- const config_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_path, "config" });
- list.appendAssumeCapacity(config_dir);
- }
-
- var sysroot: ?[]const u8 = null;
-
- if (target.isDarwin()) d: {
- const down1 = std.fs.path.dirname(lci.sys_include_dir.?) orelse break :d;
- const down2 = std.fs.path.dirname(down1) orelse break :d;
- try framework_list.append(try std.fs.path.join(arena, &.{ down2, "System", "Library", "Frameworks" }));
- sysroot = down2;
- }
-
- return LibCDirs{
- .libc_include_dir_list = list.items,
- .libc_installation = lci,
- .libc_framework_dir_list = framework_list.items,
- .sysroot = sysroot,
- .darwin_sdk_layout = if (sysroot == null) null else .sdk,
- };
-}
-
-fn detectLibCFromBuilding(
- arena: Allocator,
- zig_lib_dir: []const u8,
- target: std.Target,
-) !LibCDirs {
- if (target.isDarwin())
- return getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir);
-
- const generic_name = target_util.libCGenericName(target);
- // Some architectures are handled by the same set of headers.
- const arch_name = if (target.abi.isMusl())
- musl.archNameHeaders(target.cpu.arch)
- else if (target.cpu.arch.isThumb())
- // ARM headers are valid for Thumb too.
- switch (target.cpu.arch) {
- .thumb => "arm",
- .thumbeb => "armeb",
- else => unreachable,
- }
- else
- @tagName(target.cpu.arch);
- const os_name = @tagName(target.os.tag);
- // Musl's headers are ABI-agnostic and so they all have the "musl" ABI name.
- const abi_name = if (target.abi.isMusl()) "musl" else @tagName(target.abi);
- const s = std.fs.path.sep_str;
- const arch_include_dir = try std.fmt.allocPrint(
- arena,
- "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}",
- .{ zig_lib_dir, arch_name, os_name, abi_name },
- );
- const generic_include_dir = try std.fmt.allocPrint(
- arena,
- "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}",
- .{ zig_lib_dir, generic_name },
- );
- const generic_arch_name = target_util.osArchName(target);
- const arch_os_include_dir = try std.fmt.allocPrint(
- arena,
- "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any",
- .{ zig_lib_dir, generic_arch_name, os_name },
- );
- const generic_os_include_dir = try std.fmt.allocPrint(
- arena,
- "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any",
- .{ zig_lib_dir, os_name },
- );
-
- const list = try arena.alloc([]const u8, 4);
- list[0] = arch_include_dir;
- list[1] = generic_include_dir;
- list[2] = arch_os_include_dir;
- list[3] = generic_os_include_dir;
-
- return LibCDirs{
- .libc_include_dir_list = list,
- .libc_installation = null,
- .libc_framework_dir_list = &.{},
- .sysroot = null,
- .darwin_sdk_layout = .vendored,
- };
-}
-
pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
if (comp.wantBuildGLibCFromSource() or
comp.wantBuildMuslFromSource() or