From 4616af0ca459358ffa09ba27f9daa8527a38fd35 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 25 Feb 2020 01:52:27 -0500 Subject: introduce operating system version ranges as part of the target * re-introduce `std.build.Target` which is distinct from `std.Target`. `std.build.Target` wraps `std.Target` so that it can be annotated as "the native target" or an explicitly specified target. * `std.Target.Os` is moved to `std.Target.Os.Tag`. The former is now a struct which has the tag as well as version range information. * `std.elf` gains some more ELF header constants. * `std.Target.parse` gains the ability to parse operating system version ranges as well as glibc version. * Added `std.Target.isGnuLibC()`. * self-hosted dynamic linker detection and glibc version detection. This also adds the improved logic using `/usr/bin/env` rather than invoking the system C compiler to find the dynamic linker when zig is statically linked. Related: #2084 Note: this `/usr/bin/env` code is work-in-progress. * `-target-glibc` CLI option is removed in favor of the new `-target` syntax. Example: `-target x86_64-linux-gnu.2.27` closes #1907 --- src/stage2.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/stage2.cpp') diff --git a/src/stage2.cpp b/src/stage2.cpp index 736f11622e..2023b45aaf 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -100,13 +100,11 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons if (mcpu == nullptr) { target->llvm_cpu_name = ZigLLVMGetHostCPUName(); target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); - target->builtin_str = "Target.Cpu.baseline(arch);\n"; target->cache_hash = "native\n\n"; } else if (strcmp(mcpu, "baseline") == 0) { target->is_native = false; target->llvm_cpu_name = ""; target->llvm_cpu_features = ""; - target->builtin_str = "Target.Cpu.baseline(arch);\n"; target->cache_hash = "baseline\n\n"; } else { const char *msg = "stage0 can't handle CPU/features in the target"; @@ -148,7 +146,6 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons const char *msg = "stage0 can't handle CPU/features in the target"; stage2_panic(msg, strlen(msg)); } - target->builtin_str = "Target.Cpu.baseline(arch);\n"; target->cache_hash = "\n\n"; } @@ -186,11 +183,6 @@ enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { stage2_panic(msg, strlen(msg)); } -enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) { - const char *msg = "stage0 called stage2_detect_dynamic_linker"; - stage2_panic(msg, strlen(msg)); -} - enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) { native_paths->include_dirs_ptr = nullptr; native_paths->include_dirs_len = 0; -- cgit v1.2.3 From d45ea4d89d7232fc4bcf56a5e088d7d6b5004ebb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 28 Feb 2020 02:00:20 -0500 Subject: stage1: make get_native_target go through self-hosted --- lib/std/special/init-exe/src/main.zig | 2 +- lib/std/target.zig | 2 +- src/main.cpp | 10 +++- src/stage2.cpp | 100 ++++++++++++++++++++++++++++++++++ src/target.cpp | 100 ---------------------------------- src/target.hpp | 1 - 6 files changed, 110 insertions(+), 105 deletions(-) (limited to 'src/stage2.cpp') diff --git a/lib/std/special/init-exe/src/main.zig b/lib/std/special/init-exe/src/main.zig index 5f35540dc0..c6a70af56d 100644 --- a/lib/std/special/init-exe/src/main.zig +++ b/lib/std/special/init-exe/src/main.zig @@ -1,5 +1,5 @@ const std = @import("std"); pub fn main() anyerror!void { - std.debug.warn("All your base are belong to us.\n", .{}); + std.debug.warn("All your codebase are belong to us.\n", .{}); } diff --git a/lib/std/target.zig b/lib/std/target.zig index 379ae72afe..a72bd921b0 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1215,8 +1215,8 @@ pub const Target = struct { .uefi, .windows, .emscripten, - .other, .wasi, + .other, => return null, // TODO go over each item in this list and either move it to the above list, or diff --git a/src/main.cpp b/src/main.cpp index 11612402ee..f741cafd40 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -500,7 +500,10 @@ static int main0(int argc, char **argv) { os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); ZigTarget target; - get_native_target(&target); + if ((err = target_parse_triple(&target, "native", nullptr))) { + fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); + return EXIT_FAILURE; + } Buf *build_file_buf = buf_create_from_str((build_file != nullptr) ? build_file : "build.zig"); Buf build_file_abs = os_path_resolve(&build_file_buf, 1); @@ -1337,7 +1340,10 @@ static int main0(int argc, char **argv) { return main_exit(root_progress_node, EXIT_SUCCESS); } else if (cmd == CmdTest) { ZigTarget native; - get_native_target(&native); + if ((err = target_parse_triple(&native, "native", nullptr))) { + fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); + return EXIT_FAILURE; + } g->enable_cache = get_cache_opt(enable_cache, output_dir == nullptr); codegen_build_and_link(g); diff --git a/src/stage2.cpp b/src/stage2.cpp index 2023b45aaf..bc8e65fd56 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -91,6 +91,106 @@ void stage2_progress_complete_one(Stage2ProgressNode *node) {} void stage2_progress_disable_tty(Stage2Progress *progress) {} void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} +static Os get_zig_os_type(ZigLLVM_OSType os_type) { + switch (os_type) { + case ZigLLVM_UnknownOS: + return OsFreestanding; + case ZigLLVM_Ananas: + return OsAnanas; + case ZigLLVM_CloudABI: + return OsCloudABI; + case ZigLLVM_DragonFly: + return OsDragonFly; + case ZigLLVM_FreeBSD: + return OsFreeBSD; + case ZigLLVM_Fuchsia: + return OsFuchsia; + case ZigLLVM_IOS: + return OsIOS; + case ZigLLVM_KFreeBSD: + return OsKFreeBSD; + case ZigLLVM_Linux: + return OsLinux; + case ZigLLVM_Lv2: + return OsLv2; + case ZigLLVM_Darwin: + case ZigLLVM_MacOSX: + return OsMacOSX; + case ZigLLVM_NetBSD: + return OsNetBSD; + case ZigLLVM_OpenBSD: + return OsOpenBSD; + case ZigLLVM_Solaris: + return OsSolaris; + case ZigLLVM_Win32: + return OsWindows; + case ZigLLVM_Haiku: + return OsHaiku; + case ZigLLVM_Minix: + return OsMinix; + case ZigLLVM_RTEMS: + return OsRTEMS; + case ZigLLVM_NaCl: + return OsNaCl; + case ZigLLVM_CNK: + return OsCNK; + case ZigLLVM_AIX: + return OsAIX; + case ZigLLVM_CUDA: + return OsCUDA; + case ZigLLVM_NVCL: + return OsNVCL; + case ZigLLVM_AMDHSA: + return OsAMDHSA; + case ZigLLVM_PS4: + return OsPS4; + case ZigLLVM_ELFIAMCU: + return OsELFIAMCU; + case ZigLLVM_TvOS: + return OsTvOS; + case ZigLLVM_WatchOS: + return OsWatchOS; + case ZigLLVM_Mesa3D: + return OsMesa3D; + case ZigLLVM_Contiki: + return OsContiki; + case ZigLLVM_AMDPAL: + return OsAMDPAL; + case ZigLLVM_HermitCore: + return OsHermitCore; + case ZigLLVM_Hurd: + return OsHurd; + case ZigLLVM_WASI: + return OsWASI; + case ZigLLVM_Emscripten: + return OsEmscripten; + } + zig_unreachable(); +} + +static void get_native_target(ZigTarget *target) { + // first zero initialize + *target = {}; + + ZigLLVM_OSType os_type; + ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os + ZigLLVMGetNativeTarget( + &target->arch, + &target->vendor, + &os_type, + &target->abi, + &oformat); + target->os = get_zig_os_type(os_type); + target->is_native = true; + if (target->abi == ZigLLVM_UnknownEnvironment) { + target->abi = target_default_abi(target->arch, target->os); + } + if (target_is_glibc(target)) { + target->glibc_version = heap::c_allocator.create(); + target_init_default_glibc_version(target); + } +} + Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) { Error err; diff --git a/src/target.cpp b/src/target.cpp index 8a68afbd83..4df2cfca85 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -287,83 +287,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { zig_unreachable(); } -static Os get_zig_os_type(ZigLLVM_OSType os_type) { - switch (os_type) { - case ZigLLVM_UnknownOS: - return OsFreestanding; - case ZigLLVM_Ananas: - return OsAnanas; - case ZigLLVM_CloudABI: - return OsCloudABI; - case ZigLLVM_DragonFly: - return OsDragonFly; - case ZigLLVM_FreeBSD: - return OsFreeBSD; - case ZigLLVM_Fuchsia: - return OsFuchsia; - case ZigLLVM_IOS: - return OsIOS; - case ZigLLVM_KFreeBSD: - return OsKFreeBSD; - case ZigLLVM_Linux: - return OsLinux; - case ZigLLVM_Lv2: - return OsLv2; - case ZigLLVM_Darwin: - case ZigLLVM_MacOSX: - return OsMacOSX; - case ZigLLVM_NetBSD: - return OsNetBSD; - case ZigLLVM_OpenBSD: - return OsOpenBSD; - case ZigLLVM_Solaris: - return OsSolaris; - case ZigLLVM_Win32: - return OsWindows; - case ZigLLVM_Haiku: - return OsHaiku; - case ZigLLVM_Minix: - return OsMinix; - case ZigLLVM_RTEMS: - return OsRTEMS; - case ZigLLVM_NaCl: - return OsNaCl; - case ZigLLVM_CNK: - return OsCNK; - case ZigLLVM_AIX: - return OsAIX; - case ZigLLVM_CUDA: - return OsCUDA; - case ZigLLVM_NVCL: - return OsNVCL; - case ZigLLVM_AMDHSA: - return OsAMDHSA; - case ZigLLVM_PS4: - return OsPS4; - case ZigLLVM_ELFIAMCU: - return OsELFIAMCU; - case ZigLLVM_TvOS: - return OsTvOS; - case ZigLLVM_WatchOS: - return OsWatchOS; - case ZigLLVM_Mesa3D: - return OsMesa3D; - case ZigLLVM_Contiki: - return OsContiki; - case ZigLLVM_AMDPAL: - return OsAMDPAL; - case ZigLLVM_HermitCore: - return OsHermitCore; - case ZigLLVM_Hurd: - return OsHurd; - case ZigLLVM_WASI: - return OsWASI; - case ZigLLVM_Emscripten: - return OsEmscripten; - } - zig_unreachable(); -} - const char *target_os_name(Os os_type) { switch (os_type) { case OsFreestanding: @@ -447,29 +370,6 @@ Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { return ErrorNone; } -void get_native_target(ZigTarget *target) { - // first zero initialize - *target = {}; - - ZigLLVM_OSType os_type; - ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os - ZigLLVMGetNativeTarget( - &target->arch, - &target->vendor, - &os_type, - &target->abi, - &oformat); - target->os = get_zig_os_type(os_type); - target->is_native = true; - if (target->abi == ZigLLVM_UnknownEnvironment) { - target->abi = target_default_abi(target->arch, target->os); - } - if (target_is_glibc(target)) { - target->glibc_version = heap::c_allocator.create(); - target_init_default_glibc_version(target); - } -} - void target_init_default_glibc_version(ZigTarget *target) { *target->glibc_version = {2, 17, 0}; } diff --git a/src/target.hpp b/src/target.hpp index 9396eb2623..e72b6a6f49 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -73,7 +73,6 @@ ZigLLVM_ObjectFormatType target_oformat_enum(size_t index); const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat); ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target); -void get_native_target(ZigTarget *target); void target_triple_llvm(Buf *triple, const ZigTarget *target); void target_triple_zig(Buf *triple, const ZigTarget *target); -- cgit v1.2.3 From ef24f2dd93729493531c427aaac54444597f6e66 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 28 Feb 2020 02:36:16 -0500 Subject: remove special darwin os version min handling now it is integrated with zig's target OS range. --- lib/std/target.zig | 21 ++++++- lib/std/zig/cross_target.zig | 6 +- src-self-hosted/stage2.zig | 39 ++++++++----- src/all_types.hpp | 2 - src/codegen.cpp | 59 +++----------------- src/codegen.hpp | 2 - src/glibc.cpp | 26 ++++----- src/glibc.hpp | 2 +- src/link.cpp | 127 ++++++------------------------------------- src/main.cpp | 20 ------- src/stage2.cpp | 2 +- src/stage2.h | 9 ++- src/target.cpp | 4 +- src/target.hpp | 2 +- test/cli.zig | 2 +- 15 files changed, 95 insertions(+), 228 deletions(-) (limited to 'src/stage2.cpp') diff --git a/lib/std/target.zig b/lib/std/target.zig index a72bd921b0..6ecb679f29 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -147,7 +147,6 @@ pub const Target = struct { .cloudabi, .dragonfly, .fuchsia, - .ios, .kfreebsd, .lv2, .solaris, @@ -162,8 +161,6 @@ pub const Target = struct { .amdhsa, .ps4, .elfiamcu, - .tvos, - .watchos, .mesa3d, .contiki, .amdpal, @@ -187,6 +184,24 @@ pub const Target = struct { .max = .{ .major = 10, .minor = 15, .patch = 3 }, }, }, + .ios => return .{ + .semver = .{ + .min = .{ .major = 12, .minor = 0 }, + .max = .{ .major = 13, .minor = 4, .patch = 0 }, + }, + }, + .watchos => return .{ + .semver = .{ + .min = .{ .major = 6, .minor = 0 }, + .max = .{ .major = 6, .minor = 2, .patch = 0 }, + }, + }, + .tvos => return .{ + .semver = .{ + .min = .{ .major = 13, .minor = 0 }, + .max = .{ .major = 13, .minor = 4, .patch = 0 }, + }, + }, .netbsd => return .{ .semver = .{ .min = .{ .major = 8, .minor = 0 }, diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index fac90ddba8..c7fd1f0464 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -88,7 +88,6 @@ pub const CrossTarget = struct { .cloudabi, .dragonfly, .fuchsia, - .ios, .kfreebsd, .lv2, .solaris, @@ -103,8 +102,6 @@ pub const CrossTarget = struct { .amdhsa, .ps4, .elfiamcu, - .tvos, - .watchos, .mesa3d, .contiki, .amdpal, @@ -121,8 +118,11 @@ pub const CrossTarget = struct { .freebsd, .macosx, + .ios, .netbsd, .openbsd, + .tvos, + .watchos, => { self.os_version_min = .{ .semver = os.version_range.semver.min }; self.os_version_max = .{ .semver = os.version_range.semver.max }; diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index cd3f49edfa..3dae15056e 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -892,7 +892,7 @@ const Stage2Target = extern struct { is_native: bool, - glibc_version: ?*Stage2GLibCVersion, // null means default + glibc_or_darwin_version: ?*Stage2SemVer, llvm_cpu_name: ?[*:0]const u8, llvm_cpu_features: ?[*:0]const u8, @@ -1103,16 +1103,29 @@ const Stage2Target = extern struct { os_builtin_str_buffer.toSlice()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()], ); - const glibc_version = if (target.isGnuLibC()) blk: { - const stage1_glibc = try std.heap.c_allocator.create(Stage2GLibCVersion); - const stage2_glibc = target.os.version_range.linux.glibc; - stage1_glibc.* = .{ - .major = stage2_glibc.major, - .minor = stage2_glibc.minor, - .patch = stage2_glibc.patch, - }; - break :blk stage1_glibc; - } else null; + const glibc_or_darwin_version = blk: { + if (target.isGnuLibC()) { + const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); + const stage2_glibc = target.os.version_range.linux.glibc; + stage1_glibc.* = .{ + .major = stage2_glibc.major, + .minor = stage2_glibc.minor, + .patch = stage2_glibc.patch, + }; + break :blk stage1_glibc; + } else if (target.isDarwin()) { + const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); + const stage2_semver = target.os.version_range.semver.min; + stage1_semver.* = .{ + .major = stage2_semver.major, + .minor = stage2_semver.minor, + .patch = stage2_semver.patch, + }; + break :blk stage1_semver; + } else { + break :blk null; + } + }; self.* = .{ .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch @@ -1125,7 +1138,7 @@ const Stage2Target = extern struct { .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, .cache_hash = cache_hash.toOwnedSlice().ptr, .is_native = cross_target.isNative(), - .glibc_version = glibc_version, + .glibc_or_darwin_version = glibc_or_darwin_version, .dynamic_linker = dynamic_linker, }; } @@ -1179,7 +1192,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) } // ABI warning -const Stage2GLibCVersion = extern struct { +const Stage2SemVer = extern struct { major: u32, minor: u32, patch: u32, diff --git a/src/all_types.hpp b/src/all_types.hpp index 7277d04359..838709b9c0 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2250,8 +2250,6 @@ struct CodeGen { bool test_is_evented; CodeModel code_model; - Buf *mmacosx_version_min; - Buf *mios_version_min; Buf *root_out_name; Buf *test_filter; Buf *test_name_prefix; diff --git a/src/codegen.cpp b/src/codegen.cpp index 15122d5e11..8ae730616d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -32,31 +32,6 @@ enum ResumeId { ResumeIdCall, }; -static void init_darwin_native(CodeGen *g) { - char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); - char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); - - // Allow conflicts among OSX and iOS, but choose the default platform. - if (osx_target && ios_target) { - if (g->zig_target->arch == ZigLLVM_arm || - g->zig_target->arch == ZigLLVM_aarch64 || - g->zig_target->arch == ZigLLVM_thumb) - { - osx_target = nullptr; - } else { - ios_target = nullptr; - } - } - - if (osx_target) { - g->mmacosx_version_min = buf_create_from_str(osx_target); - } else if (ios_target) { - g->mios_version_min = buf_create_from_str(ios_target); - } else if (g->zig_target->os != OsIOS) { - g->mmacosx_version_min = buf_create_from_str("10.14"); - } -} - static ZigPackage *new_package(const char *root_src_dir, const char *root_src_path, const char *pkg_path) { ZigPackage *entry = heap::c_allocator.create(); entry->package_table.init(4); @@ -160,14 +135,6 @@ void codegen_add_framework(CodeGen *g, const char *framework) { g->darwin_frameworks.append(buf_create_from_str(framework)); } -void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { - g->mmacosx_version_min = mmacosx_version_min; -} - -void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min) { - g->mios_version_min = mios_version_min; -} - void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { g->linker_rdynamic = rdynamic; } @@ -8655,10 +8622,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { if (g->zig_target->cache_hash != nullptr) { cache_str(&cache_hash, g->zig_target->cache_hash); } - if (g->zig_target->glibc_version != nullptr) { - cache_int(&cache_hash, g->zig_target->glibc_version->major); - cache_int(&cache_hash, g->zig_target->glibc_version->minor); - cache_int(&cache_hash, g->zig_target->glibc_version->patch); + if (g->zig_target->glibc_or_darwin_version != nullptr) { + cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->major); + cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->minor); + cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->patch); } cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); @@ -10313,10 +10280,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { if (g->zig_target->cache_hash != nullptr) { cache_str(ch, g->zig_target->cache_hash); } - if (g->zig_target->glibc_version != nullptr) { - cache_int(ch, g->zig_target->glibc_version->major); - cache_int(ch, g->zig_target->glibc_version->minor); - cache_int(ch, g->zig_target->glibc_version->patch); + if (g->zig_target->glibc_or_darwin_version != nullptr) { + cache_int(ch, g->zig_target->glibc_or_darwin_version->major); + cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); + cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); } cache_int(ch, detect_subsystem(g)); cache_bool(ch, g->strip_debug_symbols); @@ -10344,8 +10311,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->emit_bin); cache_bool(ch, g->emit_llvm_ir); cache_bool(ch, g->emit_asm); - cache_buf_opt(ch, g->mmacosx_version_min); - cache_buf_opt(ch, g->mios_version_min); cache_usize(ch, g->version_major); cache_usize(ch, g->version_minor); cache_usize(ch, g->version_patch); @@ -10662,9 +10627,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o codegen_set_errmsg_color(child_gen, parent_gen->err_color); - codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); - codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); - child_gen->enable_cache = true; return child_gen; @@ -10772,11 +10734,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget g->each_lib_rpath = false; } else { g->each_lib_rpath = true; - - if (target_os_is_darwin(g->zig_target->os)) { - init_darwin_native(g); - } - } if (target_os_requires_libc(g->zig_target->os)) { diff --git a/src/codegen.hpp b/src/codegen.hpp index 6329c59a5e..191da9a04b 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -35,8 +35,6 @@ LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); void codegen_add_framework(CodeGen *codegen, const char *name); void codegen_add_rpath(CodeGen *codegen, const char *name); void codegen_set_rdynamic(CodeGen *g, bool rdynamic); -void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); -void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); void codegen_set_linker_script(CodeGen *g, const char *linker_script); void codegen_set_test_filter(CodeGen *g, Buf *filter); void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); diff --git a/src/glibc.cpp b/src/glibc.cpp index 91e2f9dfc1..da5c1d5290 100644 --- a/src/glibc.cpp +++ b/src/glibc.cpp @@ -55,7 +55,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo Optional> opt_component = SplitIterator_next(&it); if (!opt_component.is_some) break; Buf *ver_buf = buf_create_from_slice(opt_component.value); - ZigGLibCVersion *this_ver = glibc_abi->all_versions.add_one(); + Stage2SemVer *this_ver = glibc_abi->all_versions.add_one(); if ((err = target_parse_glibc_version(this_ver, buf_ptr(ver_buf)))) { if (verbose) { fprintf(stderr, "Unable to parse glibc version '%s': %s\n", buf_ptr(ver_buf), err_str(err)); @@ -186,9 +186,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con cache_buf(cache_hash, compiler_id); cache_int(cache_hash, target->arch); cache_int(cache_hash, target->abi); - cache_int(cache_hash, target->glibc_version->major); - cache_int(cache_hash, target->glibc_version->minor); - cache_int(cache_hash, target->glibc_version->patch); + cache_int(cache_hash, target->glibc_or_darwin_version->major); + cache_int(cache_hash, target->glibc_or_darwin_version->minor); + cache_int(cache_hash, target->glibc_or_darwin_version->patch); Buf digest = BUF_INIT; buf_resize(&digest, 0); @@ -224,10 +224,10 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con uint8_t target_ver_index = 0; for (;target_ver_index < glibc_abi->all_versions.length; target_ver_index += 1) { - const ZigGLibCVersion *this_ver = &glibc_abi->all_versions.at(target_ver_index); - if (this_ver->major == target->glibc_version->major && - this_ver->minor == target->glibc_version->minor && - this_ver->patch == target->glibc_version->patch) + const Stage2SemVer *this_ver = &glibc_abi->all_versions.at(target_ver_index); + if (this_ver->major == target->glibc_or_darwin_version->major && + this_ver->minor == target->glibc_or_darwin_version->minor && + this_ver->patch == target->glibc_or_darwin_version->patch) { break; } @@ -235,9 +235,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con if (target_ver_index == glibc_abi->all_versions.length) { if (verbose) { fprintf(stderr, "Unrecognized glibc version: %d.%d.%d\n", - target->glibc_version->major, - target->glibc_version->minor, - target->glibc_version->patch); + target->glibc_or_darwin_version->major, + target->glibc_or_darwin_version->minor, + target->glibc_or_darwin_version->patch); } return ErrorUnknownABI; } @@ -246,7 +246,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con Buf *map_contents = buf_alloc(); for (uint8_t ver_i = 0; ver_i < glibc_abi->all_versions.length; ver_i += 1) { - const ZigGLibCVersion *ver = &glibc_abi->all_versions.at(ver_i); + const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_i); if (ver->patch == 0) { buf_appendf(map_contents, "GLIBC_%d.%d { };\n", ver->major, ver->minor); } else { @@ -294,7 +294,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con uint8_t ver_index = ver_list->versions[ver_i]; Buf *stub_name; - const ZigGLibCVersion *ver = &glibc_abi->all_versions.at(ver_index); + const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_index); const char *sym_name = buf_ptr(libc_fn->name); if (ver->patch == 0) { stub_name = buf_sprintf("%s_%d_%d", sym_name, ver->major, ver->minor); diff --git a/src/glibc.hpp b/src/glibc.hpp index 8e4c7888ad..c04dcb4629 100644 --- a/src/glibc.hpp +++ b/src/glibc.hpp @@ -32,7 +32,7 @@ struct ZigGLibCAbi { Buf *abi_txt_path; Buf *vers_txt_path; Buf *fns_txt_path; - ZigList all_versions; + ZigList all_versions; ZigList all_functions; // The value is a pointer to all_functions.length items and each item is an index // into all_functions. diff --git a/src/link.cpp b/src/link.cpp index 901390feae..588771d8bf 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -2371,99 +2371,6 @@ static void construct_linker_job_coff(LinkJob *lj) { } } - -// Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the -// grouped values as integers. Numbers which are not provided are set to 0. -// return true if the entire string was parsed (9.2), or all groups were -// parsed (10.3.5extrastuff). -static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) { - *had_extra = false; - - *major = 0; - *minor = 0; - *micro = 0; - - if (*str == '\0') - return false; - - char *end; - *major = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (*end != '.') - return false; - - str = end + 1; - *minor = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (*end != '.') - return false; - - str = end + 1; - *micro = (int)strtol(str, &end, 10); - if (*str != '\0' && *end == '\0') - return true; - if (str == end) - return false; - *had_extra = true; - return true; -} - -enum DarwinPlatformKind { - MacOS, - IPhoneOS, - IPhoneOSSimulator, -}; - -struct DarwinPlatform { - DarwinPlatformKind kind; - int major; - int minor; - int micro; -}; - -static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { - CodeGen *g = lj->codegen; - - if (g->mmacosx_version_min) { - platform->kind = MacOS; - } else if (g->mios_version_min) { - platform->kind = IPhoneOS; - } else if (g->zig_target->os == OsMacOSX) { - platform->kind = MacOS; - g->mmacosx_version_min = buf_create_from_str("10.14"); - } else { - zig_panic("unable to infer -mmacosx-version-min or -mios-version-min"); - } - - bool had_extra; - if (platform->kind == MacOS) { - if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min), - &platform->major, &platform->minor, &platform->micro, &had_extra) || - had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100) - { - zig_panic("invalid -mmacosx-version-min"); - } - } else if (platform->kind == IPhoneOS) { - if (!darwin_get_release_version(buf_ptr(g->mios_version_min), - &platform->major, &platform->minor, &platform->micro, &had_extra) || - had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100) - { - zig_panic("invalid -mios-version-min"); - } - } else { - zig_unreachable(); - } - - if (platform->kind == IPhoneOS && - (g->zig_target->arch == ZigLLVM_x86 || - g->zig_target->arch == ZigLLVM_x86_64)) - { - platform->kind = IPhoneOSSimulator; - } -} - static void construct_linker_job_macho(LinkJob *lj) { CodeGen *g = lj->codegen; @@ -2507,25 +2414,25 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append("-arch"); lj->args.append(get_darwin_arch_string(g->zig_target)); - DarwinPlatform platform; - get_darwin_platform(lj, &platform); - switch (platform.kind) { - case MacOS: + if (g->zig_target->glibc_or_darwin_version != nullptr) { + if (g->zig_target->os == OsMacOSX) { lj->args.append("-macosx_version_min"); - break; - case IPhoneOS: - lj->args.append("-iphoneos_version_min"); - break; - case IPhoneOSSimulator: - lj->args.append("-ios_simulator_version_min"); - break; - } - Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro); - lj->args.append(buf_ptr(version_string)); - - lj->args.append("-sdk_version"); - lj->args.append(buf_ptr(version_string)); + } else if (g->zig_target->os == OsIOS) { + if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64) { + lj->args.append("-ios_simulator_version_min"); + } else { + lj->args.append("-iphoneos_version_min"); + } + } + Buf *version_string = buf_sprintf("%d.%d.%d", + g->zig_target->glibc_or_darwin_version->major, + g->zig_target->glibc_or_darwin_version->minor, + g->zig_target->glibc_or_darwin_version->patch); + lj->args.append(buf_ptr(version_string)); + lj->args.append("-sdk_version"); + lj->args.append(buf_ptr(version_string)); + } if (g->out_type == OutTypeExe) { lj->args.append("-pie"); diff --git a/src/main.cpp b/src/main.cpp index f741cafd40..f471bda374 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -127,8 +127,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --subsystem [subsystem] (windows) /SUBSYSTEM: to the linker\n" " -F[dir] (darwin) add search path for frameworks\n" " -framework [name] (darwin) link against framework\n" - " -mios-version-min [ver] (darwin) set iOS deployment target\n" - " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" " --ver-minor [ver] dynamic library semver minor version\n" " --ver-patch [ver] dynamic library semver patch version\n" @@ -414,8 +412,6 @@ static int main0(int argc, char **argv) { bool have_libc = false; const char *target_string = nullptr; bool rdynamic = false; - const char *mmacosx_version_min = nullptr; - const char *mios_version_min = nullptr; const char *linker_script = nullptr; Buf *version_script = nullptr; ZigList rpath_list = {0}; @@ -844,10 +840,6 @@ static int main0(int argc, char **argv) { cache_dir = argv[i]; } else if (strcmp(arg, "-target") == 0) { target_string = argv[i]; - } else if (strcmp(arg, "-mmacosx-version-min") == 0) { - mmacosx_version_min = argv[i]; - } else if (strcmp(arg, "-mios-version-min") == 0) { - mios_version_min = argv[i]; } else if (strcmp(arg, "-framework") == 0) { frameworks.append(argv[i]); } else if (strcmp(arg, "--linker-script") == 0) { @@ -1240,18 +1232,6 @@ static int main0(int argc, char **argv) { } codegen_set_rdynamic(g, rdynamic); - if (mmacosx_version_min && mios_version_min) { - fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n"); - return main_exit(root_progress_node, EXIT_FAILURE); - } - - if (mmacosx_version_min) { - codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min)); - } - - if (mios_version_min) { - codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min)); - } if (test_filter) { codegen_set_test_filter(g, buf_create_from_str(test_filter)); diff --git a/src/stage2.cpp b/src/stage2.cpp index bc8e65fd56..67a518e1fa 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -186,7 +186,7 @@ static void get_native_target(ZigTarget *target) { target->abi = target_default_abi(target->arch, target->os); } if (target_is_glibc(target)) { - target->glibc_version = heap::c_allocator.create(); + target->glibc_or_darwin_version = heap::c_allocator.create(); target_init_default_glibc_version(target); } } diff --git a/src/stage2.h b/src/stage2.h index 96222e3138..20311788b2 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -270,14 +270,12 @@ enum Os { }; // ABI warning -struct ZigGLibCVersion { - uint32_t major; // always 2 +struct Stage2SemVer { + uint32_t major; uint32_t minor; uint32_t patch; }; -struct Stage2TargetData; - // ABI warning struct ZigTarget { enum ZigLLVM_ArchType arch; @@ -288,7 +286,8 @@ struct ZigTarget { bool is_native; - struct ZigGLibCVersion *glibc_version; // null means default + // null means default. this is double-purposed to be darwin min version + struct Stage2SemVer *glibc_or_darwin_version; const char *llvm_cpu_name; const char *llvm_cpu_features; diff --git a/src/target.cpp b/src/target.cpp index 4df2cfca85..96ac2e1666 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -347,7 +347,7 @@ const char *target_abi_name(ZigLLVM_EnvironmentType abi) { return ZigLLVMGetEnvironmentTypeName(abi); } -Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { +Error target_parse_glibc_version(Stage2SemVer *glibc_ver, const char *text) { glibc_ver->major = 2; glibc_ver->minor = 0; glibc_ver->patch = 0; @@ -371,7 +371,7 @@ Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { } void target_init_default_glibc_version(ZigTarget *target) { - *target->glibc_version = {2, 17, 0}; + *target->glibc_or_darwin_version = {2, 17, 0}; } Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) { diff --git a/src/target.hpp b/src/target.hpp index e72b6a6f49..9c6e8ce46e 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -46,7 +46,7 @@ Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arc Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); -Error target_parse_glibc_version(ZigGLibCVersion *out, const char *text); +Error target_parse_glibc_version(Stage2SemVer *out, const char *text); void target_init_default_glibc_version(ZigTarget *target); size_t target_arch_count(void); diff --git a/test/cli.zig b/test/cli.zig index bc5a29be44..117c714a29 100644 --- a/test/cli.zig +++ b/test/cli.zig @@ -92,7 +92,7 @@ fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void { fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void { _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-exe" }); const run_result = try exec(dir_path, &[_][]const u8{ zig_exe, "build", "run" }); - testing.expect(std.mem.eql(u8, run_result.stderr, "All your base are belong to us.\n")); + testing.expect(std.mem.eql(u8, run_result.stderr, "All your codebase are belong to us.\n")); } fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { -- cgit v1.2.3 From 500dde32d5cf59f5700fb3f69ae6c7a0defd8a93 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 28 Feb 2020 13:27:52 -0500 Subject: dynamic_linker becomes a field of std.zig.CrossTarget --- lib/std/build.zig | 12 +++--- lib/std/target.zig | 92 ++++++++++++++++++++++++++++++-------------- lib/std/zig/cross_target.zig | 17 ++++++-- lib/std/zig/system.zig | 77 ++++++++++++------------------------ src-self-hosted/stage2.zig | 15 ++++---- src/all_types.hpp | 1 - src/codegen.cpp | 19 ++------- src/link.cpp | 4 +- src/main.cpp | 11 +++--- src/stage2.cpp | 7 +++- src/stage2.h | 3 +- src/target.cpp | 4 +- src/target.hpp | 2 +- 13 files changed, 137 insertions(+), 127 deletions(-) (limited to 'src/stage2.cpp') diff --git a/lib/std/build.zig b/lib/std/build.zig index 7852828f7c..3ca59ae4cb 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1177,8 +1177,6 @@ pub const LibExeObjStep = struct { /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. glibc_multi_install_dir: ?[]const u8 = null, - dynamic_linker: ?[]const u8 = null, - /// Position Independent Code force_pic: ?bool = null, @@ -1978,6 +1976,11 @@ pub const LibExeObjStep = struct { } try zig_args.append(mcpu_buffer.toSliceConst()); } + + if (self.target.dynamic_linker.get()) |dynamic_linker| { + try zig_args.append("--dynamic-linker"); + try zig_args.append(dynamic_linker); + } } if (self.linker_script) |linker_script| { @@ -1985,11 +1988,6 @@ pub const LibExeObjStep = struct { zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; } - if (self.dynamic_linker) |dynamic_linker| { - try zig_args.append("--dynamic-linker"); - try zig_args.append(dynamic_linker); - } - if (self.version_script) |version_script| { try zig_args.append("--version-script"); try zig_args.append(builder.pathFromRoot(version_script)); diff --git a/lib/std/target.zig b/lib/std/target.zig index 6ecb679f29..3054c60467 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1099,16 +1099,52 @@ pub const Target = struct { } } + pub const DynamicLinker = struct { + /// Contains the memory used to store the dynamic linker path. This field should + /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator. + buffer: [255]u8 = undefined, + + /// Used to construct the dynamic linker path. This field should not be used + /// directly. See `get` and `set`. + max_byte: ?u8 = null, + + /// Asserts that the length is less than or equal to 255 bytes. + pub fn init(dl_or_null: ?[]const u8) DynamicLinker { + var result: DynamicLinker = undefined; + result.set(dl_or_null); + return result; + } + + /// The returned memory has the same lifetime as the `DynamicLinker`. + pub fn get(self: *const DynamicLinker) ?[]const u8 { + const m: usize = self.max_byte orelse return null; + return self.buffer[0 .. m + 1]; + } + + /// Asserts that the length is less than or equal to 255 bytes. + pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { + if (dl_or_null) |dl| { + mem.copy(u8, &self.buffer, dl); + self.max_byte = @intCast(u8, dl.len - 1); + } else { + self.max_byte = null; + } + } + }; + /// The result will be a byte index *pointing at the final byte*. In other words, length minus one. /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. - pub fn standardDynamicLinkerPath(self: Target, buffer: *[255]u8) ?u8 { + pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { + var result: DynamicLinker = .{}; const S = struct { - fn print(b: *[255]u8, comptime fmt: []const u8, args: var) u8 { - return @intCast(u8, (std.fmt.bufPrint(b, fmt, args) catch unreachable).len - 1); + fn print(r: *DynamicLinker, comptime fmt: []const u8, args: var) DynamicLinker { + r.max_byte = @intCast(u8, (std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1); + return r.*; } - fn copy(b: *[255]u8, s: []const u8) u8 { - mem.copy(u8, b, s); - return @intCast(u8, s.len - 1); + fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker { + mem.copy(u8, &r.buffer, s); + r.max_byte = @intCast(u8, s.len - 1); + return r.*; } }; const print = S.print; @@ -1116,7 +1152,7 @@ pub const Target = struct { if (self.isAndroid()) { const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; - return print(buffer, "/system/bin/linker{}", .{suffix}); + return print(&result, "/system/bin/linker{}", .{suffix}); } if (self.isMusl()) { @@ -1130,28 +1166,28 @@ pub const Target = struct { else => |arch| @tagName(arch), }; const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; - return print(buffer, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); + return print(&result, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); } switch (self.os.tag) { - .freebsd => return copy(buffer, "/libexec/ld-elf.so.1"), - .netbsd => return copy(buffer, "/libexec/ld.elf_so"), - .dragonfly => return copy(buffer, "/libexec/ld-elf.so.2"), + .freebsd => return copy(&result, "/libexec/ld-elf.so.1"), + .netbsd => return copy(&result, "/libexec/ld.elf_so"), + .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), .linux => switch (self.cpu.arch) { .i386, .sparc, .sparcel, - => return copy(buffer, "/lib/ld-linux.so.2"), + => return copy(&result, "/lib/ld-linux.so.2"), - .aarch64 => return copy(buffer, "/lib/ld-linux-aarch64.so.1"), - .aarch64_be => return copy(buffer, "/lib/ld-linux-aarch64_be.so.1"), - .aarch64_32 => return copy(buffer, "/lib/ld-linux-aarch64_32.so.1"), + .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"), + .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"), + .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"), .arm, .armeb, .thumb, .thumbeb, - => return copy(buffer, switch (self.getFloatAbi()) { + => return copy(&result, switch (self.getFloatAbi()) { .hard => "/lib/ld-linux-armhf.so.3", else => "/lib/ld-linux.so.3", }), @@ -1168,20 +1204,20 @@ pub const Target = struct { }; const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; - return print(buffer, "/lib{}/{}", .{ lib_suffix, loader }); + return print(&result, "/lib{}/{}", .{ lib_suffix, loader }); }, - .powerpc => return copy(buffer, "/lib/ld.so.1"), - .powerpc64, .powerpc64le => return copy(buffer, "/lib64/ld64.so.2"), - .s390x => return copy(buffer, "/lib64/ld64.so.1"), - .sparcv9 => return copy(buffer, "/lib64/ld-linux.so.2"), - .x86_64 => return copy(buffer, switch (self.abi) { + .powerpc => return copy(&result, "/lib/ld.so.1"), + .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"), + .s390x => return copy(&result, "/lib64/ld64.so.1"), + .sparcv9 => return copy(&result, "/lib64/ld-linux.so.2"), + .x86_64 => return copy(&result, switch (self.abi) { .gnux32 => "/libx32/ld-linux-x32.so.2", else => "/lib64/ld-linux-x86-64.so.2", }), - .riscv32 => return copy(buffer, "/lib/ld-linux-riscv32-ilp32.so.1"), - .riscv64 => return copy(buffer, "/lib/ld-linux-riscv64-lp64.so.1"), + .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"), + .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"), // Architectures in this list have been verified as not having a standard // dynamic linker path. @@ -1191,7 +1227,7 @@ pub const Target = struct { .bpfeb, .nvptx, .nvptx64, - => return null, + => return result, // TODO go over each item in this list and either move it to the above list, or // implement the standard dynamic linker path code for it. @@ -1217,7 +1253,7 @@ pub const Target = struct { .lanai, .renderscript32, .renderscript64, - => return null, + => return result, }, // Operating systems in this list have been verified as not having a standard @@ -1232,7 +1268,7 @@ pub const Target = struct { .emscripten, .wasi, .other, - => return null, + => return result, // TODO go over each item in this list and either move it to the above list, or // implement the standard dynamic linker path code for it. @@ -1259,7 +1295,7 @@ pub const Target = struct { .amdpal, .hermit, .hurd, - => return null, + => return result, } } }; diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index c7fd1f0464..212bc8eb9a 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -40,6 +40,10 @@ pub const CrossTarget = struct { /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. glibc_version: ?SemVer = null, + /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path + /// based on the `os_tag`. + dynamic_linker: DynamicLinker = DynamicLinker{}, + pub const OsVersion = union(enum) { none: void, semver: SemVer, @@ -48,6 +52,8 @@ pub const CrossTarget = struct { pub const SemVer = std.builtin.Version; + pub const DynamicLinker = Target.DynamicLinker; + pub fn fromTarget(target: Target) CrossTarget { var result: CrossTarget = .{ .cpu_arch = target.cpu.arch, @@ -170,6 +176,10 @@ pub const CrossTarget = struct { /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". cpu_features: ?[]const u8 = null, + /// Absolute path to dynamic linker, to override the default, which is either a natively + /// detected path, or a standard path. + dynamic_linker: ?[]const u8 = null, + /// If this is provided, the function will populate some information about parsing failures, /// so that user-friendly error messages can be delivered. diagnostics: ?*Diagnostics = null, @@ -199,8 +209,9 @@ pub const CrossTarget = struct { var dummy_diags: ParseOptions.Diagnostics = undefined; const diags = args.diagnostics orelse &dummy_diags; - // Start with everything initialized to default values. - var result: CrossTarget = .{}; + var result: CrossTarget = .{ + .dynamic_linker = DynamicLinker.init(args.dynamic_linker), + }; var it = mem.separate(args.arch_os_abi, "-"); const arch_name = it.next().?; @@ -446,7 +457,7 @@ pub const CrossTarget = struct { return self.cpu_arch == null and self.cpu_model == null and self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and self.os_tag == null and self.os_version_min == null and self.os_version_max == null and - self.abi == null; + self.abi == null and self.dynamic_linker.get() == null; } pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index ffae5c6015..44ff9af674 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -168,14 +168,9 @@ pub const NativePaths = struct { pub const NativeTargetInfo = struct { target: Target, - /// Contains the memory used to store the dynamic linker path. This field should - /// not be used directly. See `dynamicLinker` and `setDynamicLinker`. This field - /// exists so that this API requires no allocator. - dynamic_linker_buffer: [255]u8 = undefined, + dynamic_linker: DynamicLinker = DynamicLinker{}, - /// Used to construct the dynamic linker path. This field should not be used - /// directly. See `dynamicLinker` and `setDynamicLinker`. - dynamic_linker_max: ?u8 = null, + pub const DynamicLinker = Target.DynamicLinker; pub const DetectError = error{ OutOfMemory, @@ -220,21 +215,6 @@ pub const NativeTargetInfo = struct { return detectAbiAndDynamicLinker(allocator, cpu, os); } - /// The returned memory has the same lifetime as the `NativeTargetInfo`. - pub fn dynamicLinker(self: *const NativeTargetInfo) ?[]const u8 { - const m: usize = self.dynamic_linker_max orelse return null; - return self.dynamic_linker_buffer[0 .. m + 1]; - } - - pub fn setDynamicLinker(self: *NativeTargetInfo, dl_or_null: ?[]const u8) void { - if (dl_or_null) |dl| { - mem.copy(u8, &self.dynamic_linker_buffer, dl); - self.dynamic_linker_max = @intCast(u8, dl.len - 1); - } else { - self.dynamic_linker_max = null; - } - } - /// First we attempt to use the executable's own binary. If it is dynamically /// linked, then it should answer both the C ABI question and the dynamic linker question. /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then @@ -273,15 +253,14 @@ pub const NativeTargetInfo = struct { .os = os, .abi = abi, }; - const ld_info = &ld_info_list_buffer[ld_info_list_len]; - ld_info_list_len += 1; + const ld = target.standardDynamicLinkerPath(); + if (ld.get() == null) continue; - ld_info.* = .{ - .ld_path_buffer = undefined, - .ld_path_max = undefined, + ld_info_list_buffer[ld_info_list_len] = .{ + .ld = ld, .abi = abi, }; - ld_info.ld_path_max = target.standardDynamicLinkerPath(&ld_info.ld_path_buffer) orelse continue; + ld_info_list_len += 1; } const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; @@ -298,7 +277,7 @@ pub const NativeTargetInfo = struct { // This is O(N^M) but typical case here is N=2 and M=10. find_ld: for (lib_paths) |lib_path| { for (ld_info_list) |ld_info| { - const standard_ld_basename = fs.path.basename(ld_info.ldPath()); + const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { found_ld_info = ld_info; found_ld_path = lib_path; @@ -329,8 +308,8 @@ pub const NativeTargetInfo = struct { .os = os_adjusted, .abi = found_ld_info.abi, }, + .dynamic_linker = DynamicLinker.init(found_ld_path), }; - result.setDynamicLinker(found_ld_path); return result; } @@ -472,18 +451,18 @@ pub const NativeTargetInfo = struct { elf.PT_INTERP => { const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); - if (p_filesz > result.dynamic_linker_buffer.len) return error.NameTooLong; - _ = try preadFull(env_file, result.dynamic_linker_buffer[0..p_filesz], p_offset, p_filesz); + if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; + _ = try preadFull(env_file, result.dynamic_linker.buffer[0..p_filesz], p_offset, p_filesz); // PT_INTERP includes a null byte in p_filesz. const len = p_filesz - 1; - // dynamic_linker_max is "max", not "len". - // We know it will fit in u8 because we check against dynamic_linker_buffer.len above. - result.dynamic_linker_max = @intCast(u8, len - 1); + // dynamic_linker.max_byte is "max", not "len". + // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. + result.dynamic_linker.max_byte = @intCast(u8, len - 1); // Use it to determine ABI. - const full_ld_path = result.dynamic_linker_buffer[0..len]; + const full_ld_path = result.dynamic_linker.buffer[0..len]; for (ld_info_list) |ld_info| { - const standard_ld_basename = fs.path.basename(ld_info.ldPath()); + const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { result.target.abi = ld_info.abi; break; @@ -679,26 +658,20 @@ pub const NativeTargetInfo = struct { } fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os) !NativeTargetInfo { - var result: NativeTargetInfo = .{ - .target = .{ - .cpu = cpu, - .os = os, - .abi = Target.Abi.default(cpu.arch, os), - }, + const target: Target = .{ + .cpu = cpu, + .os = os, + .abi = Target.Abi.default(cpu.arch, os), + }; + return NativeTargetInfo{ + .target = target, + .dynamic_linker = target.standardDynamicLinkerPath(), }; - result.dynamic_linker_max = result.target.standardDynamicLinkerPath(&result.dynamic_linker_buffer); - return result; } const LdInfo = struct { - ld_path_buffer: [255]u8, - ld_path_max: u8, + ld: DynamicLinker, abi: Target.Abi, - - pub fn ldPath(self: *const LdInfo) []const u8 { - const m: usize = self.ld_path_max; - return self.ld_path_buffer[0 .. m + 1]; - } }; fn elfInt(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_64) { diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 3dae15056e..726c65937e 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -651,8 +651,9 @@ export fn stage2_target_parse( target: *Stage2Target, zig_triple: ?[*:0]const u8, mcpu: ?[*:0]const u8, + dynamic_linker: ?[*:0]const u8, ) Error { - stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) { + stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) { error.OutOfMemory => return .OutOfMemory, error.UnknownArchitecture => return .UnknownArchitecture, error.UnknownOperatingSystem => return .UnknownOperatingSystem, @@ -676,14 +677,17 @@ fn stage2TargetParse( stage1_target: *Stage2Target, zig_triple_oz: ?[*:0]const u8, mcpu_oz: ?[*:0]const u8, + dynamic_linker_oz: ?[*:0]const u8, ) !void { const target: CrossTarget = if (zig_triple_oz) |zig_triple_z| blk: { const zig_triple = mem.toSliceConst(u8, zig_triple_z); const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; + const dynamic_linker = if (dynamic_linker_oz) |dl_z| mem.toSliceConst(u8, dl_z) else null; var diags: CrossTarget.ParseOptions.Diagnostics = .{}; break :blk CrossTarget.parse(.{ .arch_os_abi = zig_triple, .cpu_features = mcpu, + .dynamic_linker = dynamic_linker, .diagnostics = &diags, }) catch |err| switch (err) { error.UnknownCpuModel => { @@ -1170,7 +1174,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) if (cross_target.os_tag == null) { adjusted_target.os = detected_info.target.os; - if (detected_info.dynamicLinker()) |dl| { + if (detected_info.dynamic_linker.get()) |dl| { have_native_dl = true; dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); } @@ -1182,11 +1186,8 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) } } if (!have_native_dl) { - var buf: [255]u8 = undefined; - dynamic_linker_ptr.* = if (adjusted_target.standardDynamicLinkerPath(&buf)) |m| - try mem.dupeZ(std.heap.c_allocator, u8, buf[0 .. @as(usize, m) + 1]) - else - null; + const dl = adjusted_target.standardDynamicLinkerPath(); + dynamic_linker_ptr.* = if (dl.get()) |s| try mem.dupeZ(std.heap.c_allocator, u8, s) else null; } return adjusted_target; } diff --git a/src/all_types.hpp b/src/all_types.hpp index 838709b9c0..9f6bfd80a5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2255,7 +2255,6 @@ struct CodeGen { Buf *test_name_prefix; Buf *zig_lib_dir; Buf *zig_std_dir; - Buf *dynamic_linker_path; Buf *version_script_path; const char **llvm_argv; diff --git a/src/codegen.cpp b/src/codegen.cpp index 8ae730616d..62f2c7a8ba 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8832,19 +8832,6 @@ static void init(CodeGen *g) { } } -static void detect_dynamic_linker(CodeGen *g) { - if (g->dynamic_linker_path != nullptr) - return; - if (!g->have_dynamic_link) - return; - if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) - return; - - if (g->zig_target->dynamic_linker != nullptr) { - g->dynamic_linker_path = buf_create_from_str(g->zig_target->dynamic_linker); - } -} - static void detect_libc(CodeGen *g) { Error err; @@ -10285,6 +10272,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); } + if (g->zig_target->dynamic_linker != nullptr) { + cache_str(ch, g->zig_target->dynamic_linker); + } cache_int(ch, detect_subsystem(g)); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); @@ -10325,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_str(ch, g->libc->msvc_lib_dir); cache_str(ch, g->libc->kernel32_lib_dir); } - cache_buf_opt(ch, g->dynamic_linker_path); cache_buf_opt(ch, g->version_script_path); // gen_c_objects appends objects to g->link_objects which we want to include in the hash @@ -10422,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { g->have_err_ret_tracing = detect_err_ret_tracing(g); g->have_sanitize_c = detect_sanitize_c(g); detect_libc(g); - detect_dynamic_linker(g); Buf digest = BUF_INIT; if (g->enable_cache) { @@ -10619,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o child_gen->verbose_cc = parent_gen->verbose_cc; child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; child_gen->llvm_argv = parent_gen->llvm_argv; - child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; diff --git a/src/link.cpp b/src/link.cpp index 588771d8bf..03534db3b2 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { } if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { - assert(g->dynamic_linker_path != nullptr); + assert(g->zig_target->dynamic_linker != nullptr); lj->args.append("-dynamic-linker"); - lj->args.append(buf_ptr(g->dynamic_linker_path)); + lj->args.append(g->zig_target->dynamic_linker); } } diff --git a/src/main.cpp b/src/main.cpp index f471bda374..92d08bed4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -401,7 +401,7 @@ static int main0(int argc, char **argv) { bool link_eh_frame_hdr = false; ErrColor color = ErrColorAuto; CacheOpt enable_cache = CacheOptAuto; - Buf *dynamic_linker = nullptr; + const char *dynamic_linker = nullptr; const char *libc_txt = nullptr; ZigList clang_argv = {0}; ZigList lib_dirs = {0}; @@ -496,7 +496,7 @@ static int main0(int argc, char **argv) { os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); ZigTarget target; - if ((err = target_parse_triple(&target, "native", nullptr))) { + if ((err = target_parse_triple(&target, "native", nullptr, nullptr))) { fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); return EXIT_FAILURE; } @@ -766,7 +766,7 @@ static int main0(int argc, char **argv) { } else if (strcmp(arg, "--name") == 0) { out_name = argv[i]; } else if (strcmp(arg, "--dynamic-linker") == 0) { - dynamic_linker = buf_create_from_str(argv[i]); + dynamic_linker = argv[i]; } else if (strcmp(arg, "--libc") == 0) { libc_txt = argv[i]; } else if (strcmp(arg, "-D") == 0) { @@ -968,7 +968,7 @@ static int main0(int argc, char **argv) { init_all_targets(); ZigTarget target; - if ((err = target_parse_triple(&target, target_string, mcpu))) { + if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { fprintf(stderr, "invalid target: %s\n" "See `%s targets` to display valid targets.\n", err_str(err), arg0); return print_error_usage(arg0); @@ -1193,7 +1193,6 @@ static int main0(int argc, char **argv) { codegen_set_strip(g, strip); g->is_dynamic = is_dynamic; - g->dynamic_linker_path = dynamic_linker; g->verbose_tokenize = verbose_tokenize; g->verbose_ast = verbose_ast; g->verbose_link = verbose_link; @@ -1320,7 +1319,7 @@ static int main0(int argc, char **argv) { return main_exit(root_progress_node, EXIT_SUCCESS); } else if (cmd == CmdTest) { ZigTarget native; - if ((err = target_parse_triple(&native, "native", nullptr))) { + if ((err = target_parse_triple(&native, "native", nullptr, nullptr))) { fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); return EXIT_FAILURE; } diff --git a/src/stage2.cpp b/src/stage2.cpp index 67a518e1fa..1f6cb2d6aa 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -191,7 +191,9 @@ static void get_native_target(ZigTarget *target) { } } -Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) { +Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, + const char *dynamic_linker) +{ Error err; if (zig_triple == nullptr) { @@ -249,6 +251,9 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons target->cache_hash = "\n\n"; } + if (dynamic_linker != nullptr) { + target->dynamic_linker = dynamic_linker; + } return ErrorNone; } diff --git a/src/stage2.h b/src/stage2.h index 20311788b2..b73269f4e8 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -298,7 +298,8 @@ struct ZigTarget { }; // ABI warning -ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu); +ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, + const char *dynamic_linker); // ABI warning diff --git a/src/target.cpp b/src/target.cpp index 96ac2e1666..f0030e05ac 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -410,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si return ErrorUnknownABI; } -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) { - return stage2_target_parse(target, triple, mcpu); +Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { + return stage2_target_parse(target, triple, mcpu, dynamic_linker); } const char *target_arch_name(ZigLLVM_ArchType arch) { diff --git a/src/target.hpp b/src/target.hpp index 9c6e8ce46e..01f2c6b168 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -41,7 +41,7 @@ enum CIntType { CIntTypeCount, }; -Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu); +Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); -- cgit v1.2.3