authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-23 09:35:56-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-02-23 09:35:56-05:00
log6fd8d455bcc6765e7411fa00d23dca1eb270aac9
tree047a654678400140fd46ffa64d7c4248050247cd
parent52bb71867d8d6e738eefb7dafead875eb21a4ae7
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

better libc detection (#1996)

* better libc detection This introduces a new command `zig libc` which prints the various paths of libc files. It outputs them to stdout in a simple text file format that it is capable of parsing. You can use `zig libc libc.txt` to validate a file. These arguments are gone: --libc-lib-dir [path] directory where libc crt1.o resides --libc-static-lib-dir [path] directory where libc crtbegin.o resides --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides Instead we have this argument: --libc [file] Provide a file which specifies libc paths This is used to pass a libc text file (which can be generated with `zig libc`). So it is easier to manage multiple cross compilation environments. `--cache on` now works when linking against libc. `ZigTarget` now has a bool field `is_native` Better error messaging when you try to link against libc or use `@cImport` but the various paths cannot be found. It should also be faster. * save native_libc.txt in zig-cache This avoids having to detect libc at runtime on every invocation.

18 files changed, 774 insertions(+), 592 deletions(-)

CMakeLists.txt+1
...@@ -414,6 +414,7 @@ set(ZIG_SOURCES...@@ -414,6 +414,7 @@ set(ZIG_SOURCES
414 "${CMAKE_SOURCE_DIR}/src/error.cpp"414 "${CMAKE_SOURCE_DIR}/src/error.cpp"
415 "${CMAKE_SOURCE_DIR}/src/ir.cpp"415 "${CMAKE_SOURCE_DIR}/src/ir.cpp"
416 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"416 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
417 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
417 "${CMAKE_SOURCE_DIR}/src/link.cpp"418 "${CMAKE_SOURCE_DIR}/src/link.cpp"
418 "${CMAKE_SOURCE_DIR}/src/main.cpp"419 "${CMAKE_SOURCE_DIR}/src/main.cpp"
419 "${CMAKE_SOURCE_DIR}/src/os.cpp"420 "${CMAKE_SOURCE_DIR}/src/os.cpp"
src/all_types.hpp+11-16
...@@ -18,6 +18,7 @@...@@ -18,6 +18,7 @@
18#include "bigfloat.hpp"18#include "bigfloat.hpp"
19#include "target.hpp"19#include "target.hpp"
20#include "tokenizer.hpp"20#include "tokenizer.hpp"
21#include "libc_installation.hpp"
2122
22struct AstNode;23struct AstNode;
23struct ImportTableEntry;24struct ImportTableEntry;
...@@ -1743,6 +1744,9 @@ struct CodeGen {...@@ -1743,6 +1744,9 @@ struct CodeGen {
1743 Buf *wanted_output_file_path;1744 Buf *wanted_output_file_path;
1744 Buf cache_dir;1745 Buf cache_dir;
17451746
1747 Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir.
1748 Buf *zig_std_special_dir; // Cannot be overridden; derived from zig_lib_dir.
1749
1746 IrInstruction *invalid_instruction;1750 IrInstruction *invalid_instruction;
1747 IrInstruction *unreach_instruction;1751 IrInstruction *unreach_instruction;
17481752
...@@ -1791,6 +1795,8 @@ struct CodeGen {...@@ -1791,6 +1795,8 @@ struct CodeGen {
1791 bool system_linker_hack;1795 bool system_linker_hack;
17921796
1793 //////////////////////////// Participates in Input Parameter Cache Hash1797 //////////////////////////// Participates in Input Parameter Cache Hash
1798 /////// Note: there is a separate cache hash for builtin.zig, when adding fields,
1799 /////// consider if they need to go into both.
1794 ZigList<LinkLib *> link_libs_list;1800 ZigList<LinkLib *> link_libs_list;
1795 // add -framework [name] args to linker1801 // add -framework [name] args to linker
1796 ZigList<Buf *> darwin_frameworks;1802 ZigList<Buf *> darwin_frameworks;
...@@ -1801,6 +1807,8 @@ struct CodeGen {...@@ -1801,6 +1807,8 @@ struct CodeGen {
1801 ZigList<Buf *> assembly_files;1807 ZigList<Buf *> assembly_files;
1802 ZigList<const char *> lib_dirs;1808 ZigList<const char *> lib_dirs;
18031809
1810 ZigLibCInstallation *libc;
1811
1804 size_t version_major;1812 size_t version_major;
1805 size_t version_minor;1813 size_t version_minor;
1806 size_t version_patch;1814 size_t version_patch;
...@@ -1809,14 +1817,13 @@ struct CodeGen {...@@ -1809,14 +1817,13 @@ struct CodeGen {
1809 EmitFileType emit_file_type;1817 EmitFileType emit_file_type;
1810 BuildMode build_mode;1818 BuildMode build_mode;
1811 OutType out_type;1819 OutType out_type;
1812 ZigTarget zig_target;1820 const ZigTarget *zig_target;
1813 TargetSubsystem subsystem;1821 TargetSubsystem subsystem;
1814 ValgrindSupport valgrind_support;1822 ValgrindSupport valgrind_support;
1815 bool is_static;1823 bool is_static;
1816 bool strip_debug_symbols;1824 bool strip_debug_symbols;
1817 bool is_test_build;1825 bool is_test_build;
1818 bool is_single_threaded;1826 bool is_single_threaded;
1819 bool is_native_target;
1820 bool linker_rdynamic;1827 bool linker_rdynamic;
1821 bool each_lib_rpath;1828 bool each_lib_rpath;
1822 bool disable_pic;1829 bool disable_pic;
...@@ -1827,26 +1834,14 @@ struct CodeGen {...@@ -1827,26 +1834,14 @@ struct CodeGen {
1827 Buf *test_filter;1834 Buf *test_filter;
1828 Buf *test_name_prefix;1835 Buf *test_name_prefix;
1829 PackageTableEntry *root_package;1836 PackageTableEntry *root_package;
1837 Buf *zig_lib_dir;
1838 Buf *zig_std_dir;
18301839
1831 const char **llvm_argv;1840 const char **llvm_argv;
1832 size_t llvm_argv_len;1841 size_t llvm_argv_len;
18331842
1834 const char **clang_argv;1843 const char **clang_argv;
1835 size_t clang_argv_len;1844 size_t clang_argv_len;
1836
1837 //////////////////////////// Unsorted
1838
1839 Buf *libc_lib_dir;
1840 Buf *libc_static_lib_dir;
1841 Buf *libc_include_dir;
1842 Buf *msvc_lib_dir;
1843 Buf *kernel32_lib_dir;
1844 Buf *zig_lib_dir;
1845 Buf *zig_std_dir;
1846 Buf *zig_c_headers_dir;
1847 Buf *zig_std_special_dir;
1848 Buf *dynamic_linker;
1849 ZigWindowsSDK *win_sdk;
1850};1845};
18511846
1852enum VarLinkage {1847enum VarLinkage {
src/analyze.cpp+5-193
...@@ -1102,10 +1102,10 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1102,10 +1102,10 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
1102 if (type_is_c_abi_int(g, fn_type_id->return_type)) {1102 if (type_is_c_abi_int(g, fn_type_id->return_type)) {
1103 return false;1103 return false;
1104 }1104 }
1105 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {1105 if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
1106 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);1106 X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
1107 return abi_class == X64CABIClass_MEMORY;1107 return abi_class == X64CABIClass_MEMORY;
1108 } else if (target_is_arm(&g->zig_target)) {1108 } else if (target_is_arm(g->zig_target)) {
1109 return type_size(g, fn_type_id->return_type) > 16;1109 return type_size(g, fn_type_id->return_type) > 16;
1110 }1110 }
1111 zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481");1111 zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481");
...@@ -3304,16 +3304,16 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi...@@ -3304,16 +3304,16 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi
3304 g->have_c_main = true;3304 g->have_c_main = true;
3305 g->subsystem = TargetSubsystemConsole;3305 g->subsystem = TargetSubsystemConsole;
3306 } else if (buf_eql_str(symbol_name, "WinMain") &&3306 } else if (buf_eql_str(symbol_name, "WinMain") &&
3307 g->zig_target.os == OsWindows)3307 g->zig_target->os == OsWindows)
3308 {3308 {
3309 g->have_winmain = true;3309 g->have_winmain = true;
3310 g->subsystem = TargetSubsystemWindows;3310 g->subsystem = TargetSubsystemWindows;
3311 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&3311 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
3312 g->zig_target.os == OsWindows)3312 g->zig_target->os == OsWindows)
3313 {3313 {
3314 g->have_winmain_crt_startup = true;3314 g->have_winmain_crt_startup = true;
3315 } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&3315 } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
3316 g->zig_target.os == OsWindows)3316 g->zig_target->os == OsWindows)
3317 {3317 {
3318 g->have_dllmain_crt_startup = true;3318 g->have_dllmain_crt_startup = true;
3319 }3319 }
...@@ -4651,186 +4651,6 @@ bool handle_is_ptr(ZigType *type_entry) {...@@ -4651,186 +4651,6 @@ bool handle_is_ptr(ZigType *type_entry) {
4651 zig_unreachable();4651 zig_unreachable();
4652}4652}
46534653
4654static ZigWindowsSDK *get_windows_sdk(CodeGen *g) {
4655 if (g->win_sdk == nullptr) {
4656 if (zig_find_windows_sdk(&g->win_sdk)) {
4657 fprintf(stderr, "unable to determine windows sdk path\n");
4658 exit(1);
4659 }
4660 }
4661 assert(g->win_sdk != nullptr);
4662 return g->win_sdk;
4663}
4664
4665
4666static Buf *get_linux_libc_lib_path(const char *o_file) {
4667 const char *cc_exe = getenv("CC");
4668 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
4669 ZigList<const char *> args = {};
4670 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
4671 Termination term;
4672 Buf *out_stderr = buf_alloc();
4673 Buf *out_stdout = buf_alloc();
4674 Error err;
4675 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
4676 zig_panic("unable to determine libc lib path: executing C compiler: %s", err_str(err));
4677 }
4678 if (term.how != TerminationIdClean || term.code != 0) {
4679 zig_panic("unable to determine libc lib path: executing C compiler command failed");
4680 }
4681 if (buf_ends_with_str(out_stdout, "\n")) {
4682 buf_resize(out_stdout, buf_len(out_stdout) - 1);
4683 }
4684 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
4685 zig_panic("unable to determine libc lib path: C compiler could not find %s", o_file);
4686 }
4687 Buf *result = buf_alloc();
4688 os_path_dirname(out_stdout, result);
4689 return result;
4690}
4691
4692static Buf *get_posix_libc_include_path(void) {
4693 const char *cc_exe = getenv("CC");
4694 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
4695 ZigList<const char *> args = {};
4696 args.append("-E");
4697 args.append("-Wp,-v");
4698 args.append("-xc");
4699 args.append("/dev/null");
4700 Termination term;
4701 Buf *out_stderr = buf_alloc();
4702 Buf *out_stdout = buf_alloc();
4703 Error err;
4704 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
4705 zig_panic("unable to determine libc include path: executing C compiler: %s", err_str(err));
4706 }
4707 if (term.how != TerminationIdClean || term.code != 0) {
4708 zig_panic("unable to determine libc include path: executing C compiler command failed");
4709 }
4710 char *prev_newline = buf_ptr(out_stderr);
4711 ZigList<const char *> search_paths = {};
4712 for (;;) {
4713 char *newline = strchr(prev_newline, '\n');
4714 if (newline == nullptr) {
4715 break;
4716 }
4717 *newline = 0;
4718 if (prev_newline[0] == ' ') {
4719 search_paths.append(prev_newline);
4720 }
4721 prev_newline = newline + 1;
4722 }
4723 if (search_paths.length == 0) {
4724 zig_panic("unable to determine libc include path: even C compiler does not know where libc headers are");
4725 }
4726 for (size_t i = 0; i < search_paths.length; i += 1) {
4727 // search in reverse order
4728 const char *search_path = search_paths.items[search_paths.length - i - 1];
4729 // cut off spaces
4730 while (*search_path == ' ') {
4731 search_path += 1;
4732 }
4733 Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
4734 bool exists;
4735 if ((err = os_file_exists(stdlib_path, &exists))) {
4736 exists = false;
4737 }
4738 if (exists) {
4739 return buf_create_from_str(search_path);
4740 }
4741 }
4742 zig_panic("unable to determine libc include path: stdlib.h not found in C compiler search paths");
4743}
4744
4745void find_libc_include_path(CodeGen *g) {
4746 if (g->libc_include_dir == nullptr) {
4747 if (!g->is_native_target) {
4748 return;
4749 }
4750
4751 if (g->zig_target.os == OsWindows) {
4752 ZigWindowsSDK *sdk = get_windows_sdk(g);
4753 g->libc_include_dir = buf_alloc();
4754 if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) {
4755 fprintf(stderr, "Unable to determine libc include path. --libc-include-dir");
4756 exit(1);
4757 }
4758 } else if (g->zig_target.os == OsLinux ||
4759 g->zig_target.os == OsMacOSX ||
4760 g->zig_target.os == OsFreeBSD ||
4761 g->zig_target.os == OsNetBSD)
4762 {
4763 g->libc_include_dir = get_posix_libc_include_path();
4764 } else {
4765 fprintf(stderr, "Unable to determine libc include path.\n"
4766 "TODO: implement finding libc at runtime for other operating systems.\n"
4767 "in the meantime, you can use as a workaround: --libc-include-dir\n");
4768 exit(1);
4769 }
4770 }
4771 assert(buf_len(g->libc_include_dir) != 0);
4772}
4773
4774void find_libc_lib_path(CodeGen *g) {
4775 // later we can handle this better by reporting an error via the normal mechanism
4776 if (g->libc_lib_dir == nullptr ||
4777 (g->zig_target.os == OsWindows && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr)))
4778 {
4779 if (g->zig_target.os == OsWindows) {
4780 ZigWindowsSDK *sdk = get_windows_sdk(g);
4781
4782 if (g->msvc_lib_dir == nullptr) {
4783 if (sdk->msvc_lib_dir_ptr == nullptr) {
4784 fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir");
4785 exit(1);
4786 }
4787 g->msvc_lib_dir = buf_create_from_mem(sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
4788 }
4789
4790 if (g->libc_lib_dir == nullptr) {
4791 Buf* ucrt_lib_path = buf_alloc();
4792 if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) {
4793 fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir");
4794 exit(1);
4795 }
4796 g->libc_lib_dir = ucrt_lib_path;
4797 }
4798
4799 if (g->kernel32_lib_dir == nullptr) {
4800 Buf* kern_lib_path = buf_alloc();
4801 if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) {
4802 fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir");
4803 exit(1);
4804 }
4805 g->kernel32_lib_dir = kern_lib_path;
4806 }
4807
4808 } else if (g->zig_target.os == OsLinux) {
4809 g->libc_lib_dir = get_linux_libc_lib_path("crt1.o");
4810 } else if ((g->zig_target.os == OsFreeBSD) || (g->zig_target.os == OsNetBSD)) {
4811 g->libc_lib_dir = buf_create_from_str("/usr/lib");
4812 } else {
4813 zig_panic("Unable to determine libc lib path.");
4814 }
4815 } else {
4816 assert(buf_len(g->libc_lib_dir) != 0);
4817 }
4818
4819 if (g->libc_static_lib_dir == nullptr) {
4820 if ((g->zig_target.os == OsWindows) && (g->msvc_lib_dir != NULL)) {
4821 return;
4822 } else if (g->zig_target.os == OsLinux) {
4823 g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o");
4824 } else if ((g->zig_target.os == OsFreeBSD) || (g->zig_target.os == OsNetBSD)) {
4825 g->libc_static_lib_dir = buf_create_from_str("/usr/lib");
4826 } else {
4827 zig_panic("Unable to determine libc static lib path.");
4828 }
4829 } else {
4830 assert(buf_len(g->libc_static_lib_dir) != 0);
4831 }
4832}
4833
4834static uint32_t hash_ptr(void *ptr) {4654static uint32_t hash_ptr(void *ptr) {
4835 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);4655 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);
4836}4656}
...@@ -6736,14 +6556,6 @@ LinkLib *add_link_lib(CodeGen *g, Buf *name) {...@@ -6736,14 +6556,6 @@ LinkLib *add_link_lib(CodeGen *g, Buf *name) {
6736 if (is_libc && g->libc_link_lib != nullptr)6556 if (is_libc && g->libc_link_lib != nullptr)
6737 return g->libc_link_lib;6557 return g->libc_link_lib;
67386558
6739 if (g->enable_cache && is_libc && g->zig_target.os != OsMacOSX &&
6740 g->zig_target.os != OsIOS && g->zig_target.os != OsFreeBSD &&
6741 g->zig_target.os != OsNetBSD) {
6742 fprintf(stderr, "TODO linking against libc is currently incompatible with `--cache on`.\n"
6743 "Zig is not yet capable of determining whether the libc installation has changed on subsequent builds.\n");
6744 exit(1);
6745 }
6746
6747 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {6559 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
6748 LinkLib *existing_lib = g->link_libs_list.at(i);6560 LinkLib *existing_lib = g->link_libs_list.at(i);
6749 if (buf_eql_buf(existing_lib->name, name)) {6561 if (buf_eql_buf(existing_lib->name, name)) {
src/analyze.hpp-2
...@@ -40,8 +40,6 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type);...@@ -40,8 +40,6 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type);
40ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type);40ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type);
41ZigType *get_test_fn_type(CodeGen *g);41ZigType *get_test_fn_type(CodeGen *g);
42bool handle_is_ptr(ZigType *type_entry);42bool handle_is_ptr(ZigType *type_entry);
43void find_libc_include_path(CodeGen *g);
44void find_libc_lib_path(CodeGen *g);
4543
46bool type_has_bits(ZigType *type_entry);44bool type_has_bits(ZigType *type_entry);
47bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);45bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
src/codegen.cpp+127-107
...@@ -29,9 +29,9 @@ static void init_darwin_native(CodeGen *g) {...@@ -29,9 +29,9 @@ static void init_darwin_native(CodeGen *g) {
2929
30 // Allow conflicts among OSX and iOS, but choose the default platform.30 // Allow conflicts among OSX and iOS, but choose the default platform.
31 if (osx_target && ios_target) {31 if (osx_target && ios_target) {
32 if (g->zig_target.arch.arch == ZigLLVM_arm ||32 if (g->zig_target->arch.arch == ZigLLVM_arm ||
33 g->zig_target.arch.arch == ZigLLVM_aarch64 ||33 g->zig_target->arch.arch == ZigLLVM_aarch64 ||
34 g->zig_target.arch.arch == ZigLLVM_thumb)34 g->zig_target->arch.arch == ZigLLVM_thumb)
35 {35 {
36 osx_target = nullptr;36 osx_target = nullptr;
37 } else {37 } else {
...@@ -43,7 +43,7 @@ static void init_darwin_native(CodeGen *g) {...@@ -43,7 +43,7 @@ static void init_darwin_native(CodeGen *g) {
43 g->mmacosx_version_min = buf_create_from_str(osx_target);43 g->mmacosx_version_min = buf_create_from_str(osx_target);
44 } else if (ios_target) {44 } else if (ios_target) {
45 g->mios_version_min = buf_create_from_str(ios_target);45 g->mios_version_min = buf_create_from_str(ios_target);
46 } else if (g->zig_target.os != OsIOS) {46 } else if (g->zig_target->os != OsIOS) {
47 g->mmacosx_version_min = buf_create_from_str("10.10");47 g->mmacosx_version_min = buf_create_from_str("10.10");
48 }48 }
49}49}
...@@ -88,13 +88,15 @@ static const char *symbols_that_llvm_depends_on[] = {...@@ -88,13 +88,15 @@ static const char *symbols_that_llvm_depends_on[] = {
88};88};
8989
90CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,90CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
91 Buf *zig_lib_dir, Buf *override_std_dir)91 Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc)
92{92{
93 CodeGen *g = allocate<CodeGen>(1);93 CodeGen *g = allocate<CodeGen>(1);
9494
95 codegen_add_time_event(g, "Initialize");95 codegen_add_time_event(g, "Initialize");
9696
97 g->libc = libc;
97 g->zig_lib_dir = zig_lib_dir;98 g->zig_lib_dir = zig_lib_dir;
99 g->zig_target = target;
98100
99 if (override_std_dir == nullptr) {101 if (override_std_dir == nullptr) {
100 g->zig_std_dir = buf_alloc();102 g->zig_std_dir = buf_alloc();
...@@ -149,44 +151,19 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out...@@ -149,44 +151,19 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
149 g->zig_std_special_dir = buf_alloc();151 g->zig_std_special_dir = buf_alloc();
150 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);152 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
151153
152 if (target) {154 assert(target != nullptr);
153 // cross compiling, so we can't rely on all the configured stuff since155 if (!target->is_native) {
154 // that's for native compilation
155 g->zig_target = *target;
156 resolve_target_object_format(&g->zig_target);
157 g->dynamic_linker = nullptr;
158 g->libc_lib_dir = nullptr;
159 g->libc_static_lib_dir = nullptr;
160 g->libc_include_dir = nullptr;
161 g->msvc_lib_dir = nullptr;
162 g->kernel32_lib_dir = nullptr;
163 g->each_lib_rpath = false;156 g->each_lib_rpath = false;
164 } else {157 } else {
165 // native compilation, we can rely on the configuration stuff
166 g->is_native_target = true;
167 get_native_target(&g->zig_target);
168 g->dynamic_linker = nullptr; // find it at runtime
169 g->libc_lib_dir = nullptr; // find it at runtime
170 g->libc_static_lib_dir = nullptr; // find it at runtime
171 g->libc_include_dir = nullptr; // find it at runtime
172 g->msvc_lib_dir = nullptr; // find it at runtime
173 g->kernel32_lib_dir = nullptr; // find it at runtime
174 g->each_lib_rpath = true;158 g->each_lib_rpath = true;
175159
176 if (g->zig_target.os == OsMacOSX ||160 if (target_is_darwin(g->zig_target)) {
177 g->zig_target.os == OsIOS)
178 {
179 init_darwin_native(g);161 init_darwin_native(g);
180 }162 }
181163
182 }164 }
183165
184 // On Darwin/MacOS/iOS, we always link libSystem which contains libc.166 if (target_requires_libc(g->zig_target)) {
185 if (g->zig_target.os == OsMacOSX ||
186 g->zig_target.os == OsIOS ||
187 g->zig_target.os == OsFreeBSD ||
188 g->zig_target.os == OsNetBSD)
189 {
190 g->libc_link_lib = create_link_lib(buf_create_from_str("c"));167 g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
191 g->link_libs_list.append(g->libc_link_lib);168 g->link_libs_list.append(g->libc_link_lib);
192 }169 }
...@@ -254,30 +231,6 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {...@@ -254,30 +231,6 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {
254 g->root_out_name = out_name;231 g->root_out_name = out_name;
255}232}
256233
257void codegen_set_libc_lib_dir(CodeGen *g, Buf *libc_lib_dir) {
258 g->libc_lib_dir = libc_lib_dir;
259}
260
261void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir) {
262 g->libc_static_lib_dir = libc_static_lib_dir;
263}
264
265void codegen_set_libc_include_dir(CodeGen *g, Buf *libc_include_dir) {
266 g->libc_include_dir = libc_include_dir;
267}
268
269void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir) {
270 g->msvc_lib_dir = msvc_lib_dir;
271}
272
273void codegen_set_kernel32_lib_dir(CodeGen *g, Buf *kernel32_lib_dir) {
274 g->kernel32_lib_dir = kernel32_lib_dir;
275}
276
277void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) {
278 g->dynamic_linker = dynamic_linker;
279}
280
281void codegen_add_lib_dir(CodeGen *g, const char *dir) {234void codegen_add_lib_dir(CodeGen *g, const char *dir) {
282 g->lib_dirs.append(dir);235 g->lib_dirs.append(dir);
283}236}
...@@ -390,11 +343,11 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -390,11 +343,11 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
390 case CallingConventionC: return LLVMCCallConv;343 case CallingConventionC: return LLVMCCallConv;
391 case CallingConventionCold:344 case CallingConventionCold:
392 // cold calling convention only works on x86.345 // cold calling convention only works on x86.
393 if (g->zig_target.arch.arch == ZigLLVM_x86 ||346 if (g->zig_target->arch.arch == ZigLLVM_x86 ||
394 g->zig_target.arch.arch == ZigLLVM_x86_64)347 g->zig_target->arch.arch == ZigLLVM_x86_64)
395 {348 {
396 // cold calling convention is not supported on windows349 // cold calling convention is not supported on windows
397 if (g->zig_target.os == OsWindows) {350 if (g->zig_target->os == OsWindows) {
398 return LLVMCCallConv;351 return LLVMCCallConv;
399 } else {352 } else {
400 return LLVMColdCallConv;353 return LLVMColdCallConv;
...@@ -407,7 +360,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -407,7 +360,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
407 zig_unreachable();360 zig_unreachable();
408 case CallingConventionStdcall:361 case CallingConventionStdcall:
409 // stdcall calling convention only works on x86.362 // stdcall calling convention only works on x86.
410 if (g->zig_target.arch.arch == ZigLLVM_x86) {363 if (g->zig_target->arch.arch == ZigLLVM_x86) {
411 return LLVMX86StdcallCallConv;364 return LLVMX86StdcallCallConv;
412 } else {365 } else {
413 return LLVMCCallConv;366 return LLVMCCallConv;
...@@ -419,7 +372,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -419,7 +372,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
419}372}
420373
421static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {374static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
422 if (g->zig_target.os == OsWindows) {375 if (g->zig_target->os == OsWindows) {
423 addLLVMFnAttr(fn_val, "uwtable");376 addLLVMFnAttr(fn_val, "uwtable");
424 }377 }
425}378}
...@@ -455,13 +408,13 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {...@@ -455,13 +408,13 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
455}408}
456409
457static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {410static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
458 if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {411 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
459 LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);412 LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
460 }413 }
461}414}
462415
463static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {416static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
464 if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {417 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
465 // TODO come up with a good explanation/understanding for why we never do418 // TODO come up with a good explanation/understanding for why we never do
466 // DLLImportStorageClass. Empirically it only causes problems. But let's have419 // DLLImportStorageClass. Empirically it only causes problems. But let's have
467 // this documented and then clean up the code accordingly.420 // this documented and then clean up the code accordingly.
...@@ -506,7 +459,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -506,7 +459,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
506 bool external_linkage = linkage != GlobalLinkageIdInternal;459 bool external_linkage = linkage != GlobalLinkageIdInternal;
507 CallingConvention cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;460 CallingConvention cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;
508 if (cc == CallingConventionStdcall && external_linkage &&461 if (cc == CallingConventionStdcall && external_linkage &&
509 g->zig_target.arch.arch == ZigLLVM_x86)462 g->zig_target->arch.arch == ZigLLVM_x86)
510 {463 {
511 // prevent llvm name mangling464 // prevent llvm name mangling
512 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));465 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));
...@@ -2138,7 +2091,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2138,7 +2091,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2138 return true;2091 return true;
2139 }2092 }
21402093
2141 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {2094 if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
2142 X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty);2095 X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty);
2143 size_t ty_size = type_size(g, ty);2096 size_t ty_size = type_size(g, ty);
2144 if (abi_class == X64CABIClass_MEMORY) {2097 if (abi_class == X64CABIClass_MEMORY) {
...@@ -3381,15 +3334,15 @@ static bool value_is_all_undef(ConstExprValue *const_val) {...@@ -3381,15 +3334,15 @@ static bool value_is_all_undef(ConstExprValue *const_val) {
3381static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default_value, LLVMValueRef request,3334static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default_value, LLVMValueRef request,
3382 LLVMValueRef a1, LLVMValueRef a2, LLVMValueRef a3, LLVMValueRef a4, LLVMValueRef a5)3335 LLVMValueRef a1, LLVMValueRef a2, LLVMValueRef a3, LLVMValueRef a4, LLVMValueRef a5)
3383{3336{
3384 if (!target_has_valgrind_support(&g->zig_target)) {3337 if (!target_has_valgrind_support(g->zig_target)) {
3385 return default_value;3338 return default_value;
3386 }3339 }
3387 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref;3340 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref;
3388 bool asm_has_side_effects = true;3341 bool asm_has_side_effects = true;
3389 bool asm_is_alignstack = false;3342 bool asm_is_alignstack = false;
3390 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {3343 if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
3391 if (g->zig_target.os == OsLinux || target_is_darwin(&g->zig_target) || g->zig_target.os == OsSolaris ||3344 if (g->zig_target->os == OsLinux || target_is_darwin(g->zig_target) || g->zig_target->os == OsSolaris ||
3392 (g->zig_target.os == OsWindows && g->zig_target.env_type != ZigLLVM_MSVC))3345 (g->zig_target->os == OsWindows && g->zig_target->env_type != ZigLLVM_MSVC))
3393 {3346 {
3394 if (g->cur_fn->valgrind_client_request_array == nullptr) {3347 if (g->cur_fn->valgrind_client_request_array == nullptr) {
3395 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);3348 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
...@@ -3436,7 +3389,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default...@@ -3436,7 +3389,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
3436}3389}
34373390
3438static bool want_valgrind_support(CodeGen *g) {3391static bool want_valgrind_support(CodeGen *g) {
3439 if (!target_has_valgrind_support(&g->zig_target))3392 if (!target_has_valgrind_support(g->zig_target))
3440 return false;3393 return false;
3441 switch (g->valgrind_support) {3394 switch (g->valgrind_support) {
3442 case ValgrindSupportDisabled:3395 case ValgrindSupportDisabled:
...@@ -3629,7 +3582,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {...@@ -3629,7 +3582,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
3629 LLVMValueRef write_register_fn_val = get_write_register_fn_val(g);3582 LLVMValueRef write_register_fn_val = get_write_register_fn_val(g);
36303583
3631 if (g->sp_md_node == nullptr) {3584 if (g->sp_md_node == nullptr) {
3632 Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target.arch));3585 Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target->arch));
3633 LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1);3586 LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1);
3634 g->sp_md_node = LLVMMDNode(&str_node, 1);3587 g->sp_md_node = LLVMMDNode(&str_node, 1);
3635 }3588 }
...@@ -7042,7 +6995,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -7042,7 +6995,7 @@ static void define_builtin_types(CodeGen *g) {
70426995
7043 for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {6996 for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
7044 const CIntTypeInfo *info = &c_int_type_infos[i];6997 const CIntTypeInfo *info = &c_int_type_infos[i];
7045 uint32_t size_in_bits = target_c_type_size_in_bits(&g->zig_target, info->id);6998 uint32_t size_in_bits = target_c_type_size_in_bits(g->zig_target, info->id);
7046 bool is_signed = info->is_signed;6999 bool is_signed = info->is_signed;
70477000
7048 ZigType *entry = new_type_table_entry(ZigTypeIdInt);7001 ZigType *entry = new_type_table_entry(ZigTypeIdInt);
...@@ -7309,6 +7262,9 @@ static const char *build_mode_to_str(BuildMode build_mode) {...@@ -7309,6 +7262,9 @@ static const char *build_mode_to_str(BuildMode build_mode) {
7309Buf *codegen_generate_builtin_source(CodeGen *g) {7262Buf *codegen_generate_builtin_source(CodeGen *g) {
7310 Buf *contents = buf_alloc();7263 Buf *contents = buf_alloc();
73117264
7265 // NOTE: when editing this file, you may need to make modifications to the
7266 // cache input parameters in define_builtin_compile_vars
7267
7312 // Modifications to this struct must be coordinated with code that does anything with7268 // Modifications to this struct must be coordinated with code that does anything with
7313 // g->stack_trace_type. There are hard-coded references to the field indexes.7269 // g->stack_trace_type. There are hard-coded references to the field indexes.
7314 buf_append_str(contents,7270 buf_append_str(contents,
...@@ -7328,7 +7284,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7328,7 +7284,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7328 const char *name = get_target_os_name(os_type);7284 const char *name = get_target_os_name(os_type);
7329 buf_appendf(contents, " %s,\n", name);7285 buf_appendf(contents, " %s,\n", name);
73307286
7331 if (os_type == g->zig_target.os) {7287 if (os_type == g->zig_target->os) {
7332 g->target_os_index = i;7288 g->target_os_index = i;
7333 cur_os = name;7289 cur_os = name;
7334 }7290 }
...@@ -7350,8 +7306,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7350,8 +7306,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
73507306
7351 buf_appendf(contents, " %s,\n", buf_ptr(arch_name));7307 buf_appendf(contents, " %s,\n", buf_ptr(arch_name));
73527308
7353 if (arch_type->arch == g->zig_target.arch.arch &&7309 if (arch_type->arch == g->zig_target->arch.arch &&
7354 arch_type->sub_arch == g->zig_target.arch.sub_arch)7310 arch_type->sub_arch == g->zig_target->arch.sub_arch)
7355 {7311 {
7356 g->target_arch_index = i;7312 g->target_arch_index = i;
7357 cur_arch = buf_ptr(arch_name);7313 cur_arch = buf_ptr(arch_name);
...@@ -7370,7 +7326,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7370,7 +7326,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7370 const char *name = ZigLLVMGetEnvironmentTypeName(environ_type);7326 const char *name = ZigLLVMGetEnvironmentTypeName(environ_type);
7371 buf_appendf(contents, " %s,\n", name);7327 buf_appendf(contents, " %s,\n", name);
73727328
7373 if (environ_type == g->zig_target.env_type) {7329 if (environ_type == g->zig_target->env_type) {
7374 g->target_environ_index = i;7330 g->target_environ_index = i;
7375 cur_environ = name;7331 cur_environ = name;
7376 }7332 }
...@@ -7388,7 +7344,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7388,7 +7344,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7388 const char *name = get_target_oformat_name(oformat);7344 const char *name = get_target_oformat_name(oformat);
7389 buf_appendf(contents, " %s,\n", name);7345 buf_appendf(contents, " %s,\n", name);
73907346
7391 if (oformat == g->zig_target.oformat) {7347 ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);
7348 if (oformat == target_oformat) {
7392 g->target_oformat_index = i;7349 g->target_oformat_index = i;
7393 cur_obj_fmt = name;7350 cur_obj_fmt = name;
7394 }7351 }
...@@ -7707,14 +7664,15 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -7707,14 +7664,15 @@ static Error define_builtin_compile_vars(CodeGen *g) {
7707 cache_int(&cache_hash, g->build_mode);7664 cache_int(&cache_hash, g->build_mode);
7708 cache_bool(&cache_hash, g->is_test_build);7665 cache_bool(&cache_hash, g->is_test_build);
7709 cache_bool(&cache_hash, g->is_single_threaded);7666 cache_bool(&cache_hash, g->is_single_threaded);
7710 cache_int(&cache_hash, g->zig_target.arch.arch);7667 cache_int(&cache_hash, g->zig_target->is_native);
7711 cache_int(&cache_hash, g->zig_target.arch.sub_arch);7668 cache_int(&cache_hash, g->zig_target->arch.arch);
7712 cache_int(&cache_hash, g->zig_target.vendor);7669 cache_int(&cache_hash, g->zig_target->arch.sub_arch);
7713 cache_int(&cache_hash, g->zig_target.os);7670 cache_int(&cache_hash, g->zig_target->vendor);
7714 cache_int(&cache_hash, g->zig_target.env_type);7671 cache_int(&cache_hash, g->zig_target->os);
7715 cache_int(&cache_hash, g->zig_target.oformat);7672 cache_int(&cache_hash, g->zig_target->env_type);
7716 cache_bool(&cache_hash, g->have_err_ret_tracing);7673 cache_bool(&cache_hash, g->have_err_ret_tracing);
7717 cache_bool(&cache_hash, g->libc_link_lib != nullptr);7674 cache_bool(&cache_hash, g->libc_link_lib != nullptr);
7675 cache_bool(&cache_hash, g->valgrind_support);
77187676
7719 Buf digest = BUF_INIT;7677 Buf digest = BUF_INIT;
7720 buf_resize(&digest, 0);7678 buf_resize(&digest, 0);
...@@ -7783,11 +7741,11 @@ static void init(CodeGen *g) {...@@ -7783,11 +7741,11 @@ static void init(CodeGen *g) {
7783 assert(g->root_out_name);7741 assert(g->root_out_name);
7784 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));7742 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
77857743
7786 get_target_triple(&g->triple_str, &g->zig_target);7744 get_target_triple(&g->triple_str, g->zig_target);
77877745
7788 LLVMSetTarget(g->module, buf_ptr(&g->triple_str));7746 LLVMSetTarget(g->module, buf_ptr(&g->triple_str));
77897747
7790 if (g->zig_target.oformat == ZigLLVM_COFF) {7748 if (target_object_format(g->zig_target) == ZigLLVM_COFF) {
7791 ZigLLVMAddModuleCodeViewFlag(g->module);7749 ZigLLVMAddModuleCodeViewFlag(g->module);
7792 } else {7750 } else {
7793 ZigLLVMAddModuleDebugInfoFlag(g->module);7751 ZigLLVMAddModuleDebugInfoFlag(g->module);
...@@ -7815,11 +7773,11 @@ static void init(CodeGen *g) {...@@ -7815,11 +7773,11 @@ static void init(CodeGen *g) {
78157773
7816 const char *target_specific_cpu_args;7774 const char *target_specific_cpu_args;
7817 const char *target_specific_features;7775 const char *target_specific_features;
7818 if (g->is_native_target) {7776 if (g->zig_target->is_native) {
7819 // LLVM creates invalid binaries on Windows sometimes.7777 // LLVM creates invalid binaries on Windows sometimes.
7820 // See https://github.com/ziglang/zig/issues/5087778 // See https://github.com/ziglang/zig/issues/508
7821 // As a workaround we do not use target native features on Windows.7779 // As a workaround we do not use target native features on Windows.
7822 if (g->zig_target.os == OsWindows || g->zig_target.os == OsUefi) {7780 if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
7823 target_specific_cpu_args = "";7781 target_specific_cpu_args = "";
7824 target_specific_features = "";7782 target_specific_features = "";
7825 } else {7783 } else {
...@@ -7892,9 +7850,59 @@ static void init(CodeGen *g) {...@@ -7892,9 +7850,59 @@ static void init(CodeGen *g) {
7892 }7850 }
7893}7851}
78947852
7895void codegen_translate_c(CodeGen *g, Buf *full_path) {7853static void detect_libc(CodeGen *g) {
7896 find_libc_include_path(g);7854 Error err;
7855
7856 if (g->libc != nullptr || g->libc_link_lib == nullptr)
7857 return;
78977858
7859 if (g->zig_target->is_native) {
7860 g->libc = allocate<ZigLibCInstallation>(1);
7861
7862 // Look for zig-cache/native_libc.txt
7863 Buf *native_libc_txt = buf_alloc();
7864 os_path_join(&g->cache_dir, buf_create_from_str("native_libc.txt"), native_libc_txt);
7865 if ((err = zig_libc_parse(g->libc, native_libc_txt, g->zig_target, false))) {
7866 if ((err = zig_libc_find_native(g->libc, true))) {
7867 fprintf(stderr,
7868 "Unable to link against libc: Unable to find libc installation: %s\n"
7869 "See `zig libc --help` for more details.\n", err_str(err));
7870 exit(1);
7871 }
7872 if ((err = os_make_path(&g->cache_dir))) {
7873 fprintf(stderr, "Unable to create %s directory: %s\n",
7874 buf_ptr(&g->cache_dir), err_str(err));
7875 exit(1);
7876 }
7877 Buf *native_libc_tmp = buf_sprintf("%s.tmp", buf_ptr(native_libc_txt));
7878 FILE *file = fopen(buf_ptr(native_libc_tmp), "wb");
7879 if (file == nullptr) {
7880 fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
7881 exit(1);
7882 }
7883 zig_libc_render(g->libc, file);
7884 if (fclose(file) != 0) {
7885 fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
7886 exit(1);
7887 }
7888 if (rename(buf_ptr(native_libc_tmp), buf_ptr(native_libc_txt)) == -1) {
7889 fprintf(stderr, "Unable to create %s: %s\n", buf_ptr(native_libc_txt), strerror(errno));
7890 exit(1);
7891 }
7892 }
7893 } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) &&
7894 !target_is_darwin(g->zig_target))
7895 {
7896 // Currently darwin is the only platform that we can link libc on when not compiling natively,
7897 // without a cross compiling libc kit.
7898 fprintf(stderr,
7899 "Cannot link against libc for non-native OS '%s' without providing a libc installation file.\n"
7900 "See `zig libc --help` for more details.\n", get_target_os_name(g->zig_target->os));
7901 exit(1);
7902 }
7903}
7904
7905void codegen_translate_c(CodeGen *g, Buf *full_path) {
7898 Buf *src_basename = buf_alloc();7906 Buf *src_basename = buf_alloc();
7899 Buf *src_dirname = buf_alloc();7907 Buf *src_dirname = buf_alloc();
7900 os_path_split(full_path, src_dirname, src_basename);7908 os_path_split(full_path, src_dirname, src_basename);
...@@ -7905,6 +7913,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {...@@ -7905,6 +7913,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
7905 g->root_import = import;7913 g->root_import = import;
7906 import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);7914 import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
79077915
7916 detect_libc(g);
7917
7908 init(g);7918 init(g);
79097919
7910 import->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));7920 import->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
...@@ -8064,14 +8074,14 @@ static void gen_root_source(CodeGen *g) {...@@ -8064,14 +8074,14 @@ static void gen_root_source(CodeGen *g) {
8064 }8074 }
8065 report_errors_and_maybe_exit(g);8075 report_errors_and_maybe_exit(g);
80668076
8067 if (!g->is_test_build && g->zig_target.os != OsFreestanding &&8077 if (!g->is_test_build && g->zig_target->os != OsFreestanding &&
8068 g->zig_target.os != OsUefi &&8078 g->zig_target->os != OsUefi &&
8069 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&8079 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
8070 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))8080 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
8071 {8081 {
8072 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");8082 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
8073 }8083 }
8074 if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup &&8084 if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup &&
8075 g->out_type == OutTypeLib && !g->is_static)8085 g->out_type == OutTypeLib && !g->is_static)
8076 {8086 {
8077 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");8087 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
...@@ -8619,6 +8629,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -8619,6 +8629,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
8619 }8629 }
8620 cache_buf(ch, compiler_id);8630 cache_buf(ch, compiler_id);
8621 cache_buf(ch, g->root_out_name);8631 cache_buf(ch, g->root_out_name);
8632 cache_buf(ch, g->zig_lib_dir);
8633 cache_buf(ch, g->zig_std_dir);
8622 cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);8634 cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);
8623 cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);8635 cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);
8624 cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length);8636 cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length);
...@@ -8628,18 +8640,17 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -8628,18 +8640,17 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
8628 cache_int(ch, g->emit_file_type);8640 cache_int(ch, g->emit_file_type);
8629 cache_int(ch, g->build_mode);8641 cache_int(ch, g->build_mode);
8630 cache_int(ch, g->out_type);8642 cache_int(ch, g->out_type);
8631 cache_int(ch, g->zig_target.arch.arch);8643 cache_bool(ch, g->zig_target->is_native);
8632 cache_int(ch, g->zig_target.arch.sub_arch);8644 cache_int(ch, g->zig_target->arch.arch);
8633 cache_int(ch, g->zig_target.vendor);8645 cache_int(ch, g->zig_target->arch.sub_arch);
8634 cache_int(ch, g->zig_target.os);8646 cache_int(ch, g->zig_target->vendor);
8635 cache_int(ch, g->zig_target.env_type);8647 cache_int(ch, g->zig_target->os);
8636 cache_int(ch, g->zig_target.oformat);8648 cache_int(ch, g->zig_target->env_type);
8637 cache_int(ch, g->subsystem);8649 cache_int(ch, g->subsystem);
8638 cache_bool(ch, g->is_static);8650 cache_bool(ch, g->is_static);
8639 cache_bool(ch, g->strip_debug_symbols);8651 cache_bool(ch, g->strip_debug_symbols);
8640 cache_bool(ch, g->is_test_build);8652 cache_bool(ch, g->is_test_build);
8641 cache_bool(ch, g->is_single_threaded);8653 cache_bool(ch, g->is_single_threaded);
8642 cache_bool(ch, g->is_native_target);
8643 cache_bool(ch, g->linker_rdynamic);8654 cache_bool(ch, g->linker_rdynamic);
8644 cache_bool(ch, g->each_lib_rpath);8655 cache_bool(ch, g->each_lib_rpath);
8645 cache_bool(ch, g->disable_pic);8656 cache_bool(ch, g->disable_pic);
...@@ -8654,6 +8665,14 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -8654,6 +8665,14 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
8654 cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len);8665 cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len);
8655 cache_list_of_str(ch, g->clang_argv, g->clang_argv_len);8666 cache_list_of_str(ch, g->clang_argv, g->clang_argv_len);
8656 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);8667 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
8668 if (g->libc) {
8669 cache_buf(ch, &g->libc->include_dir);
8670 cache_buf(ch, &g->libc->lib_dir);
8671 cache_buf(ch, &g->libc->static_lib_dir);
8672 cache_buf(ch, &g->libc->msvc_lib_dir);
8673 cache_buf(ch, &g->libc->kernel32_lib_dir);
8674 cache_buf(ch, &g->libc->dynamic_linker_path);
8675 }
86578676
8658 buf_resize(digest, 0);8677 buf_resize(digest, 0);
8659 if ((err = cache_hit(ch, digest)))8678 if ((err = cache_hit(ch, digest)))
...@@ -8668,19 +8687,19 @@ static void resolve_out_paths(CodeGen *g) {...@@ -8668,19 +8687,19 @@ static void resolve_out_paths(CodeGen *g) {
8668 switch (g->emit_file_type) {8687 switch (g->emit_file_type) {
8669 case EmitFileTypeBinary:8688 case EmitFileTypeBinary:
8670 {8689 {
8671 const char *o_ext = target_o_file_ext(&g->zig_target);8690 const char *o_ext = target_o_file_ext(g->zig_target);
8672 buf_append_str(o_basename, o_ext);8691 buf_append_str(o_basename, o_ext);
8673 break;8692 break;
8674 }8693 }
8675 case EmitFileTypeAssembly:8694 case EmitFileTypeAssembly:
8676 {8695 {
8677 const char *asm_ext = target_asm_file_ext(&g->zig_target);8696 const char *asm_ext = target_asm_file_ext(g->zig_target);
8678 buf_append_str(o_basename, asm_ext);8697 buf_append_str(o_basename, asm_ext);
8679 break;8698 break;
8680 }8699 }
8681 case EmitFileTypeLLVMIr:8700 case EmitFileTypeLLVMIr:
8682 {8701 {
8683 const char *llvm_ir_ext = target_llvm_ir_file_ext(&g->zig_target);8702 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
8684 buf_append_str(o_basename, llvm_ir_ext);8703 buf_append_str(o_basename, llvm_ir_ext);
8685 break;8704 break;
8686 }8705 }
...@@ -8706,7 +8725,7 @@ static void resolve_out_paths(CodeGen *g) {...@@ -8706,7 +8725,7 @@ static void resolve_out_paths(CodeGen *g) {
87068725
8707 Buf basename = BUF_INIT;8726 Buf basename = BUF_INIT;
8708 buf_init_from_buf(&basename, g->root_out_name);8727 buf_init_from_buf(&basename, g->root_out_name);
8709 buf_append_str(&basename, target_exe_file_ext(&g->zig_target));8728 buf_append_str(&basename, target_exe_file_ext(g->zig_target));
8710 if (g->enable_cache || g->is_test_build) {8729 if (g->enable_cache || g->is_test_build) {
8711 os_path_join(&g->artifact_dir, &basename, &g->output_file_path);8730 os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
8712 } else {8731 } else {
...@@ -8719,7 +8738,7 @@ static void resolve_out_paths(CodeGen *g) {...@@ -8719,7 +8738,7 @@ static void resolve_out_paths(CodeGen *g) {
8719 } else {8738 } else {
8720 Buf basename = BUF_INIT;8739 Buf basename = BUF_INIT;
8721 buf_init_from_buf(&basename, g->root_out_name);8740 buf_init_from_buf(&basename, g->root_out_name);
8722 buf_append_str(&basename, target_lib_file_ext(&g->zig_target, g->is_static,8741 buf_append_str(&basename, target_lib_file_ext(g->zig_target, g->is_static,
8723 g->version_major, g->version_minor, g->version_patch));8742 g->version_major, g->version_minor, g->version_patch));
8724 if (g->enable_cache) {8743 if (g->enable_cache) {
8725 os_path_join(&g->artifact_dir, &basename, &g->output_file_path);8744 os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
...@@ -8732,11 +8751,12 @@ static void resolve_out_paths(CodeGen *g) {...@@ -8732,11 +8751,12 @@ static void resolve_out_paths(CodeGen *g) {
8732 }8751 }
8733}8752}
87348753
8735
8736void codegen_build_and_link(CodeGen *g) {8754void codegen_build_and_link(CodeGen *g) {
8737 Error err;8755 Error err;
8738 assert(g->out_type != OutTypeUnknown);8756 assert(g->out_type != OutTypeUnknown);
87398757
8758 detect_libc(g);
8759
8740 Buf *stage1_dir = get_stage1_cache_path();8760 Buf *stage1_dir = get_stage1_cache_path();
8741 Buf *artifact_dir = buf_alloc();8761 Buf *artifact_dir = buf_alloc();
8742 Buf digest = BUF_INIT;8762 Buf digest = BUF_INIT;
src/codegen.hpp+2-7
...@@ -11,11 +11,12 @@...@@ -11,11 +11,12 @@
11#include "parser.hpp"11#include "parser.hpp"
12#include "errmsg.hpp"12#include "errmsg.hpp"
13#include "target.hpp"13#include "target.hpp"
14#include "libc_installation.hpp"
1415
15#include <stdio.h>16#include <stdio.h>
1617
17CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,18CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
18 Buf *zig_lib_dir, Buf *override_std_dir);19 Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc);
1920
20void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);21void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
21void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);22void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
...@@ -27,12 +28,6 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static);...@@ -27,12 +28,6 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static);
27void codegen_set_strip(CodeGen *codegen, bool strip);28void codegen_set_strip(CodeGen *codegen, bool strip);
28void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);29void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
29void codegen_set_out_name(CodeGen *codegen, Buf *out_name);30void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
30void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
31void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
32void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
33void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir);
34void codegen_set_kernel32_lib_dir(CodeGen *codegen, Buf *kernel32_lib_dir);
35void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);
36void codegen_add_lib_dir(CodeGen *codegen, const char *dir);31void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
37void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib);32void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib);
38LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib);33LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib);
src/error.cpp+2
...@@ -34,6 +34,8 @@ const char *err_str(Error err) {...@@ -34,6 +34,8 @@ const char *err_str(Error err) {
34 case ErrorPipeBusy: return "pipe busy";34 case ErrorPipeBusy: return "pipe busy";
35 case ErrorPrimitiveTypeNotFound: return "primitive type not found";35 case ErrorPrimitiveTypeNotFound: return "primitive type not found";
36 case ErrorCacheUnavailable: return "cache unavailable";36 case ErrorCacheUnavailable: return "cache unavailable";
37 case ErrorPathTooLong: return "path too long";
38 case ErrorCCompilerCannotFindFile: return "C compiler cannot find file";
37 }39 }
38 return "(invalid error)";40 return "(invalid error)";
39}41}
src/error.hpp+2
...@@ -36,6 +36,8 @@ enum Error {...@@ -36,6 +36,8 @@ enum Error {
36 ErrorPipeBusy,36 ErrorPipeBusy,
37 ErrorPrimitiveTypeNotFound,37 ErrorPrimitiveTypeNotFound,
38 ErrorCacheUnavailable,38 ErrorCacheUnavailable,
39 ErrorPathTooLong,
40 ErrorCCompilerCannotFindFile,
39};41};
4042
41const char *err_str(Error err);43const char *err_str(Error err);
src/ir.cpp-2
...@@ -18690,8 +18690,6 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -18690,8 +18690,6 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
18690 if (type_is_invalid(cimport_result->type))18690 if (type_is_invalid(cimport_result->type))
18691 return ira->codegen->invalid_instruction;18691 return ira->codegen->invalid_instruction;
1869218692
18693 find_libc_include_path(ira->codegen);
18694
18695 ImportTableEntry *child_import = allocate<ImportTableEntry>(1);18693 ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
18696 child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);18694 child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
18697 child_import->c_import_node = node;18695 child_import->c_import_node = node;
src/libc_installation.cpp created+408
...@@ -0,0 +1,408 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "libc_installation.hpp"
9#include "os.hpp"
10#include "windows_sdk.h"
11#include "target.hpp"
12
13static const size_t zig_libc_keys_len = 6;
14
15static const char *zig_libc_keys[] = {
16 "include_dir",
17 "lib_dir",
18 "static_lib_dir",
19 "msvc_lib_dir",
20 "kernel32_lib_dir",
21 "dynamic_linker_path",
22};
23
24static bool zig_libc_match_key(Slice<uint8_t> name, Slice<uint8_t> value, bool *found_keys,
25 size_t index, Buf *field_ptr)
26{
27 if (!memEql(name, str(zig_libc_keys[index]))) return false;
28 buf_init_from_mem(field_ptr, (const char*)value.ptr, value.len);
29 found_keys[index] = true;
30 return true;
31}
32
33static void zig_libc_init_empty(ZigLibCInstallation *libc) {
34 *libc = {};
35 buf_init_from_str(&libc->include_dir, "");
36 buf_init_from_str(&libc->lib_dir, "");
37 buf_init_from_str(&libc->static_lib_dir, "");
38 buf_init_from_str(&libc->msvc_lib_dir, "");
39 buf_init_from_str(&libc->kernel32_lib_dir, "");
40 buf_init_from_str(&libc->dynamic_linker_path, "");
41}
42
43Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget *target, bool verbose) {
44 Error err;
45 zig_libc_init_empty(libc);
46
47 bool found_keys[6] = {}; // zig_libc_keys_len
48
49 Buf *contents = buf_alloc();
50 if ((err = os_fetch_file_path(libc_file, contents, false))) {
51 if (err != ErrorFileNotFound && verbose) {
52 fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err));
53 }
54 return err;
55 }
56
57 SplitIterator it = memSplit(buf_to_slice(contents), str("\n"));
58 for (;;) {
59 Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);
60 if (!opt_line.is_some)
61 break;
62
63 if (opt_line.value.len == 0 || opt_line.value.ptr[0] == '#')
64 continue;
65
66 SplitIterator line_it = memSplit(opt_line.value, str("="));
67 Slice<uint8_t> name;
68 if (!SplitIterator_next(&line_it).unwrap(&name)) {
69 if (verbose) {
70 fprintf(stderr, "missing equal sign after field name\n");
71 }
72 return ErrorSemanticAnalyzeFail;
73 }
74 Slice<uint8_t> value = SplitIterator_rest(&line_it);
75 bool match = false;
76 match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
77 match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->lib_dir);
78 match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->static_lib_dir);
79 match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir);
80 match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->kernel32_lib_dir);
81 match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->dynamic_linker_path);
82 }
83
84 for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
85 if (!found_keys[i]) {
86 if (verbose) {
87 fprintf(stderr, "missing field: %s\n", zig_libc_keys[i]);
88 }
89 return ErrorSemanticAnalyzeFail;
90 }
91 }
92
93 if (buf_len(&libc->include_dir) == 0) {
94 if (verbose) {
95 fprintf(stderr, "include_dir may not be empty\n");
96 }
97 return ErrorSemanticAnalyzeFail;
98 }
99
100 if (buf_len(&libc->lib_dir) == 0) {
101 if (!target_is_darwin(target)) {
102 if (verbose) {
103 fprintf(stderr, "lib_dir may not be empty for %s\n", get_target_os_name(target->os));
104 }
105 return ErrorSemanticAnalyzeFail;
106 }
107 }
108
109 if (buf_len(&libc->static_lib_dir) == 0) {
110 if (!target_is_darwin(target) && target->os != OsWindows) {
111 if (verbose) {
112 fprintf(stderr, "static_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
113 }
114 return ErrorSemanticAnalyzeFail;
115 }
116 }
117
118 if (buf_len(&libc->msvc_lib_dir) == 0) {
119 if (target->os == OsWindows) {
120 if (verbose) {
121 fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
122 }
123 return ErrorSemanticAnalyzeFail;
124 }
125 }
126
127 if (buf_len(&libc->kernel32_lib_dir) == 0) {
128 if (target->os == OsWindows) {
129 if (verbose) {
130 fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
131 }
132 return ErrorSemanticAnalyzeFail;
133 }
134 }
135
136 if (buf_len(&libc->dynamic_linker_path) == 0) {
137 if (target->os == OsLinux) {
138 if (verbose) {
139 fprintf(stderr, "dynamic_linker_path may not be empty for %s\n", get_target_os_name(target->os));
140 }
141 return ErrorSemanticAnalyzeFail;
142 }
143 }
144
145 return ErrorNone;
146}
147
148#if defined(ZIG_OS_WINDOWS)
149static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
150 Error err;
151 if ((err = os_get_win32_ucrt_include_path(sdk, &self->include_dir))) {
152 if (verbose) {
153 fprintf(stderr, "Unable to determine libc include path: %s\n", err_str(err));
154 }
155 return err;
156 }
157 return ErrorNone;
158}
159static Error zig_libc_find_lib_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
160 bool verbose)
161{
162 Error err;
163 if ((err = os_get_win32_ucrt_lib_path(sdk, &self->lib_dir, target->arch.arch))) {
164 if (verbose) {
165 fprintf(stderr, "Unable to determine ucrt path: %s\n", err_str(err));
166 }
167 return err;
168 }
169 return ErrorNone;
170}
171static Error zig_libc_find_kernel32_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
172 bool verbose)
173{
174 Error err;
175 if ((err = os_get_win32_kern32_path(sdk, &self->kernel32_lib_dir, target->arch.arch))) {
176 if (verbose) {
177 fprintf(stderr, "Unable to determine kernel32 path: %s\n", err_str(err));
178 }
179 return err;
180 }
181 return ErrorNone;
182}
183static Error zig_libc_find_native_msvc_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
184 if (sdk->msvc_lib_dir_ptr == nullptr) {
185 if (verbose) {
186 fprintf(stderr, "Unable to determine vcruntime path\n");
187 }
188 return ErrorFileNotFound;
189 }
190 buf_init_from_mem(&self->msvc_lib_dir, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
191 return ErrorNone;
192}
193#else
194static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, bool verbose) {
195 const char *cc_exe = getenv("CC");
196 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
197 ZigList<const char *> args = {};
198 args.append("-E");
199 args.append("-Wp,-v");
200 args.append("-xc");
201 args.append("/dev/null");
202 Termination term;
203 Buf *out_stderr = buf_alloc();
204 Buf *out_stdout = buf_alloc();
205 Error err;
206 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
207 if (verbose) {
208 fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
209 }
210 return err;
211 }
212 if (term.how != TerminationIdClean || term.code != 0) {
213 if (verbose) {
214 fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
215 }
216 return ErrorCCompileErrors;
217 }
218 char *prev_newline = buf_ptr(out_stderr);
219 ZigList<const char *> search_paths = {};
220 for (;;) {
221 char *newline = strchr(prev_newline, '\n');
222 if (newline == nullptr) {
223 break;
224 }
225 *newline = 0;
226 if (prev_newline[0] == ' ') {
227 search_paths.append(prev_newline);
228 }
229 prev_newline = newline + 1;
230 }
231 if (search_paths.length == 0) {
232 if (verbose) {
233 fprintf(stderr, "unable to determine libc include path: '%s' cannot find libc headers\n", cc_exe);
234 }
235 return ErrorCCompileErrors;
236 }
237 for (size_t i = 0; i < search_paths.length; i += 1) {
238 // search in reverse order
239 const char *search_path = search_paths.items[search_paths.length - i - 1];
240 // cut off spaces
241 while (*search_path == ' ') {
242 search_path += 1;
243 }
244 Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
245 bool exists;
246 if ((err = os_file_exists(stdlib_path, &exists))) {
247 exists = false;
248 }
249 if (exists) {
250 buf_init_from_str(&self->include_dir, search_path);
251 return ErrorNone;
252 }
253 }
254 if (verbose) {
255 fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe);
256 }
257 return ErrorFileNotFound;
258}
259#if !defined(ZIG_OS_DARWIN)
260static Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
261 const char *cc_exe = getenv("CC");
262 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
263 ZigList<const char *> args = {};
264 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
265 Termination term;
266 Buf *out_stderr = buf_alloc();
267 Buf *out_stdout = buf_alloc();
268 Error err;
269 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
270 if (verbose) {
271 fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
272 }
273 return err;
274 }
275 if (term.how != TerminationIdClean || term.code != 0) {
276 if (verbose) {
277 fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
278 }
279 return ErrorCCompileErrors;
280 }
281 if (buf_ends_with_str(out_stdout, "\n")) {
282 buf_resize(out_stdout, buf_len(out_stdout) - 1);
283 }
284 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
285 return ErrorCCompilerCannotFindFile;
286 }
287 if (want_dirname) {
288 os_path_dirname(out_stdout, out);
289 } else {
290 buf_init_from_buf(out, out_stdout);
291 }
292 return ErrorNone;
293}
294static Error zig_libc_find_native_lib_dir_posix(ZigLibCInstallation *self, bool verbose) {
295 return zig_libc_cc_print_file_name("crt1.o", &self->lib_dir, true, verbose);
296}
297
298static Error zig_libc_find_native_static_lib_dir_posix(ZigLibCInstallation *self, bool verbose) {
299 return zig_libc_cc_print_file_name("crtbegin.o", &self->static_lib_dir, true, verbose);
300}
301#endif
302
303static Error zig_libc_find_native_dynamic_linker_posix(ZigLibCInstallation *self, bool verbose) {
304#if defined(ZIG_OS_LINUX)
305 Error err;
306 static const char *dyn_tests[] = {
307 "ld-linux-x86-64.so.2",
308 "ld-musl-x86_64.so.1",
309 };
310 for (size_t i = 0; i < array_length(dyn_tests); i += 1) {
311 const char *lib_name = dyn_tests[i];
312 if ((err = zig_libc_cc_print_file_name(lib_name, &self->dynamic_linker_path, false, true))) {
313 if (err != ErrorCCompilerCannotFindFile)
314 return err;
315 continue;
316 }
317 return ErrorNone;
318 }
319#endif
320 ZigTarget native_target;
321 get_native_target(&native_target);
322 Buf *dynamic_linker_path = target_dynamic_linker(&native_target);
323 buf_init_from_buf(&self->dynamic_linker_path, dynamic_linker_path);
324 return ErrorNone;
325}
326#endif
327
328void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
329 fprintf(file,
330 "# The directory that contains `stdlib.h`.\n"
331 "# On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`\n"
332 "include_dir=%s\n"
333 "\n"
334 "# The directory that contains `crt1.o`.\n"
335 "# On Linux, can be found with `cc -print-file-name=crt1.o`.\n"
336 "# Not needed when targeting MacOS.\n"
337 "lib_dir=%s\n"
338 "\n"
339 "# The directory that contains `crtbegin.o`.\n"
340 "# On Linux, can be found with `cc -print-file-name=crtbegin.o`.\n"
341 "# Not needed when targeting MacOS or Windows.\n"
342 "static_lib_dir=%s\n"
343 "\n"
344 "# The directory that contains `vcruntime.lib`.\n"
345 "# Only needed when targeting Windows.\n"
346 "msvc_lib_dir=%s\n"
347 "\n"
348 "# The directory that contains `kernel32.lib`.\n"
349 "# Only needed when targeting Windows.\n"
350 "kernel32_lib_dir=%s\n"
351 "\n"
352 "# The full path to the dynamic linker, on the target system.\n"
353 "# Only needed when targeting Linux.\n"
354 "dynamic_linker_path=%s\n"
355 "\n"
356 ,
357 buf_ptr(&self->include_dir),
358 buf_ptr(&self->lib_dir),
359 buf_ptr(&self->static_lib_dir),
360 buf_ptr(&self->msvc_lib_dir),
361 buf_ptr(&self->kernel32_lib_dir),
362 buf_ptr(&self->dynamic_linker_path)
363 );
364}
365
366Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
367 Error err;
368 zig_libc_init_empty(self);
369#if defined(ZIG_OS_WINDOWS)
370 ZigTarget native_target;
371 get_native_target(&native_target);
372 ZigWindowsSDK *sdk;
373 switch (zig_find_windows_sdk(&sdk)) {
374 case ZigFindWindowsSdkErrorNone:
375 if ((err = zig_libc_find_native_msvc_lib_dir(self, sdk, verbose)))
376 return err;
377 if ((err = zig_libc_find_kernel32_lib_dir(self, sdk, &native_target, verbose)))
378 return err;
379 if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
380 return err;
381 if ((err = zig_libc_find_lib_dir_windows(self, sdk, &native_target, verbose)))
382 return err;
383 return ErrorNone;
384 case ZigFindWindowsSdkErrorOutOfMemory:
385 return ErrorNoMem;
386 case ZigFindWindowsSdkErrorNotFound:
387 return ErrorFileNotFound;
388 case ZigFindWindowsSdkErrorPathTooLong:
389 return ErrorPathTooLong;
390 }
391 zig_unreachable();
392#else
393 if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
394 return err;
395#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD)
396 buf_init_from_str(&self->lib_dir, "/usr/lib");
397 buf_init_from_str(&self->static_lib_dir, "/usr/lib");
398#elif !defined(ZIG_OS_DARWIN)
399 if ((err = zig_libc_find_native_lib_dir_posix(self, verbose)))
400 return err;
401 if ((err = zig_libc_find_native_static_lib_dir_posix(self, verbose)))
402 return err;
403#endif
404 if ((err = zig_libc_find_native_dynamic_linker_posix(self, verbose)))
405 return err;
406 return ErrorNone;
407#endif
408}
src/libc_installation.hpp created+33
...@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_LIBC_INSTALLATION_HPP
9#define ZIG_LIBC_INSTALLATION_HPP
10
11#include <stdio.h>
12
13#include "buffer.hpp"
14#include "error.hpp"
15#include "target.hpp"
16
17// Must be synchronized with zig_libc_keys
18struct ZigLibCInstallation {
19 Buf include_dir;
20 Buf lib_dir;
21 Buf static_lib_dir;
22 Buf msvc_lib_dir;
23 Buf kernel32_lib_dir;
24 Buf dynamic_linker_path;
25};
26
27Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file,
28 const ZigTarget *target, bool verbose);
29void zig_libc_render(ZigLibCInstallation *self, FILE *file);
30
31Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
32
33#endif
src/link.cpp+45-104
...@@ -18,31 +18,32 @@ struct LinkJob {...@@ -18,31 +18,32 @@ struct LinkJob {
18};18};
1919
20static const char *get_libc_file(CodeGen *g, const char *file) {20static const char *get_libc_file(CodeGen *g, const char *file) {
21 assert(g->libc != nullptr);
21 Buf *out_buf = buf_alloc();22 Buf *out_buf = buf_alloc();
22 os_path_join(g->libc_lib_dir, buf_create_from_str(file), out_buf);23 os_path_join(&g->libc->lib_dir, buf_create_from_str(file), out_buf);
23 return buf_ptr(out_buf);24 return buf_ptr(out_buf);
24}25}
2526
26static const char *get_libc_static_file(CodeGen *g, const char *file) {27static const char *get_libc_static_file(CodeGen *g, const char *file) {
28 assert(g->libc != nullptr);
27 Buf *out_buf = buf_alloc();29 Buf *out_buf = buf_alloc();
28 os_path_join(g->libc_static_lib_dir, buf_create_from_str(file), out_buf);30 os_path_join(&g->libc->static_lib_dir, buf_create_from_str(file), out_buf);
29 return buf_ptr(out_buf);31 return buf_ptr(out_buf);
30}32}
3133
32static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {34static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {
33 ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
34
35 // The Mach-O LLD code is not well maintained, and trips an assertion35 // The Mach-O LLD code is not well maintained, and trips an assertion
36 // when we link compiler_rt and builtin as libraries rather than objects.36 // when we link compiler_rt and builtin as libraries rather than objects.
37 // Here we workaround this by having compiler_rt and builtin be objects.37 // Here we workaround this by having compiler_rt and builtin be objects.
38 // TODO write our own linker. https://github.com/ziglang/zig/issues/153538 // TODO write our own linker. https://github.com/ziglang/zig/issues/1535
39 OutType child_out_type = OutTypeLib;39 OutType child_out_type = OutTypeLib;
40 if (parent_gen->zig_target.os == OsMacOSX) {40 if (parent_gen->zig_target->os == OsMacOSX) {
41 child_out_type = OutTypeObj;41 child_out_type = OutTypeObj;
42 }42 }
4343
44 CodeGen *child_gen = codegen_create(full_path, child_target, child_out_type,44 CodeGen *child_gen = codegen_create(full_path, parent_gen->zig_target, child_out_type,
45 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir);45 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir,
46 parent_gen->libc);
4647
47 child_gen->out_h_path = nullptr;48 child_gen->out_h_path = nullptr;
48 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;49 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
...@@ -171,62 +172,11 @@ static void add_rpath(LinkJob *lj, Buf *rpath) {...@@ -171,62 +172,11 @@ static void add_rpath(LinkJob *lj, Buf *rpath) {
171 lj->rpath_table.put(rpath, true);172 lj->rpath_table.put(rpath, true);
172}173}
173174
174static Buf *try_dynamic_linker_path(const char *ld_name) {
175 const char *cc_exe = getenv("CC");
176 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
177 ZigList<const char *> args = {};
178 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", ld_name)));
179 Termination term;
180 Buf *out_stderr = buf_alloc();
181 Buf *out_stdout = buf_alloc();
182 int err;
183 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
184 return nullptr;
185 }
186 if (term.how != TerminationIdClean || term.code != 0) {
187 return nullptr;
188 }
189 if (buf_ends_with_str(out_stdout, "\n")) {
190 buf_resize(out_stdout, buf_len(out_stdout) - 1);
191 }
192 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, ld_name)) {
193 return nullptr;
194 }
195 return out_stdout;
196}
197
198static Buf *get_dynamic_linker_path(CodeGen *g) {
199 if (g->zig_target.os == OsFreeBSD) {
200 return buf_create_from_str("/libexec/ld-elf.so.1");
201 }
202 if (g->zig_target.os == OsNetBSD) {
203 return buf_create_from_str("/libexec/ld.elf_so");
204 }
205 if (g->is_native_target && g->zig_target.arch.arch == ZigLLVM_x86_64) {
206 static const char *ld_names[] = {
207 "ld-linux-x86-64.so.2",
208 "ld-musl-x86_64.so.1",
209 };
210 for (size_t i = 0; i < array_length(ld_names); i += 1) {
211 const char *ld_name = ld_names[i];
212 Buf *result = try_dynamic_linker_path(ld_name);
213 if (result != nullptr) {
214 return result;
215 }
216 }
217 }
218 return target_dynamic_linker(&g->zig_target);
219}
220
221static void construct_linker_job_elf(LinkJob *lj) {175static void construct_linker_job_elf(LinkJob *lj) {
222 CodeGen *g = lj->codegen;176 CodeGen *g = lj->codegen;
223177
224 lj->args.append("-error-limit=0");178 lj->args.append("-error-limit=0");
225179
226 if (g->libc_link_lib != nullptr) {
227 find_libc_lib_path(g);
228 }
229
230 if (g->linker_script) {180 if (g->linker_script) {
231 lj->args.append("-T");181 lj->args.append("-T");
232 lj->args.append(g->linker_script);182 lj->args.append(g->linker_script);
...@@ -235,14 +185,14 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -235,14 +185,14 @@ static void construct_linker_job_elf(LinkJob *lj) {
235 lj->args.append("--gc-sections");185 lj->args.append("--gc-sections");
236186
237 lj->args.append("-m");187 lj->args.append("-m");
238 lj->args.append(getLDMOption(&g->zig_target));188 lj->args.append(getLDMOption(g->zig_target));
239189
240 bool is_lib = g->out_type == OutTypeLib;190 bool is_lib = g->out_type == OutTypeLib;
241 bool shared = !g->is_static && is_lib;191 bool shared = !g->is_static && is_lib;
242 Buf *soname = nullptr;192 Buf *soname = nullptr;
243 if (g->is_static) {193 if (g->is_static) {
244 if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb ||194 if (g->zig_target->arch.arch == ZigLLVM_arm || g->zig_target->arch.arch == ZigLLVM_armeb ||
245 g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb)195 g->zig_target->arch.arch == ZigLLVM_thumb || g->zig_target->arch.arch == ZigLLVM_thumbeb)
246 {196 {
247 lj->args.append("-Bstatic");197 lj->args.append("-Bstatic");
248 } else {198 } else {
...@@ -264,13 +214,13 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -264,13 +214,13 @@ static void construct_linker_job_elf(LinkJob *lj) {
264 if (lj->link_in_crt) {214 if (lj->link_in_crt) {
265 const char *crt1o;215 const char *crt1o;
266 const char *crtbegino;216 const char *crtbegino;
267 if (g->zig_target.os == OsNetBSD) {217 if (g->zig_target->os == OsNetBSD) {
268 crt1o = "crt0.o";218 crt1o = "crt0.o";
269 crtbegino = "crtbegin.o";219 crtbegino = "crtbegin.o";
270 } else if (g->is_static) {220 } else if (g->is_static) {
271 crt1o = "crt1.o";221 crt1o = "crt1.o";
272 crtbegino = "crtbeginT.o";222 crtbegino = "crtbeginT.o";
273 } else {223 } else {
274 crt1o = "Scrt1.o";224 crt1o = "Scrt1.o";
275 crtbegino = "crtbegin.o";225 crtbegino = "crtbegin.o";
276 }226 }
...@@ -311,23 +261,19 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -311,23 +261,19 @@ static void construct_linker_job_elf(LinkJob *lj) {
311 }261 }
312262
313 if (g->libc_link_lib != nullptr) {263 if (g->libc_link_lib != nullptr) {
264 assert(g->libc != nullptr);
314 lj->args.append("-L");265 lj->args.append("-L");
315 lj->args.append(buf_ptr(g->libc_lib_dir));266 lj->args.append(buf_ptr(&g->libc->lib_dir));
316267
317 lj->args.append("-L");268 lj->args.append("-L");
318 lj->args.append(buf_ptr(g->libc_static_lib_dir));269 lj->args.append(buf_ptr(&g->libc->static_lib_dir));
319 }
320270
321 if (!g->is_static) {271 if (!g->is_static) {
322 if (g->dynamic_linker != nullptr) {272 assert(buf_len(&g->libc->dynamic_linker_path) != 0);
323 assert(buf_len(g->dynamic_linker) != 0);
324 lj->args.append("-dynamic-linker");
325 lj->args.append(buf_ptr(g->dynamic_linker));
326 } else {
327 Buf *resolved_dynamic_linker = get_dynamic_linker_path(g);
328 lj->args.append("-dynamic-linker");273 lj->args.append("-dynamic-linker");
329 lj->args.append(buf_ptr(resolved_dynamic_linker));274 lj->args.append(buf_ptr(&g->libc->dynamic_linker_path));
330 }275 }
276
331 }277 }
332278
333 if (shared) {279 if (shared) {
...@@ -397,11 +343,11 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -397,11 +343,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
397 lj->args.append(get_libc_file(g, "crtn.o"));343 lj->args.append(get_libc_file(g, "crtn.o"));
398 }344 }
399345
400 if (!g->is_native_target) {346 if (!g->zig_target->is_native) {
401 lj->args.append("--allow-shlib-undefined");347 lj->args.append("--allow-shlib-undefined");
402 }348 }
403349
404 if (g->zig_target.os == OsZen) {350 if (g->zig_target->os == OsZen) {
405 lj->args.append("-e");351 lj->args.append("-e");
406 lj->args.append("_start");352 lj->args.append("_start");
407353
...@@ -429,11 +375,11 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -429,11 +375,11 @@ static void construct_linker_job_wasm(LinkJob *lj) {
429//}375//}
430376
431static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {377static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
432 if (g->zig_target.arch.arch == ZigLLVM_x86) {378 if (g->zig_target->arch.arch == ZigLLVM_x86) {
433 list->append("-MACHINE:X86");379 list->append("-MACHINE:X86");
434 } else if (g->zig_target.arch.arch == ZigLLVM_x86_64) {380 } else if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
435 list->append("-MACHINE:X64");381 list->append("-MACHINE:X64");
436 } else if (g->zig_target.arch.arch == ZigLLVM_arm) {382 } else if (g->zig_target->arch.arch == ZigLLVM_arm) {
437 list->append("-MACHINE:ARM");383 list->append("-MACHINE:ARM");
438 }384 }
439}385}
...@@ -592,10 +538,6 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -592,10 +538,6 @@ static void construct_linker_job_coff(LinkJob *lj) {
592538
593 lj->args.append("/ERRORLIMIT:0");539 lj->args.append("/ERRORLIMIT:0");
594540
595 if (g->libc_link_lib != nullptr) {
596 find_libc_lib_path(g);
597 }
598
599 lj->args.append("/NOLOGO");541 lj->args.append("/NOLOGO");
600542
601 if (!g->strip_debug_symbols) {543 if (!g->strip_debug_symbols) {
...@@ -650,13 +592,11 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -650,13 +592,11 @@ static void construct_linker_job_coff(LinkJob *lj) {
650 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));592 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
651593
652 if (g->libc_link_lib != nullptr) {594 if (g->libc_link_lib != nullptr) {
653 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir))));595 assert(g->libc != nullptr);
654 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir))));
655596
656 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir))));597 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
657 if (g->libc_static_lib_dir != nullptr) {598 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
658 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir))));599 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->lib_dir))));
659 }
660 }600 }
661601
662 if (is_library && !g->is_static) {602 if (is_library && !g->is_static) {
...@@ -691,7 +631,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -691,7 +631,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
691 continue;631 continue;
692 }632 }
693 if (link_lib->provided_explicitly) {633 if (link_lib->provided_explicitly) {
694 if (lj->codegen->zig_target.env_type == ZigLLVM_GNU) {634 if (lj->codegen->zig_target->env_type == ZigLLVM_GNU) {
695 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));635 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
696 lj->args.append(buf_ptr(arg));636 lj->args.append(buf_ptr(arg));
697 }637 }
...@@ -721,7 +661,8 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -721,7 +661,8 @@ static void construct_linker_job_coff(LinkJob *lj) {
721 gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));661 gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
722 gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));662 gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
723 Buf diag = BUF_INIT;663 Buf diag = BUF_INIT;
724 if (!zig_lld_link(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {664 ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target);
665 if (!zig_lld_link(target_ofmt, gen_lib_args.items, gen_lib_args.length, &diag)) {
725 fprintf(stderr, "%s\n", buf_ptr(&diag));666 fprintf(stderr, "%s\n", buf_ptr(&diag));
726 exit(1);667 exit(1);
727 }668 }
...@@ -790,7 +731,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {...@@ -790,7 +731,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
790 platform->kind = MacOS;731 platform->kind = MacOS;
791 } else if (g->mios_version_min) {732 } else if (g->mios_version_min) {
792 platform->kind = IPhoneOS;733 platform->kind = IPhoneOS;
793 } else if (g->zig_target.os == OsMacOSX) {734 } else if (g->zig_target->os == OsMacOSX) {
794 platform->kind = MacOS;735 platform->kind = MacOS;
795 g->mmacosx_version_min = buf_create_from_str("10.10");736 g->mmacosx_version_min = buf_create_from_str("10.10");
796 } else {737 } else {
...@@ -817,8 +758,8 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {...@@ -817,8 +758,8 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
817 }758 }
818759
819 if (platform->kind == IPhoneOS &&760 if (platform->kind == IPhoneOS &&
820 (g->zig_target.arch.arch == ZigLLVM_x86 ||761 (g->zig_target->arch.arch == ZigLLVM_x86 ||
821 g->zig_target.arch.arch == ZigLLVM_x86_64))762 g->zig_target->arch.arch == ZigLLVM_x86_64))
822 {763 {
823 platform->kind = IPhoneOSSimulator;764 platform->kind = IPhoneOSSimulator;
824 }765 }
...@@ -882,7 +823,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -882,7 +823,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
882 }823 }
883824
884 lj->args.append("-arch");825 lj->args.append("-arch");
885 lj->args.append(get_darwin_arch_string(&g->zig_target));826 lj->args.append(get_darwin_arch_string(g->zig_target));
886827
887 DarwinPlatform platform;828 DarwinPlatform platform;
888 get_darwin_platform(lj, &platform);829 get_darwin_platform(lj, &platform);
...@@ -939,7 +880,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -939,7 +880,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
939 }880 }
940 break;881 break;
941 case IPhoneOS:882 case IPhoneOS:
942 if (g->zig_target.arch.arch == ZigLLVM_aarch64) {883 if (g->zig_target->arch.arch == ZigLLVM_aarch64) {
943 // iOS does not need any crt1 files for arm64884 // iOS does not need any crt1 files for arm64
944 } else if (darwin_version_lt(&platform, 3, 1)) {885 } else if (darwin_version_lt(&platform, 3, 1)) {
945 lj->args.append("-lcrt1.o");886 lj->args.append("-lcrt1.o");
...@@ -969,7 +910,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -969,7 +910,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
969 lj->args.append(buf_ptr(compiler_rt_o_path));910 lj->args.append(buf_ptr(compiler_rt_o_path));
970 }911 }
971912
972 if (g->is_native_target) {913 if (g->zig_target->is_native) {
973 for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {914 for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
974 LinkLib *link_lib = g->link_libs_list.at(lib_i);915 LinkLib *link_lib = g->link_libs_list.at(lib_i);
975 if (buf_eql_str(link_lib->name, "c")) {916 if (buf_eql_str(link_lib->name, "c")) {
...@@ -1010,7 +951,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -1010,7 +951,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
1010}951}
1011952
1012static void construct_linker_job(LinkJob *lj) {953static void construct_linker_job(LinkJob *lj) {
1013 switch (lj->codegen->zig_target.oformat) {954 switch (target_object_format(lj->codegen->zig_target)) {
1014 case ZigLLVM_UnknownObjectFormat:955 case ZigLLVM_UnknownObjectFormat:
1015 zig_unreachable();956 zig_unreachable();
1016957
...@@ -1050,7 +991,7 @@ void codegen_link(CodeGen *g) {...@@ -1050,7 +991,7 @@ void codegen_link(CodeGen *g) {
1050 for (size_t i = 0; i < g->link_objects.length; i += 1) {991 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1051 file_names.append((const char *)buf_ptr(g->link_objects.at(i)));992 file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
1052 }993 }
1053 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target.os);994 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
1054 codegen_add_time_event(g, "LLVM Link");995 codegen_add_time_event(g, "LLVM Link");
1055 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {996 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
1056 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));997 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
...@@ -1075,7 +1016,7 @@ void codegen_link(CodeGen *g) {...@@ -1075,7 +1016,7 @@ void codegen_link(CodeGen *g) {
1075 Buf diag = BUF_INIT;1016 Buf diag = BUF_INIT;
10761017
1077 codegen_add_time_event(g, "LLVM Link");1018 codegen_add_time_event(g, "LLVM Link");
1078 if (g->system_linker_hack && g->zig_target.os == OsMacOSX) {1019 if (g->system_linker_hack && g->zig_target->os == OsMacOSX) {
1079 Termination term;1020 Termination term;
1080 ZigList<const char *> args = {};1021 ZigList<const char *> args = {};
1081 for (size_t i = 1; i < lj.args.length; i += 1) {1022 for (size_t i = 1; i < lj.args.length; i += 1) {
...@@ -1085,7 +1026,7 @@ void codegen_link(CodeGen *g) {...@@ -1085,7 +1026,7 @@ void codegen_link(CodeGen *g) {
1085 if (term.how != TerminationIdClean || term.code != 0) {1026 if (term.how != TerminationIdClean || term.code != 0) {
1086 exit(1);1027 exit(1);
1087 }1028 }
1088 } else if (!zig_lld_link(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {1029 } else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) {
1089 fprintf(stderr, "%s\n", buf_ptr(&diag));1030 fprintf(stderr, "%s\n", buf_ptr(&diag));
1090 exit(1);1031 exit(1);
1091 }1032 }
src/main.cpp+75-52
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13#include "error.hpp"13#include "error.hpp"
14#include "os.hpp"14#include "os.hpp"
15#include "target.hpp"15#include "target.hpp"
16#include "libc_installation.hpp"
1617
17#include <stdio.h>18#include <stdio.h>
1819
...@@ -36,6 +37,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -36,6 +37,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
36 " id print the base64-encoded compiler id\n"37 " id print the base64-encoded compiler id\n"
37 " init-exe initialize a `zig build` application in the cwd\n"38 " init-exe initialize a `zig build` application in the cwd\n"
38 " init-lib initialize a `zig build` library in the cwd\n"39 " init-lib initialize a `zig build` library in the cwd\n"
40 " libc [paths_file] Display native libc paths file or validate one\n"
39 " run [source] create executable and run immediately\n"41 " run [source] create executable and run immediately\n"
40 " translate-c [source] convert c code to zig code\n"42 " translate-c [source] convert c code to zig code\n"
41 " targets list available compilation targets\n"43 " targets list available compilation targets\n"
...@@ -53,7 +55,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -53,7 +55,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
53 " --enable-valgrind include valgrind client requests release builds\n"55 " --enable-valgrind include valgrind client requests release builds\n"
54 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"56 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
55 " -ftime-report print timing diagnostics\n"57 " -ftime-report print timing diagnostics\n"
56 " --libc-include-dir [path] directory where libc stdlib.h resides\n"58 " --libc [file] Provide a file which specifies libc paths\n"
57 " --name [name] override output name\n"59 " --name [name] override output name\n"
58 " --output [file] override destination path\n"60 " --output [file] override destination path\n"
59 " --output-h [file] generate header file\n"61 " --output-h [file] generate header file\n"
...@@ -82,10 +84,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -82,10 +84,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
82 "Link Options:\n"84 "Link Options:\n"
83 " --dynamic-linker [path] set the path to ld.so\n"85 " --dynamic-linker [path] set the path to ld.so\n"
84 " --each-lib-rpath add rpath for each used dynamic library\n"86 " --each-lib-rpath add rpath for each used dynamic library\n"
85 " --libc-lib-dir [path] directory where libc crt1.o resides\n"
86 " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
87 " --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n"
88 " --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n"
89 " --library [lib] link against lib\n"87 " --library [lib] link against lib\n"
90 " --forbid-library [lib] make it an error to link against lib\n"88 " --forbid-library [lib] make it an error to link against lib\n"
91 " --library-path [dir] add a directory to the library search path\n"89 " --library-path [dir] add a directory to the library search path\n"
...@@ -111,6 +109,26 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -111,6 +109,26 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
111 return return_code;109 return return_code;
112}110}
113111
112static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
113 fprintf(file,
114 "Usage: %s libc\n"
115 "\n"
116 "Detect the native libc installation and print the resulting paths to stdout.\n"
117 "You can save this into a file and then edit the paths to create a cross\n"
118 "compilation libc kit. Then you can pass `--libc [file]` for Zig to use it.\n"
119 "\n"
120 "When compiling natively and no `--libc` argument provided, Zig automatically\n"
121 "creates zig-cache/native_libc.txt so that it does not have to detect libc\n"
122 "on every invocation. You can remove this file to have Zig re-detect the\n"
123 "native libc.\n"
124 "\n\n"
125 "Usage: %s libc [file]\n"
126 "\n"
127 "Parse a libc installation text file and validate it.\n"
128 , arg0, arg0);
129 return return_code;
130}
131
114static const char *ZIG_ZEN = "\n"132static const char *ZIG_ZEN = "\n"
115" * Communicate intent precisely.\n"133" * Communicate intent precisely.\n"
116" * Edge cases matter.\n"134" * Edge cases matter.\n"
...@@ -169,6 +187,7 @@ enum Cmd {...@@ -169,6 +187,7 @@ enum Cmd {
169 CmdTranslateC,187 CmdTranslateC,
170 CmdVersion,188 CmdVersion,
171 CmdZen,189 CmdZen,
190 CmdLibC,
172};191};
173192
174static const char *default_zig_cache_name = "zig-cache";193static const char *default_zig_cache_name = "zig-cache";
...@@ -359,12 +378,7 @@ int main(int argc, char **argv) {...@@ -359,12 +378,7 @@ int main(int argc, char **argv) {
359 bool verbose_cimport = false;378 bool verbose_cimport = false;
360 ErrColor color = ErrColorAuto;379 ErrColor color = ErrColorAuto;
361 CacheOpt enable_cache = CacheOptAuto;380 CacheOpt enable_cache = CacheOptAuto;
362 const char *libc_lib_dir = nullptr;381 const char *libc_txt = nullptr;
363 const char *libc_static_lib_dir = nullptr;
364 const char *libc_include_dir = nullptr;
365 const char *msvc_lib_dir = nullptr;
366 const char *kernel32_lib_dir = nullptr;
367 const char *dynamic_linker = nullptr;
368 ZigList<const char *> clang_argv = {0};382 ZigList<const char *> clang_argv = {0};
369 ZigList<const char *> llvm_argv = {0};383 ZigList<const char *> llvm_argv = {0};
370 ZigList<const char *> lib_dirs = {0};384 ZigList<const char *> lib_dirs = {0};
...@@ -434,8 +448,10 @@ int main(int argc, char **argv) {...@@ -434,8 +448,10 @@ int main(int argc, char **argv) {
434 Buf *build_runner_path = buf_alloc();448 Buf *build_runner_path = buf_alloc();
435 os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);449 os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
436450
437 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),451 ZigTarget target;
438 override_std_dir);452 get_native_target(&target);
453 CodeGen *g = codegen_create(build_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
454 override_std_dir, nullptr);
439 g->valgrind_support = valgrind_support;455 g->valgrind_support = valgrind_support;
440 g->enable_time_report = timing_info;456 g->enable_time_report = timing_info;
441 buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);457 buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);
...@@ -520,10 +536,12 @@ int main(int argc, char **argv) {...@@ -520,10 +536,12 @@ int main(int argc, char **argv) {
520 return (term.how == TerminationIdClean) ? term.code : -1;536 return (term.how == TerminationIdClean) ? term.code : -1;
521 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {537 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
522 init_all_targets();538 init_all_targets();
539 ZigTarget target;
540 get_native_target(&target);
523 Buf *fmt_runner_path = buf_alloc();541 Buf *fmt_runner_path = buf_alloc();
524 os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);542 os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
525 CodeGen *g = codegen_create(fmt_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),543 CodeGen *g = codegen_create(fmt_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
526 nullptr);544 nullptr, nullptr);
527 g->valgrind_support = valgrind_support;545 g->valgrind_support = valgrind_support;
528 g->is_single_threaded = true;546 g->is_single_threaded = true;
529 codegen_set_out_name(g, buf_create_from_str("fmt"));547 codegen_set_out_name(g, buf_create_from_str("fmt"));
...@@ -557,7 +575,11 @@ int main(int argc, char **argv) {...@@ -557,7 +575,11 @@ int main(int argc, char **argv) {
557 } else if (strcmp(arg, "--release-small") == 0) {575 } else if (strcmp(arg, "--release-small") == 0) {
558 build_mode = BuildModeSmallRelease;576 build_mode = BuildModeSmallRelease;
559 } else if (strcmp(arg, "--help") == 0) {577 } else if (strcmp(arg, "--help") == 0) {
560 return print_full_usage(arg0, stderr, EXIT_FAILURE);578 if (cmd == CmdLibC) {
579 return print_libc_usage(arg0, stderr, EXIT_FAILURE);
580 } else {
581 return print_full_usage(arg0, stderr, EXIT_FAILURE);
582 }
561 } else if (strcmp(arg, "--strip") == 0) {583 } else if (strcmp(arg, "--strip") == 0) {
562 strip = true;584 strip = true;
563 } else if (strcmp(arg, "--static") == 0) {585 } else if (strcmp(arg, "--static") == 0) {
...@@ -658,18 +680,8 @@ int main(int argc, char **argv) {...@@ -658,18 +680,8 @@ int main(int argc, char **argv) {
658 }680 }
659 } else if (strcmp(arg, "--name") == 0) {681 } else if (strcmp(arg, "--name") == 0) {
660 out_name = argv[i];682 out_name = argv[i];
661 } else if (strcmp(arg, "--libc-lib-dir") == 0) {683 } else if (strcmp(arg, "--libc") == 0) {
662 libc_lib_dir = argv[i];684 libc_txt = argv[i];
663 } else if (strcmp(arg, "--libc-static-lib-dir") == 0) {
664 libc_static_lib_dir = argv[i];
665 } else if (strcmp(arg, "--libc-include-dir") == 0) {
666 libc_include_dir = argv[i];
667 } else if (strcmp(arg, "--msvc-lib-dir") == 0) {
668 msvc_lib_dir = argv[i];
669 } else if (strcmp(arg, "--kernel32-lib-dir") == 0) {
670 kernel32_lib_dir = argv[i];
671 } else if (strcmp(arg, "--dynamic-linker") == 0) {
672 dynamic_linker = argv[i];
673 } else if (strcmp(arg, "-isystem") == 0) {685 } else if (strcmp(arg, "-isystem") == 0) {
674 clang_argv.append("-isystem");686 clang_argv.append("-isystem");
675 clang_argv.append(argv[i]);687 clang_argv.append(argv[i]);
...@@ -778,6 +790,8 @@ int main(int argc, char **argv) {...@@ -778,6 +790,8 @@ int main(int argc, char **argv) {
778 cmd = CmdVersion;790 cmd = CmdVersion;
779 } else if (strcmp(arg, "zen") == 0) {791 } else if (strcmp(arg, "zen") == 0) {
780 cmd = CmdZen;792 cmd = CmdZen;
793 } else if (strcmp(arg, "libc") == 0) {
794 cmd = CmdLibC;
781 } else if (strcmp(arg, "translate-c") == 0) {795 } else if (strcmp(arg, "translate-c") == 0) {
782 cmd = CmdTranslateC;796 cmd = CmdTranslateC;
783 } else if (strcmp(arg, "test") == 0) {797 } else if (strcmp(arg, "test") == 0) {
...@@ -797,6 +811,7 @@ int main(int argc, char **argv) {...@@ -797,6 +811,7 @@ int main(int argc, char **argv) {
797 case CmdRun:811 case CmdRun:
798 case CmdTranslateC:812 case CmdTranslateC:
799 case CmdTest:813 case CmdTest:
814 case CmdLibC:
800 if (!in_file) {815 if (!in_file) {
801 in_file = arg;816 in_file = arg;
802 if (cmd == CmdRun) {817 if (cmd == CmdRun) {
...@@ -828,27 +843,25 @@ int main(int argc, char **argv) {...@@ -828,27 +843,25 @@ int main(int argc, char **argv) {
828843
829 init_all_targets();844 init_all_targets();
830845
831 ZigTarget alloc_target;846 ZigTarget target;
832 ZigTarget *target;
833 if (!target_arch && !target_os && !target_environ) {847 if (!target_arch && !target_os && !target_environ) {
834 target = nullptr;848 get_native_target(&target);
835 } else {849 } else {
836 target = &alloc_target;850 get_unknown_target(&target);
837 get_unknown_target(target);
838 if (target_arch) {851 if (target_arch) {
839 if (parse_target_arch(target_arch, &target->arch)) {852 if (parse_target_arch(target_arch, &target.arch)) {
840 fprintf(stderr, "invalid --target-arch argument\n");853 fprintf(stderr, "invalid --target-arch argument\n");
841 return print_error_usage(arg0);854 return print_error_usage(arg0);
842 }855 }
843 }856 }
844 if (target_os) {857 if (target_os) {
845 if (parse_target_os(target_os, &target->os)) {858 if (parse_target_os(target_os, &target.os)) {
846 fprintf(stderr, "invalid --target-os argument\n");859 fprintf(stderr, "invalid --target-os argument\n");
847 return print_error_usage(arg0);860 return print_error_usage(arg0);
848 }861 }
849 }862 }
850 if (target_environ) {863 if (target_environ) {
851 if (parse_target_environ(target_environ, &target->env_type)) {864 if (parse_target_environ(target_environ, &target.env_type)) {
852 fprintf(stderr, "invalid --target-environ argument\n");865 fprintf(stderr, "invalid --target-environ argument\n");
853 return print_error_usage(arg0);866 return print_error_usage(arg0);
854 }867 }
...@@ -856,8 +869,22 @@ int main(int argc, char **argv) {...@@ -856,8 +869,22 @@ int main(int argc, char **argv) {
856 }869 }
857870
858 switch (cmd) {871 switch (cmd) {
872 case CmdLibC: {
873 if (in_file) {
874 ZigLibCInstallation libc;
875 if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))
876 return EXIT_FAILURE;
877 return EXIT_SUCCESS;
878 }
879 ZigLibCInstallation libc;
880 if ((err = zig_libc_find_native(&libc, true)))
881 return EXIT_FAILURE;
882 zig_libc_render(&libc, stdout);
883 return EXIT_SUCCESS;
884 }
859 case CmdBuiltin: {885 case CmdBuiltin: {
860 CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir);886 CodeGen *g = codegen_create(nullptr, &target, out_type, build_mode, get_zig_lib_dir(), override_std_dir,
887 nullptr);
861 g->valgrind_support = valgrind_support;888 g->valgrind_support = valgrind_support;
862 g->is_single_threaded = is_single_threaded;889 g->is_single_threaded = is_single_threaded;
863 Buf *builtin_source = codegen_generate_builtin_source(g);890 Buf *builtin_source = codegen_generate_builtin_source(g);
...@@ -917,8 +944,16 @@ int main(int argc, char **argv) {...@@ -917,8 +944,16 @@ int main(int argc, char **argv) {
917 if (cmd == CmdRun && buf_out_name == nullptr) {944 if (cmd == CmdRun && buf_out_name == nullptr) {
918 buf_out_name = buf_create_from_str("run");945 buf_out_name = buf_create_from_str("run");
919 }946 }
920 CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(),947 ZigLibCInstallation *libc = nullptr;
921 override_std_dir);948 if (libc_txt != nullptr) {
949 libc = allocate<ZigLibCInstallation>(1);
950 if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {
951 fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
952 return EXIT_FAILURE;
953 }
954 }
955 CodeGen *g = codegen_create(zig_root_source_file, &target, out_type, build_mode, get_zig_lib_dir(),
956 override_std_dir, libc);
922 g->valgrind_support = valgrind_support;957 g->valgrind_support = valgrind_support;
923 g->subsystem = subsystem;958 g->subsystem = subsystem;
924959
...@@ -944,18 +979,6 @@ int main(int argc, char **argv) {...@@ -944,18 +979,6 @@ int main(int argc, char **argv) {
944 codegen_set_llvm_argv(g, llvm_argv.items, llvm_argv.length);979 codegen_set_llvm_argv(g, llvm_argv.items, llvm_argv.length);
945 codegen_set_strip(g, strip);980 codegen_set_strip(g, strip);
946 codegen_set_is_static(g, is_static);981 codegen_set_is_static(g, is_static);
947 if (libc_lib_dir)
948 codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
949 if (libc_static_lib_dir)
950 codegen_set_libc_static_lib_dir(g, buf_create_from_str(libc_static_lib_dir));
951 if (libc_include_dir)
952 codegen_set_libc_include_dir(g, buf_create_from_str(libc_include_dir));
953 if (msvc_lib_dir)
954 codegen_set_msvc_lib_dir(g, buf_create_from_str(msvc_lib_dir));
955 if (kernel32_lib_dir)
956 codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir));
957 if (dynamic_linker)
958 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
959 g->verbose_tokenize = verbose_tokenize;982 g->verbose_tokenize = verbose_tokenize;
960 g->verbose_ast = verbose_ast;983 g->verbose_ast = verbose_ast;
961 g->verbose_link = verbose_link;984 g->verbose_link = verbose_link;
...@@ -1086,7 +1109,7 @@ int main(int argc, char **argv) {...@@ -1086,7 +1109,7 @@ int main(int argc, char **argv) {
1086 }1109 }
1087 }1110 }
10881111
1089 if (!target_can_exec(&native, target)) {1112 if (!target_can_exec(&native, &target)) {
1090 fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",1113 fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",
1091 buf_ptr(test_exe_path));1114 buf_ptr(test_exe_path));
1092 return 0;1115 return 0;
src/os.cpp+7-7
...@@ -1550,7 +1550,7 @@ void os_stderr_set_color(TermColor color) {...@@ -1550,7 +1550,7 @@ void os_stderr_set_color(TermColor color) {
1550#endif1550#endif
1551}1551}
15521552
1553int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {1553Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1554#if defined(ZIG_OS_WINDOWS)1554#if defined(ZIG_OS_WINDOWS)
1555 buf_resize(output_buf, 0);1555 buf_resize(output_buf, 0);
1556 buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);1556 buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
...@@ -1571,7 +1571,7 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch...@@ -1571,7 +1571,7 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
1571 buf_init_from_buf(tmp_buf, output_buf);1571 buf_init_from_buf(tmp_buf, output_buf);
1572 buf_append_str(tmp_buf, "ucrt.lib");1572 buf_append_str(tmp_buf, "ucrt.lib");
1573 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {1573 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1574 return 0;1574 return ErrorNone;
1575 }1575 }
1576 else {1576 else {
1577 buf_resize(output_buf, 0);1577 buf_resize(output_buf, 0);
...@@ -1582,12 +1582,12 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch...@@ -1582,12 +1582,12 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
1582#endif1582#endif
1583}1583}
15841584
1585int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {1585Error os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
1586#if defined(ZIG_OS_WINDOWS)1586#if defined(ZIG_OS_WINDOWS)
1587 buf_resize(output_buf, 0);1587 buf_resize(output_buf, 0);
1588 buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);1588 buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
1589 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {1589 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
1590 return 0;1590 return ErrorNone;
1591 }1591 }
1592 else {1592 else {
1593 buf_resize(output_buf, 0);1593 buf_resize(output_buf, 0);
...@@ -1598,7 +1598,7 @@ int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {...@@ -1598,7 +1598,7 @@ int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
1598#endif1598#endif
1599}1599}
16001600
1601int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {1601Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1602#if defined(ZIG_OS_WINDOWS)1602#if defined(ZIG_OS_WINDOWS)
1603 {1603 {
1604 buf_resize(output_buf, 0);1604 buf_resize(output_buf, 0);
...@@ -1620,7 +1620,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy...@@ -1620,7 +1620,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
1620 buf_init_from_buf(tmp_buf, output_buf);1620 buf_init_from_buf(tmp_buf, output_buf);
1621 buf_append_str(tmp_buf, "kernel32.lib");1621 buf_append_str(tmp_buf, "kernel32.lib");
1622 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {1622 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1623 return 0;1623 return ErrorNone;
1624 }1624 }
1625 }1625 }
1626 {1626 {
...@@ -1643,7 +1643,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy...@@ -1643,7 +1643,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
1643 buf_init_from_buf(tmp_buf, output_buf);1643 buf_init_from_buf(tmp_buf, output_buf);
1644 buf_append_str(tmp_buf, "kernel32.lib");1644 buf_append_str(tmp_buf, "kernel32.lib");
1645 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {1645 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1646 return 0;1646 return ErrorNone;
1647 }1647 }
1648 }1648 }
1649 return ErrorFileNotFound;1649 return ErrorFileNotFound;
src/os.hpp+3-3
...@@ -135,9 +135,9 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);...@@ -135,9 +135,9 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);
135135
136Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);136Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);
137137
138int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);138Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
139int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);139Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
140int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);140Error ATTRIBUTE_MUST_USE os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
141141
142Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);142Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);
143143
src/target.cpp+38-87
...@@ -214,7 +214,7 @@ size_t target_oformat_count(void) {...@@ -214,7 +214,7 @@ size_t target_oformat_count(void) {
214 return array_length(oformat_list);214 return array_length(oformat_list);
215}215}
216216
217const ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {217ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {
218 return oformat_list[index];218 return oformat_list[index];
219}219}
220220
...@@ -443,14 +443,16 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) {...@@ -443,14 +443,16 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) {
443443
444void get_native_target(ZigTarget *target) {444void get_native_target(ZigTarget *target) {
445 ZigLLVM_OSType os_type;445 ZigLLVM_OSType os_type;
446 ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
446 ZigLLVMGetNativeTarget(447 ZigLLVMGetNativeTarget(
447 &target->arch.arch,448 &target->arch.arch,
448 &target->arch.sub_arch,449 &target->arch.sub_arch,
449 &target->vendor,450 &target->vendor,
450 &os_type,451 &os_type,
451 &target->env_type,452 &target->env_type,
452 &target->oformat);453 &oformat);
453 target->os = get_zig_os_type(os_type);454 target->os = get_zig_os_type(os_type);
455 target->is_native = true;
454}456}
455457
456void get_unknown_target(ZigTarget *target) {458void get_unknown_target(ZigTarget *target) {
...@@ -459,7 +461,7 @@ void get_unknown_target(ZigTarget *target) {...@@ -459,7 +461,7 @@ void get_unknown_target(ZigTarget *target) {
459 target->vendor = ZigLLVM_UnknownVendor;461 target->vendor = ZigLLVM_UnknownVendor;
460 target->os = OsFreestanding;462 target->os = OsFreestanding;
461 target->env_type = ZigLLVM_UnknownEnvironment;463 target->env_type = ZigLLVM_UnknownEnvironment;
462 target->oformat = ZigLLVM_UnknownObjectFormat;464 target->is_native = false;
463}465}
464466
465static void get_arch_name_raw(char *out_str, ZigLLVM_ArchType arch, ZigLLVM_SubArchType sub_arch) {467static void get_arch_name_raw(char *out_str, ZigLLVM_ArchType arch, ZigLLVM_SubArchType sub_arch) {
...@@ -554,85 +556,18 @@ bool target_is_darwin(const ZigTarget *target) {...@@ -554,85 +556,18 @@ bool target_is_darwin(const ZigTarget *target) {
554 }556 }
555}557}
556558
557void resolve_target_object_format(ZigTarget *target) {559ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) {
558 if (target->oformat != ZigLLVM_UnknownObjectFormat) {560 if (target->os == OsUefi || target->os == OsWindows) {
559 return;561 return ZigLLVM_COFF;
562 } else if (target_is_darwin(target)) {
563 return ZigLLVM_MachO;
560 }564 }
561565 if (target->arch.arch == ZigLLVM_wasm32 ||
562 switch (target->arch.arch) {566 target->arch.arch == ZigLLVM_wasm64)
563 case ZigLLVM_UnknownArch:567 {
564 case ZigLLVM_aarch64:568 return ZigLLVM_Wasm;
565 case ZigLLVM_arm:
566 case ZigLLVM_thumb:
567 case ZigLLVM_x86:
568 case ZigLLVM_x86_64:
569 if (target_is_darwin(target)) {
570 target->oformat = ZigLLVM_MachO;
571 } else if (target->os == OsWindows) {
572 target->oformat = ZigLLVM_COFF;
573 } else {
574 target->oformat = ZigLLVM_ELF;
575 }
576 return;
577
578 case ZigLLVM_aarch64_be:
579 case ZigLLVM_amdgcn:
580 case ZigLLVM_amdil:
581 case ZigLLVM_amdil64:
582 case ZigLLVM_armeb:
583 case ZigLLVM_arc:
584 case ZigLLVM_avr:
585 case ZigLLVM_bpfeb:
586 case ZigLLVM_bpfel:
587 case ZigLLVM_hexagon:
588 case ZigLLVM_lanai:
589 case ZigLLVM_hsail:
590 case ZigLLVM_hsail64:
591 case ZigLLVM_kalimba:
592 case ZigLLVM_le32:
593 case ZigLLVM_le64:
594 case ZigLLVM_mips:
595 case ZigLLVM_mips64:
596 case ZigLLVM_mips64el:
597 case ZigLLVM_mipsel:
598 case ZigLLVM_msp430:
599 case ZigLLVM_nios2:
600 case ZigLLVM_nvptx:
601 case ZigLLVM_nvptx64:
602 case ZigLLVM_ppc64le:
603 case ZigLLVM_r600:
604 case ZigLLVM_renderscript32:
605 case ZigLLVM_renderscript64:
606 case ZigLLVM_riscv32:
607 case ZigLLVM_riscv64:
608 case ZigLLVM_shave:
609 case ZigLLVM_sparc:
610 case ZigLLVM_sparcel:
611 case ZigLLVM_sparcv9:
612 case ZigLLVM_spir:
613 case ZigLLVM_spir64:
614 case ZigLLVM_systemz:
615 case ZigLLVM_tce:
616 case ZigLLVM_tcele:
617 case ZigLLVM_thumbeb:
618 case ZigLLVM_xcore:
619 target->oformat= ZigLLVM_ELF;
620 return;
621
622 case ZigLLVM_wasm32:
623 case ZigLLVM_wasm64:
624 target->oformat = ZigLLVM_Wasm;
625 return;
626
627 case ZigLLVM_ppc:
628 case ZigLLVM_ppc64:
629 if (target_is_darwin(target)) {
630 target->oformat = ZigLLVM_MachO;
631 } else {
632 target->oformat= ZigLLVM_ELF;
633 }
634 return;
635 }569 }
570 return ZigLLVM_ELF;
636}571}
637572
638// See lib/Support/Triple.cpp in LLVM for the source of this data.573// See lib/Support/Triple.cpp in LLVM for the source of this data.
...@@ -812,7 +747,7 @@ bool target_allows_addr_zero(const ZigTarget *target) {...@@ -812,7 +747,7 @@ bool target_allows_addr_zero(const ZigTarget *target) {
812 return target->os == OsFreestanding;747 return target->os == OsFreestanding;
813}748}
814749
815const char *target_o_file_ext(ZigTarget *target) {750const char *target_o_file_ext(const ZigTarget *target) {
816 if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {751 if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
817 return ".obj";752 return ".obj";
818 } else {753 } else {
...@@ -820,15 +755,15 @@ const char *target_o_file_ext(ZigTarget *target) {...@@ -820,15 +755,15 @@ const char *target_o_file_ext(ZigTarget *target) {
820 }755 }
821}756}
822757
823const char *target_asm_file_ext(ZigTarget *target) {758const char *target_asm_file_ext(const ZigTarget *target) {
824 return ".s";759 return ".s";
825}760}
826761
827const char *target_llvm_ir_file_ext(ZigTarget *target) {762const char *target_llvm_ir_file_ext(const ZigTarget *target) {
828 return ".ll";763 return ".ll";
829}764}
830765
831const char *target_exe_file_ext(ZigTarget *target) {766const char *target_exe_file_ext(const ZigTarget *target) {
832 if (target->os == OsWindows) {767 if (target->os == OsWindows) {
833 return ".exe";768 return ".exe";
834 } else if (target->os == OsUefi) {769 } else if (target->os == OsUefi) {
...@@ -838,7 +773,9 @@ const char *target_exe_file_ext(ZigTarget *target) {...@@ -838,7 +773,9 @@ const char *target_exe_file_ext(ZigTarget *target) {
838 }773 }
839}774}
840775
841const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) {776const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
777 size_t version_major, size_t version_minor, size_t version_patch)
778{
842 if (target->os == OsWindows || target->os == OsUefi) {779 if (target->os == OsWindows || target->os == OsUefi) {
843 if (is_static) {780 if (is_static) {
844 return ".lib";781 return ".lib";
...@@ -860,7 +797,7 @@ enum FloatAbi {...@@ -860,7 +797,7 @@ enum FloatAbi {
860 FloatAbiSoftFp,797 FloatAbiSoftFp,
861};798};
862799
863static FloatAbi get_float_abi(ZigTarget *target) {800static FloatAbi get_float_abi(const ZigTarget *target) {
864 const ZigLLVM_EnvironmentType env = target->env_type;801 const ZigLLVM_EnvironmentType env = target->env_type;
865 if (env == ZigLLVM_GNUEABIHF ||802 if (env == ZigLLVM_GNUEABIHF ||
866 env == ZigLLVM_EABIHF ||803 env == ZigLLVM_EABIHF ||
...@@ -876,7 +813,14 @@ static bool is_64_bit(ZigLLVM_ArchType arch) {...@@ -876,7 +813,14 @@ static bool is_64_bit(ZigLLVM_ArchType arch) {
876 return get_arch_pointer_bit_width(arch) == 64;813 return get_arch_pointer_bit_width(arch) == 64;
877}814}
878815
879Buf *target_dynamic_linker(ZigTarget *target) {816Buf *target_dynamic_linker(const ZigTarget *target) {
817 if (target->os == OsFreeBSD) {
818 return buf_create_from_str("/libexec/ld-elf.so.1");
819 }
820 if (target->os == OsNetBSD) {
821 return buf_create_from_str("/libexec/ld.elf_so");
822 }
823
880 const ZigLLVM_ArchType arch = target->arch.arch;824 const ZigLLVM_ArchType arch = target->arch.arch;
881 const ZigLLVM_EnvironmentType env = target->env_type;825 const ZigLLVM_EnvironmentType env = target->env_type;
882826
...@@ -1098,3 +1042,10 @@ bool target_has_valgrind_support(const ZigTarget *target) {...@@ -1098,3 +1042,10 @@ bool target_has_valgrind_support(const ZigTarget *target) {
1098 }1042 }
1099 zig_unreachable();1043 zig_unreachable();
1100}1044}
1045
1046bool target_requires_libc(const ZigTarget *target) {
1047 // On Darwin, we always link libSystem which contains libc.
1048 // Similarly on FreeBSD and NetBSD we always link system libc
1049 // since this is the stable syscall interface.
1050 return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);
1051}
src/target.hpp+11-8
...@@ -71,7 +71,7 @@ struct ZigTarget {...@@ -71,7 +71,7 @@ struct ZigTarget {
71 ZigLLVM_VendorType vendor;71 ZigLLVM_VendorType vendor;
72 Os os;72 Os os;
73 ZigLLVM_EnvironmentType env_type;73 ZigLLVM_EnvironmentType env_type;
74 ZigLLVM_ObjectFormatType oformat;74 bool is_native;
75};75};
7676
77enum CIntType {77enum CIntType {
...@@ -105,8 +105,9 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index);...@@ -105,8 +105,9 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index);
105105
106106
107size_t target_oformat_count(void);107size_t target_oformat_count(void);
108const ZigLLVM_ObjectFormatType get_target_oformat(size_t index);108ZigLLVM_ObjectFormatType get_target_oformat(size_t index);
109const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat);109const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat);
110ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target);
110111
111void get_native_target(ZigTarget *target);112void get_native_target(ZigTarget *target);
112void get_unknown_target(ZigTarget *target);113void get_unknown_target(ZigTarget *target);
...@@ -123,13 +124,14 @@ void resolve_target_object_format(ZigTarget *target);...@@ -123,13 +124,14 @@ void resolve_target_object_format(ZigTarget *target);
123124
124uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);125uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
125126
126const char *target_o_file_ext(ZigTarget *target);127const char *target_o_file_ext(const ZigTarget *target);
127const char *target_asm_file_ext(ZigTarget *target);128const char *target_asm_file_ext(const ZigTarget *target);
128const char *target_llvm_ir_file_ext(ZigTarget *target);129const char *target_llvm_ir_file_ext(const ZigTarget *target);
129const char *target_exe_file_ext(ZigTarget *target);130const char *target_exe_file_ext(const ZigTarget *target);
130const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch);131const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
132 size_t version_major, size_t version_minor, size_t version_patch);
131133
132Buf *target_dynamic_linker(ZigTarget *target);134Buf *target_dynamic_linker(const ZigTarget *target);
133135
134bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);136bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
135ZigLLVM_OSType get_llvm_os_type(Os os_type);137ZigLLVM_OSType get_llvm_os_type(Os os_type);
...@@ -138,5 +140,6 @@ bool target_is_arm(const ZigTarget *target);...@@ -138,5 +140,6 @@ bool target_is_arm(const ZigTarget *target);
138bool target_allows_addr_zero(const ZigTarget *target);140bool target_allows_addr_zero(const ZigTarget *target);
139bool target_has_valgrind_support(const ZigTarget *target);141bool target_has_valgrind_support(const ZigTarget *target);
140bool target_is_darwin(const ZigTarget *target);142bool target_is_darwin(const ZigTarget *target);
143bool target_requires_libc(const ZigTarget *target);
141144
142#endif145#endif
src/translate_c.cpp+4-4
...@@ -4776,7 +4776,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const...@@ -4776,7 +4776,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
4776 clang_argv.append("-x");4776 clang_argv.append("-x");
4777 clang_argv.append("c");4777 clang_argv.append("c");
47784778
4779 if (c->codegen->is_native_target) {4779 if (c->codegen->zig_target->is_native) {
4780 char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");4780 char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");
4781 if (ZIG_PARSEC_CFLAGS) {4781 if (ZIG_PARSEC_CFLAGS) {
4782 Buf tmp_buf = BUF_INIT;4782 Buf tmp_buf = BUF_INIT;
...@@ -4798,9 +4798,9 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const...@@ -4798,9 +4798,9 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
4798 clang_argv.append("-isystem");4798 clang_argv.append("-isystem");
4799 clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));4799 clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
48004800
4801 if (codegen->libc_include_dir != nullptr) {4801 if (codegen->libc != nullptr) {
4802 clang_argv.append("-isystem");4802 clang_argv.append("-isystem");
4803 clang_argv.append(buf_ptr(codegen->libc_include_dir));4803 clang_argv.append(buf_ptr(&codegen->libc->include_dir));
4804 }4804 }
48054805
4806 // windows c runtime requires -D_DEBUG if using debug libraries4806 // windows c runtime requires -D_DEBUG if using debug libraries
...@@ -4820,7 +4820,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const...@@ -4820,7 +4820,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
4820 clang_argv.append("-Xclang");4820 clang_argv.append("-Xclang");
4821 clang_argv.append("-detailed-preprocessing-record");4821 clang_argv.append("-detailed-preprocessing-record");
48224822
4823 if (!c->codegen->is_native_target) {4823 if (!c->codegen->zig_target->is_native) {
4824 clang_argv.append("-target");4824 clang_argv.append("-target");
4825 clang_argv.append(buf_ptr(&c->codegen->triple_str));4825 clang_argv.append(buf_ptr(&c->codegen->triple_str));
4826 }4826 }