diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-06-25 22:37:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-25 22:37:46 +0200 |
| commit | 7a85dc6935ffaf1828cdc75c2602fb232217f7b3 (patch) | |
| tree | 4b18151af1320b2801054a5dc0e1765a541ddc62 | |
| parent | 73f77f30804f3a512fbb35caad3d87ff2778ecc0 (diff) | |
| parent | f9171bf54295df0bd8f4dbe1ab9698e5940ba445 (diff) | |
| download | zig-7a85dc6935ffaf1828cdc75c2602fb232217f7b3.tar.gz zig-7a85dc6935ffaf1828cdc75c2602fb232217f7b3.zip | |
Merge pull request #9202 from ifreund/sysroot
stage2: add --sysroot link option
| -rw-r--r-- | lib/std/build.zig | 5 | ||||
| -rw-r--r-- | lib/std/special/build_runner.zig | 7 | ||||
| -rw-r--r-- | src/Compilation.zig | 42 | ||||
| -rw-r--r-- | src/link.zig | 4 | ||||
| -rw-r--r-- | src/link/Elf.zig | 5 | ||||
| -rw-r--r-- | src/link/MachO.zig | 12 | ||||
| -rw-r--r-- | src/main.zig | 11 |
7 files changed, 60 insertions, 26 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index 8626d660f0..36a71d5061 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -57,6 +57,7 @@ pub const Builder = struct { exe_dir: []const u8, h_dir: []const u8, install_path: []const u8, + sysroot: ?[]const u8 = null, search_prefixes: ArrayList([]const u8), libc_file: ?[]const u8 = null, installed_files: ArrayList(InstalledFile), @@ -2701,6 +2702,10 @@ pub const LibExeObjStep = struct { } } + if (builder.sysroot) |sysroot| { + try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot }); + } + for (builder.search_prefixes.items) |search_prefix| { try zig_args.append("-L"); try zig_args.append(try fs.path.join(builder.allocator, &[_][]const u8{ diff --git a/lib/std/special/build_runner.zig b/lib/std/special/build_runner.zig index 510dd578c3..7530fae4f0 100644 --- a/lib/std/special/build_runner.zig +++ b/lib/std/special/build_runner.zig @@ -104,6 +104,12 @@ pub fn main() !void { warn("Expected argument after {s}\n\n", .{arg}); return usageAndErr(builder, false, stderr_stream); }; + } else if (mem.eql(u8, arg, "--sysroot")) { + const sysroot = nextArg(args, &arg_idx) orelse { + warn("Expected argument after --sysroot\n\n", .{}); + return usageAndErr(builder, false, stderr_stream); + }; + builder.sysroot = sysroot; } else if (mem.eql(u8, arg, "--search-prefix")) { const search_prefix = nextArg(args, &arg_idx) orelse { warn("Expected argument after --search-prefix\n\n", .{}); @@ -214,6 +220,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void \\ --prefix-exe-dir [path] Override default executable directory path \\ --prefix-include-dir [path] Override default include directory path \\ + \\ --sysroot [path] Set the system root directory (usually /) \\ --search-prefix [path] Add a path to look for binaries, libraries, headers \\ --libc [file] Provide a file which specifies libc paths \\ diff --git a/src/Compilation.zig b/src/Compilation.zig index eea4d930c4..f202034242 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -612,6 +612,7 @@ pub const InitOptions = struct { output_mode: std.builtin.OutputMode, thread_pool: *ThreadPool, dynamic_linker: ?[]const u8 = null, + sysroot: ?[]const u8 = null, /// `null` means to not emit a binary file. emit_bin: ?EmitLoc, /// `null` means to not emit a C header file. @@ -879,25 +880,32 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk false; }; - const DarwinOptions = struct { - syslibroot: ?[]const u8 = null, - system_linker_hack: bool = false, + const darwin_can_use_system_linker_and_sdk = + // comptime conditions + ((build_options.have_llvm and comptime std.Target.current.isDarwin()) and + // runtime conditions + (use_lld and std.builtin.os.tag == .macos and options.target.isDarwin())); + + const darwin_system_linker_hack = blk: { + if (darwin_can_use_system_linker_and_sdk) { + break :blk std.os.getenv("ZIG_SYSTEM_LINKER_HACK") != null; + } else { + break :blk false; + } }; - const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: { - const opts: DarwinOptions = if (use_lld and std.builtin.os.tag == .macos and options.target.isDarwin()) inner: { + const sysroot = blk: { + if (options.sysroot) |sysroot| { + break :blk sysroot; + } else if (darwin_can_use_system_linker_and_sdk) { // TODO Revisit this targeting versions lower than macOS 11 when LLVM 12 is out. // See https://github.com/ziglang/zig/issues/6996 const at_least_big_sur = options.target.os.getVersionRange().semver.min.major >= 11; - const syslibroot = if (at_least_big_sur) try std.zig.system.getSDKPath(arena) else null; - const system_linker_hack = std.os.getenv("ZIG_SYSTEM_LINKER_HACK") != null; - break :inner .{ - .syslibroot = syslibroot, - .system_linker_hack = system_linker_hack, - }; - } else .{}; - break :outer opts; - } else .{}; + break :blk if (at_least_big_sur) try std.zig.system.getSDKPath(arena) else null; + } else { + break :blk null; + } + }; const lto = blk: { if (options.want_lto) |explicit| { @@ -908,7 +916,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk false; } else if (options.c_source_files.len == 0) { break :blk false; - } else if (darwin_options.system_linker_hack) { + } else if (darwin_system_linker_hack) { break :blk false; } else switch (options.output_mode) { .Lib, .Obj => break :blk false, @@ -1281,13 +1289,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .module = module, .target = options.target, .dynamic_linker = options.dynamic_linker, + .sysroot = sysroot, .output_mode = options.output_mode, .link_mode = link_mode, .object_format = ofmt, .optimize_mode = options.optimize_mode, .use_lld = use_lld, .use_llvm = use_llvm, - .system_linker_hack = darwin_options.system_linker_hack, + .system_linker_hack = darwin_system_linker_hack, .link_libc = link_libc, .link_libcpp = link_libcpp, .link_libunwind = link_libunwind, @@ -1295,7 +1304,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .frameworks = options.frameworks, .framework_dirs = options.framework_dirs, .system_libs = system_libs, - .syslibroot = darwin_options.syslibroot, .wasi_emulated_libs = options.wasi_emulated_libs, .lib_dirs = options.lib_dirs, .rpath_list = options.rpath_list, diff --git a/src/link.zig b/src/link.zig index bae468d075..c26feb10fd 100644 --- a/src/link.zig +++ b/src/link.zig @@ -38,6 +38,8 @@ pub const Options = struct { /// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`. module: ?*Module, dynamic_linker: ?[]const u8, + /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) + sysroot: ?[]const u8, /// Used for calculating how much space to reserve for symbols in case the binary file /// does not already have a symbol table. symbol_count_hint: u64 = 32, @@ -104,8 +106,6 @@ pub const Options = struct { llvm_cpu_features: ?[*:0]const u8, /// Extra args passed directly to LLD. Ignored when not linking with LLD. extra_lld_args: []const []const u8, - /// Darwin-only. Set the root path to the system libraries and frameworks. - syslibroot: ?[]const u8, objects: []const []const u8, framework_dirs: []const []const u8, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 6f839c7694..722077b8b8 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1354,6 +1354,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { man.hash.add(allow_shlib_undefined); man.hash.add(self.base.options.bind_global_refs_locally); man.hash.add(self.base.options.tsan); + man.hash.addOptionalBytes(self.base.options.sysroot); // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. _ = try man.hit(); @@ -1423,6 +1424,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { try argv.append("-error-limit=0"); + if (self.base.options.sysroot) |sysroot| { + try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot})); + } + if (self.base.options.lto) { switch (self.base.options.optimize_mode) { .Debug => {}, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 4ede9c516e..95389c2d95 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -704,7 +704,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { man.hash.add(allow_shlib_undefined); man.hash.add(self.base.options.bind_global_refs_locally); man.hash.add(self.base.options.system_linker_hack); - man.hash.addOptionalBytes(self.base.options.syslibroot); + man.hash.addOptionalBytes(self.base.options.sysroot); // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. _ = try man.hit(); @@ -789,7 +789,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { zld.deinit(); } zld.arch = target.cpu.arch; - zld.syslibroot = self.base.options.syslibroot; + zld.syslibroot = self.base.options.sysroot; zld.stack_size = stack_size; // Positional arguments to the linker such as object files and static archives. @@ -833,7 +833,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { try resolvePaths( arena, &libs, - self.base.options.syslibroot, + self.base.options.sysroot, self.base.options.lib_dirs, search_lib_names.items, .lib, @@ -856,7 +856,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { try resolvePaths( arena, &libs, - self.base.options.syslibroot, + self.base.options.sysroot, self.base.options.framework_dirs, self.base.options.frameworks, .framework, @@ -868,7 +868,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { try argv.append("zig"); try argv.append("ld"); - if (self.base.options.syslibroot) |syslibroot| { + if (self.base.options.sysroot) |syslibroot| { try argv.append("-syslibroot"); try argv.append(syslibroot); } @@ -1017,7 +1017,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { } } - if (self.base.options.syslibroot) |dir| { + if (self.base.options.sysroot) |dir| { try argv.append("-syslibroot"); try argv.append(dir); } diff --git a/src/main.zig b/src/main.zig index 1cf62c011b..86995c5b9f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -379,6 +379,7 @@ const usage_build_generic = \\ -T[script], --script [script] Use a custom linker script \\ --version-script [path] Provide a version .map file \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) + \\ --sysroot [path] Set the system root directory (usually /) \\ --version [ver] Dynamic library semver \\ -fsoname[=name] (Linux) Override the default SONAME value \\ -fno-soname (Linux) Disable emitting a SONAME @@ -604,6 +605,7 @@ fn buildOutputType( var link_eh_frame_hdr = false; var link_emit_relocs = false; var each_lib_rpath: ?bool = null; + var sysroot: ?[]const u8 = null; var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC"); var machine_code_model: std.builtin.CodeModel = .default; var runtime_args_start: ?usize = null; @@ -865,6 +867,10 @@ fn buildOutputType( if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); i += 1; target_dynamic_linker = args[i]; + } else if (mem.eql(u8, arg, "--sysroot")) { + if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); + i += 1; + sysroot = args[i]; } else if (mem.eql(u8, arg, "--libc")) { if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); i += 1; @@ -1641,7 +1647,9 @@ fn buildOutputType( want_native_include_dirs = true; } - if (cross_target.isNativeOs() and (system_libs.items.len != 0 or want_native_include_dirs)) { + if (sysroot == null and cross_target.isNativeOs() and + (system_libs.items.len != 0 or want_native_include_dirs)) + { const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { fatal("unable to detect native system paths: {s}", .{@errorName(err)}); }; @@ -1918,6 +1926,7 @@ fn buildOutputType( .is_native_os = cross_target.isNativeOs(), .is_native_abi = cross_target.isNativeAbi(), .dynamic_linker = target_info.dynamic_linker.get(), + .sysroot = sysroot, .output_mode = output_mode, .root_pkg = root_pkg, .emit_bin = emit_bin_loc, |
