diff options
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 238 |
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 |
