mirror of
https://github.com/ziglang/zig.git
synced 2025-01-31 14:21:14 +00:00
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.
This commit is contained in:
parent
52bb71867d
commit
6fd8d455bc
@ -414,6 +414,7 @@ set(ZIG_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/error.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/ir.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/link.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/main.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/os.cpp"
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "bigfloat.hpp"
|
||||
#include "target.hpp"
|
||||
#include "tokenizer.hpp"
|
||||
#include "libc_installation.hpp"
|
||||
|
||||
struct AstNode;
|
||||
struct ImportTableEntry;
|
||||
@ -1743,6 +1744,9 @@ struct CodeGen {
|
||||
Buf *wanted_output_file_path;
|
||||
Buf cache_dir;
|
||||
|
||||
Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir.
|
||||
Buf *zig_std_special_dir; // Cannot be overridden; derived from zig_lib_dir.
|
||||
|
||||
IrInstruction *invalid_instruction;
|
||||
IrInstruction *unreach_instruction;
|
||||
|
||||
@ -1791,6 +1795,8 @@ struct CodeGen {
|
||||
bool system_linker_hack;
|
||||
|
||||
//////////////////////////// Participates in Input Parameter Cache Hash
|
||||
/////// Note: there is a separate cache hash for builtin.zig, when adding fields,
|
||||
/////// consider if they need to go into both.
|
||||
ZigList<LinkLib *> link_libs_list;
|
||||
// add -framework [name] args to linker
|
||||
ZigList<Buf *> darwin_frameworks;
|
||||
@ -1801,6 +1807,8 @@ struct CodeGen {
|
||||
ZigList<Buf *> assembly_files;
|
||||
ZigList<const char *> lib_dirs;
|
||||
|
||||
ZigLibCInstallation *libc;
|
||||
|
||||
size_t version_major;
|
||||
size_t version_minor;
|
||||
size_t version_patch;
|
||||
@ -1809,14 +1817,13 @@ struct CodeGen {
|
||||
EmitFileType emit_file_type;
|
||||
BuildMode build_mode;
|
||||
OutType out_type;
|
||||
ZigTarget zig_target;
|
||||
const ZigTarget *zig_target;
|
||||
TargetSubsystem subsystem;
|
||||
ValgrindSupport valgrind_support;
|
||||
bool is_static;
|
||||
bool strip_debug_symbols;
|
||||
bool is_test_build;
|
||||
bool is_single_threaded;
|
||||
bool is_native_target;
|
||||
bool linker_rdynamic;
|
||||
bool each_lib_rpath;
|
||||
bool disable_pic;
|
||||
@ -1827,26 +1834,14 @@ struct CodeGen {
|
||||
Buf *test_filter;
|
||||
Buf *test_name_prefix;
|
||||
PackageTableEntry *root_package;
|
||||
Buf *zig_lib_dir;
|
||||
Buf *zig_std_dir;
|
||||
|
||||
const char **llvm_argv;
|
||||
size_t llvm_argv_len;
|
||||
|
||||
const char **clang_argv;
|
||||
size_t clang_argv_len;
|
||||
|
||||
//////////////////////////// Unsorted
|
||||
|
||||
Buf *libc_lib_dir;
|
||||
Buf *libc_static_lib_dir;
|
||||
Buf *libc_include_dir;
|
||||
Buf *msvc_lib_dir;
|
||||
Buf *kernel32_lib_dir;
|
||||
Buf *zig_lib_dir;
|
||||
Buf *zig_std_dir;
|
||||
Buf *zig_c_headers_dir;
|
||||
Buf *zig_std_special_dir;
|
||||
Buf *dynamic_linker;
|
||||
ZigWindowsSDK *win_sdk;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
|
198
src/analyze.cpp
198
src/analyze.cpp
@ -1102,10 +1102,10 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
if (type_is_c_abi_int(g, fn_type_id->return_type)) {
|
||||
return false;
|
||||
}
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
|
||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
|
||||
return abi_class == X64CABIClass_MEMORY;
|
||||
} else if (target_is_arm(&g->zig_target)) {
|
||||
} else if (target_is_arm(g->zig_target)) {
|
||||
return type_size(g, fn_type_id->return_type) > 16;
|
||||
}
|
||||
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
|
||||
g->have_c_main = true;
|
||||
g->subsystem = TargetSubsystemConsole;
|
||||
} else if (buf_eql_str(symbol_name, "WinMain") &&
|
||||
g->zig_target.os == OsWindows)
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_winmain = true;
|
||||
g->subsystem = TargetSubsystemWindows;
|
||||
} else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
|
||||
g->zig_target.os == OsWindows)
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_winmain_crt_startup = true;
|
||||
} else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
|
||||
g->zig_target.os == OsWindows)
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_dllmain_crt_startup = true;
|
||||
}
|
||||
@ -4651,186 +4651,6 @@ bool handle_is_ptr(ZigType *type_entry) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static ZigWindowsSDK *get_windows_sdk(CodeGen *g) {
|
||||
if (g->win_sdk == nullptr) {
|
||||
if (zig_find_windows_sdk(&g->win_sdk)) {
|
||||
fprintf(stderr, "unable to determine windows sdk path\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
assert(g->win_sdk != nullptr);
|
||||
return g->win_sdk;
|
||||
}
|
||||
|
||||
|
||||
static Buf *get_linux_libc_lib_path(const char *o_file) {
|
||||
const char *cc_exe = getenv("CC");
|
||||
cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
|
||||
ZigList<const char *> args = {};
|
||||
args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
|
||||
Termination term;
|
||||
Buf *out_stderr = buf_alloc();
|
||||
Buf *out_stdout = buf_alloc();
|
||||
Error err;
|
||||
if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
|
||||
zig_panic("unable to determine libc lib path: executing C compiler: %s", err_str(err));
|
||||
}
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
zig_panic("unable to determine libc lib path: executing C compiler command failed");
|
||||
}
|
||||
if (buf_ends_with_str(out_stdout, "\n")) {
|
||||
buf_resize(out_stdout, buf_len(out_stdout) - 1);
|
||||
}
|
||||
if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
|
||||
zig_panic("unable to determine libc lib path: C compiler could not find %s", o_file);
|
||||
}
|
||||
Buf *result = buf_alloc();
|
||||
os_path_dirname(out_stdout, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Buf *get_posix_libc_include_path(void) {
|
||||
const char *cc_exe = getenv("CC");
|
||||
cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
|
||||
ZigList<const char *> args = {};
|
||||
args.append("-E");
|
||||
args.append("-Wp,-v");
|
||||
args.append("-xc");
|
||||
args.append("/dev/null");
|
||||
Termination term;
|
||||
Buf *out_stderr = buf_alloc();
|
||||
Buf *out_stdout = buf_alloc();
|
||||
Error err;
|
||||
if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
|
||||
zig_panic("unable to determine libc include path: executing C compiler: %s", err_str(err));
|
||||
}
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
zig_panic("unable to determine libc include path: executing C compiler command failed");
|
||||
}
|
||||
char *prev_newline = buf_ptr(out_stderr);
|
||||
ZigList<const char *> search_paths = {};
|
||||
for (;;) {
|
||||
char *newline = strchr(prev_newline, '\n');
|
||||
if (newline == nullptr) {
|
||||
break;
|
||||
}
|
||||
*newline = 0;
|
||||
if (prev_newline[0] == ' ') {
|
||||
search_paths.append(prev_newline);
|
||||
}
|
||||
prev_newline = newline + 1;
|
||||
}
|
||||
if (search_paths.length == 0) {
|
||||
zig_panic("unable to determine libc include path: even C compiler does not know where libc headers are");
|
||||
}
|
||||
for (size_t i = 0; i < search_paths.length; i += 1) {
|
||||
// search in reverse order
|
||||
const char *search_path = search_paths.items[search_paths.length - i - 1];
|
||||
// cut off spaces
|
||||
while (*search_path == ' ') {
|
||||
search_path += 1;
|
||||
}
|
||||
Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
|
||||
bool exists;
|
||||
if ((err = os_file_exists(stdlib_path, &exists))) {
|
||||
exists = false;
|
||||
}
|
||||
if (exists) {
|
||||
return buf_create_from_str(search_path);
|
||||
}
|
||||
}
|
||||
zig_panic("unable to determine libc include path: stdlib.h not found in C compiler search paths");
|
||||
}
|
||||
|
||||
void find_libc_include_path(CodeGen *g) {
|
||||
if (g->libc_include_dir == nullptr) {
|
||||
if (!g->is_native_target) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g->zig_target.os == OsWindows) {
|
||||
ZigWindowsSDK *sdk = get_windows_sdk(g);
|
||||
g->libc_include_dir = buf_alloc();
|
||||
if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) {
|
||||
fprintf(stderr, "Unable to determine libc include path. --libc-include-dir");
|
||||
exit(1);
|
||||
}
|
||||
} else if (g->zig_target.os == OsLinux ||
|
||||
g->zig_target.os == OsMacOSX ||
|
||||
g->zig_target.os == OsFreeBSD ||
|
||||
g->zig_target.os == OsNetBSD)
|
||||
{
|
||||
g->libc_include_dir = get_posix_libc_include_path();
|
||||
} else {
|
||||
fprintf(stderr, "Unable to determine libc include path.\n"
|
||||
"TODO: implement finding libc at runtime for other operating systems.\n"
|
||||
"in the meantime, you can use as a workaround: --libc-include-dir\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
assert(buf_len(g->libc_include_dir) != 0);
|
||||
}
|
||||
|
||||
void find_libc_lib_path(CodeGen *g) {
|
||||
// later we can handle this better by reporting an error via the normal mechanism
|
||||
if (g->libc_lib_dir == nullptr ||
|
||||
(g->zig_target.os == OsWindows && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr)))
|
||||
{
|
||||
if (g->zig_target.os == OsWindows) {
|
||||
ZigWindowsSDK *sdk = get_windows_sdk(g);
|
||||
|
||||
if (g->msvc_lib_dir == nullptr) {
|
||||
if (sdk->msvc_lib_dir_ptr == nullptr) {
|
||||
fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir");
|
||||
exit(1);
|
||||
}
|
||||
g->msvc_lib_dir = buf_create_from_mem(sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
|
||||
}
|
||||
|
||||
if (g->libc_lib_dir == nullptr) {
|
||||
Buf* ucrt_lib_path = buf_alloc();
|
||||
if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) {
|
||||
fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir");
|
||||
exit(1);
|
||||
}
|
||||
g->libc_lib_dir = ucrt_lib_path;
|
||||
}
|
||||
|
||||
if (g->kernel32_lib_dir == nullptr) {
|
||||
Buf* kern_lib_path = buf_alloc();
|
||||
if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) {
|
||||
fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir");
|
||||
exit(1);
|
||||
}
|
||||
g->kernel32_lib_dir = kern_lib_path;
|
||||
}
|
||||
|
||||
} else if (g->zig_target.os == OsLinux) {
|
||||
g->libc_lib_dir = get_linux_libc_lib_path("crt1.o");
|
||||
} else if ((g->zig_target.os == OsFreeBSD) || (g->zig_target.os == OsNetBSD)) {
|
||||
g->libc_lib_dir = buf_create_from_str("/usr/lib");
|
||||
} else {
|
||||
zig_panic("Unable to determine libc lib path.");
|
||||
}
|
||||
} else {
|
||||
assert(buf_len(g->libc_lib_dir) != 0);
|
||||
}
|
||||
|
||||
if (g->libc_static_lib_dir == nullptr) {
|
||||
if ((g->zig_target.os == OsWindows) && (g->msvc_lib_dir != NULL)) {
|
||||
return;
|
||||
} else if (g->zig_target.os == OsLinux) {
|
||||
g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o");
|
||||
} else if ((g->zig_target.os == OsFreeBSD) || (g->zig_target.os == OsNetBSD)) {
|
||||
g->libc_static_lib_dir = buf_create_from_str("/usr/lib");
|
||||
} else {
|
||||
zig_panic("Unable to determine libc static lib path.");
|
||||
}
|
||||
} else {
|
||||
assert(buf_len(g->libc_static_lib_dir) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t hash_ptr(void *ptr) {
|
||||
return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);
|
||||
}
|
||||
@ -6736,14 +6556,6 @@ LinkLib *add_link_lib(CodeGen *g, Buf *name) {
|
||||
if (is_libc && g->libc_link_lib != nullptr)
|
||||
return g->libc_link_lib;
|
||||
|
||||
if (g->enable_cache && is_libc && g->zig_target.os != OsMacOSX &&
|
||||
g->zig_target.os != OsIOS && g->zig_target.os != OsFreeBSD &&
|
||||
g->zig_target.os != OsNetBSD) {
|
||||
fprintf(stderr, "TODO linking against libc is currently incompatible with `--cache on`.\n"
|
||||
"Zig is not yet capable of determining whether the libc installation has changed on subsequent builds.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
|
||||
LinkLib *existing_lib = g->link_libs_list.at(i);
|
||||
if (buf_eql_buf(existing_lib->name, name)) {
|
||||
|
@ -40,8 +40,6 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type);
|
||||
ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type);
|
||||
ZigType *get_test_fn_type(CodeGen *g);
|
||||
bool handle_is_ptr(ZigType *type_entry);
|
||||
void find_libc_include_path(CodeGen *g);
|
||||
void find_libc_lib_path(CodeGen *g);
|
||||
|
||||
bool type_has_bits(ZigType *type_entry);
|
||||
bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
|
||||
|
234
src/codegen.cpp
234
src/codegen.cpp
@ -29,9 +29,9 @@ static void init_darwin_native(CodeGen *g) {
|
||||
|
||||
// Allow conflicts among OSX and iOS, but choose the default platform.
|
||||
if (osx_target && ios_target) {
|
||||
if (g->zig_target.arch.arch == ZigLLVM_arm ||
|
||||
g->zig_target.arch.arch == ZigLLVM_aarch64 ||
|
||||
g->zig_target.arch.arch == ZigLLVM_thumb)
|
||||
if (g->zig_target->arch.arch == ZigLLVM_arm ||
|
||||
g->zig_target->arch.arch == ZigLLVM_aarch64 ||
|
||||
g->zig_target->arch.arch == ZigLLVM_thumb)
|
||||
{
|
||||
osx_target = nullptr;
|
||||
} else {
|
||||
@ -43,7 +43,7 @@ static void init_darwin_native(CodeGen *g) {
|
||||
g->mmacosx_version_min = buf_create_from_str(osx_target);
|
||||
} else if (ios_target) {
|
||||
g->mios_version_min = buf_create_from_str(ios_target);
|
||||
} else if (g->zig_target.os != OsIOS) {
|
||||
} else if (g->zig_target->os != OsIOS) {
|
||||
g->mmacosx_version_min = buf_create_from_str("10.10");
|
||||
}
|
||||
}
|
||||
@ -88,13 +88,15 @@ static const char *symbols_that_llvm_depends_on[] = {
|
||||
};
|
||||
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
|
||||
Buf *zig_lib_dir, Buf *override_std_dir)
|
||||
Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc)
|
||||
{
|
||||
CodeGen *g = allocate<CodeGen>(1);
|
||||
|
||||
codegen_add_time_event(g, "Initialize");
|
||||
|
||||
g->libc = libc;
|
||||
g->zig_lib_dir = zig_lib_dir;
|
||||
g->zig_target = target;
|
||||
|
||||
if (override_std_dir == nullptr) {
|
||||
g->zig_std_dir = buf_alloc();
|
||||
@ -149,44 +151,19 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
|
||||
g->zig_std_special_dir = buf_alloc();
|
||||
os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
|
||||
|
||||
if (target) {
|
||||
// cross compiling, so we can't rely on all the configured stuff since
|
||||
// that's for native compilation
|
||||
g->zig_target = *target;
|
||||
resolve_target_object_format(&g->zig_target);
|
||||
g->dynamic_linker = nullptr;
|
||||
g->libc_lib_dir = nullptr;
|
||||
g->libc_static_lib_dir = nullptr;
|
||||
g->libc_include_dir = nullptr;
|
||||
g->msvc_lib_dir = nullptr;
|
||||
g->kernel32_lib_dir = nullptr;
|
||||
assert(target != nullptr);
|
||||
if (!target->is_native) {
|
||||
g->each_lib_rpath = false;
|
||||
} else {
|
||||
// native compilation, we can rely on the configuration stuff
|
||||
g->is_native_target = true;
|
||||
get_native_target(&g->zig_target);
|
||||
g->dynamic_linker = nullptr; // find it at runtime
|
||||
g->libc_lib_dir = nullptr; // find it at runtime
|
||||
g->libc_static_lib_dir = nullptr; // find it at runtime
|
||||
g->libc_include_dir = nullptr; // find it at runtime
|
||||
g->msvc_lib_dir = nullptr; // find it at runtime
|
||||
g->kernel32_lib_dir = nullptr; // find it at runtime
|
||||
g->each_lib_rpath = true;
|
||||
|
||||
if (g->zig_target.os == OsMacOSX ||
|
||||
g->zig_target.os == OsIOS)
|
||||
{
|
||||
if (target_is_darwin(g->zig_target)) {
|
||||
init_darwin_native(g);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// On Darwin/MacOS/iOS, we always link libSystem which contains libc.
|
||||
if (g->zig_target.os == OsMacOSX ||
|
||||
g->zig_target.os == OsIOS ||
|
||||
g->zig_target.os == OsFreeBSD ||
|
||||
g->zig_target.os == OsNetBSD)
|
||||
{
|
||||
if (target_requires_libc(g->zig_target)) {
|
||||
g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
|
||||
g->link_libs_list.append(g->libc_link_lib);
|
||||
}
|
||||
@ -254,30 +231,6 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {
|
||||
g->root_out_name = out_name;
|
||||
}
|
||||
|
||||
void codegen_set_libc_lib_dir(CodeGen *g, Buf *libc_lib_dir) {
|
||||
g->libc_lib_dir = libc_lib_dir;
|
||||
}
|
||||
|
||||
void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir) {
|
||||
g->libc_static_lib_dir = libc_static_lib_dir;
|
||||
}
|
||||
|
||||
void codegen_set_libc_include_dir(CodeGen *g, Buf *libc_include_dir) {
|
||||
g->libc_include_dir = libc_include_dir;
|
||||
}
|
||||
|
||||
void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir) {
|
||||
g->msvc_lib_dir = msvc_lib_dir;
|
||||
}
|
||||
|
||||
void codegen_set_kernel32_lib_dir(CodeGen *g, Buf *kernel32_lib_dir) {
|
||||
g->kernel32_lib_dir = kernel32_lib_dir;
|
||||
}
|
||||
|
||||
void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) {
|
||||
g->dynamic_linker = dynamic_linker;
|
||||
}
|
||||
|
||||
void codegen_add_lib_dir(CodeGen *g, const char *dir) {
|
||||
g->lib_dirs.append(dir);
|
||||
}
|
||||
@ -390,11 +343,11 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
|
||||
case CallingConventionC: return LLVMCCallConv;
|
||||
case CallingConventionCold:
|
||||
// cold calling convention only works on x86.
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86 ||
|
||||
g->zig_target.arch.arch == ZigLLVM_x86_64)
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86 ||
|
||||
g->zig_target->arch.arch == ZigLLVM_x86_64)
|
||||
{
|
||||
// cold calling convention is not supported on windows
|
||||
if (g->zig_target.os == OsWindows) {
|
||||
if (g->zig_target->os == OsWindows) {
|
||||
return LLVMCCallConv;
|
||||
} else {
|
||||
return LLVMColdCallConv;
|
||||
@ -407,7 +360,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
|
||||
zig_unreachable();
|
||||
case CallingConventionStdcall:
|
||||
// stdcall calling convention only works on x86.
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86) {
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86) {
|
||||
return LLVMX86StdcallCallConv;
|
||||
} else {
|
||||
return LLVMCCallConv;
|
||||
@ -419,7 +372,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
|
||||
}
|
||||
|
||||
static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
|
||||
if (g->zig_target.os == OsWindows) {
|
||||
if (g->zig_target->os == OsWindows) {
|
||||
addLLVMFnAttr(fn_val, "uwtable");
|
||||
}
|
||||
}
|
||||
@ -455,13 +408,13 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
}
|
||||
|
||||
static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
|
||||
if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {
|
||||
if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
|
||||
LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
|
||||
}
|
||||
}
|
||||
|
||||
static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
|
||||
if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {
|
||||
if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
|
||||
// TODO come up with a good explanation/understanding for why we never do
|
||||
// DLLImportStorageClass. Empirically it only causes problems. But let's have
|
||||
// this documented and then clean up the code accordingly.
|
||||
@ -506,7 +459,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
bool external_linkage = linkage != GlobalLinkageIdInternal;
|
||||
CallingConvention cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;
|
||||
if (cc == CallingConventionStdcall && external_linkage &&
|
||||
g->zig_target.arch.arch == ZigLLVM_x86)
|
||||
g->zig_target->arch.arch == ZigLLVM_x86)
|
||||
{
|
||||
// prevent llvm name mangling
|
||||
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_
|
||||
return true;
|
||||
}
|
||||
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
|
||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty);
|
||||
size_t ty_size = type_size(g, ty);
|
||||
if (abi_class == X64CABIClass_MEMORY) {
|
||||
@ -3381,15 +3334,15 @@ static bool value_is_all_undef(ConstExprValue *const_val) {
|
||||
static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default_value, LLVMValueRef request,
|
||||
LLVMValueRef a1, LLVMValueRef a2, LLVMValueRef a3, LLVMValueRef a4, LLVMValueRef a5)
|
||||
{
|
||||
if (!target_has_valgrind_support(&g->zig_target)) {
|
||||
if (!target_has_valgrind_support(g->zig_target)) {
|
||||
return default_value;
|
||||
}
|
||||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref;
|
||||
bool asm_has_side_effects = true;
|
||||
bool asm_is_alignstack = false;
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
|
||||
if (g->zig_target.os == OsLinux || target_is_darwin(&g->zig_target) || g->zig_target.os == OsSolaris ||
|
||||
(g->zig_target.os == OsWindows && g->zig_target.env_type != ZigLLVM_MSVC))
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
|
||||
if (g->zig_target->os == OsLinux || target_is_darwin(g->zig_target) || g->zig_target->os == OsSolaris ||
|
||||
(g->zig_target->os == OsWindows && g->zig_target->env_type != ZigLLVM_MSVC))
|
||||
{
|
||||
if (g->cur_fn->valgrind_client_request_array == nullptr) {
|
||||
LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
|
||||
@ -3436,7 +3389,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
|
||||
}
|
||||
|
||||
static bool want_valgrind_support(CodeGen *g) {
|
||||
if (!target_has_valgrind_support(&g->zig_target))
|
||||
if (!target_has_valgrind_support(g->zig_target))
|
||||
return false;
|
||||
switch (g->valgrind_support) {
|
||||
case ValgrindSupportDisabled:
|
||||
@ -3629,7 +3582,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
|
||||
LLVMValueRef write_register_fn_val = get_write_register_fn_val(g);
|
||||
|
||||
if (g->sp_md_node == nullptr) {
|
||||
Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target.arch));
|
||||
Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(&g->zig_target->arch));
|
||||
LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1);
|
||||
g->sp_md_node = LLVMMDNode(&str_node, 1);
|
||||
}
|
||||
@ -7042,7 +6995,7 @@ static void define_builtin_types(CodeGen *g) {
|
||||
|
||||
for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
|
||||
const CIntTypeInfo *info = &c_int_type_infos[i];
|
||||
uint32_t size_in_bits = target_c_type_size_in_bits(&g->zig_target, info->id);
|
||||
uint32_t size_in_bits = target_c_type_size_in_bits(g->zig_target, info->id);
|
||||
bool is_signed = info->is_signed;
|
||||
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdInt);
|
||||
@ -7309,6 +7262,9 @@ static const char *build_mode_to_str(BuildMode build_mode) {
|
||||
Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
Buf *contents = buf_alloc();
|
||||
|
||||
// NOTE: when editing this file, you may need to make modifications to the
|
||||
// cache input parameters in define_builtin_compile_vars
|
||||
|
||||
// Modifications to this struct must be coordinated with code that does anything with
|
||||
// g->stack_trace_type. There are hard-coded references to the field indexes.
|
||||
buf_append_str(contents,
|
||||
@ -7328,7 +7284,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
const char *name = get_target_os_name(os_type);
|
||||
buf_appendf(contents, " %s,\n", name);
|
||||
|
||||
if (os_type == g->zig_target.os) {
|
||||
if (os_type == g->zig_target->os) {
|
||||
g->target_os_index = i;
|
||||
cur_os = name;
|
||||
}
|
||||
@ -7350,8 +7306,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
|
||||
buf_appendf(contents, " %s,\n", buf_ptr(arch_name));
|
||||
|
||||
if (arch_type->arch == g->zig_target.arch.arch &&
|
||||
arch_type->sub_arch == g->zig_target.arch.sub_arch)
|
||||
if (arch_type->arch == g->zig_target->arch.arch &&
|
||||
arch_type->sub_arch == g->zig_target->arch.sub_arch)
|
||||
{
|
||||
g->target_arch_index = i;
|
||||
cur_arch = buf_ptr(arch_name);
|
||||
@ -7370,7 +7326,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
const char *name = ZigLLVMGetEnvironmentTypeName(environ_type);
|
||||
buf_appendf(contents, " %s,\n", name);
|
||||
|
||||
if (environ_type == g->zig_target.env_type) {
|
||||
if (environ_type == g->zig_target->env_type) {
|
||||
g->target_environ_index = i;
|
||||
cur_environ = name;
|
||||
}
|
||||
@ -7388,7 +7344,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
const char *name = get_target_oformat_name(oformat);
|
||||
buf_appendf(contents, " %s,\n", name);
|
||||
|
||||
if (oformat == g->zig_target.oformat) {
|
||||
ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);
|
||||
if (oformat == target_oformat) {
|
||||
g->target_oformat_index = i;
|
||||
cur_obj_fmt = name;
|
||||
}
|
||||
@ -7707,14 +7664,15 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||
cache_int(&cache_hash, g->build_mode);
|
||||
cache_bool(&cache_hash, g->is_test_build);
|
||||
cache_bool(&cache_hash, g->is_single_threaded);
|
||||
cache_int(&cache_hash, g->zig_target.arch.arch);
|
||||
cache_int(&cache_hash, g->zig_target.arch.sub_arch);
|
||||
cache_int(&cache_hash, g->zig_target.vendor);
|
||||
cache_int(&cache_hash, g->zig_target.os);
|
||||
cache_int(&cache_hash, g->zig_target.env_type);
|
||||
cache_int(&cache_hash, g->zig_target.oformat);
|
||||
cache_int(&cache_hash, g->zig_target->is_native);
|
||||
cache_int(&cache_hash, g->zig_target->arch.arch);
|
||||
cache_int(&cache_hash, g->zig_target->arch.sub_arch);
|
||||
cache_int(&cache_hash, g->zig_target->vendor);
|
||||
cache_int(&cache_hash, g->zig_target->os);
|
||||
cache_int(&cache_hash, g->zig_target->env_type);
|
||||
cache_bool(&cache_hash, g->have_err_ret_tracing);
|
||||
cache_bool(&cache_hash, g->libc_link_lib != nullptr);
|
||||
cache_bool(&cache_hash, g->valgrind_support);
|
||||
|
||||
Buf digest = BUF_INIT;
|
||||
buf_resize(&digest, 0);
|
||||
@ -7783,11 +7741,11 @@ static void init(CodeGen *g) {
|
||||
assert(g->root_out_name);
|
||||
g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
|
||||
|
||||
get_target_triple(&g->triple_str, &g->zig_target);
|
||||
get_target_triple(&g->triple_str, g->zig_target);
|
||||
|
||||
LLVMSetTarget(g->module, buf_ptr(&g->triple_str));
|
||||
|
||||
if (g->zig_target.oformat == ZigLLVM_COFF) {
|
||||
if (target_object_format(g->zig_target) == ZigLLVM_COFF) {
|
||||
ZigLLVMAddModuleCodeViewFlag(g->module);
|
||||
} else {
|
||||
ZigLLVMAddModuleDebugInfoFlag(g->module);
|
||||
@ -7815,11 +7773,11 @@ static void init(CodeGen *g) {
|
||||
|
||||
const char *target_specific_cpu_args;
|
||||
const char *target_specific_features;
|
||||
if (g->is_native_target) {
|
||||
if (g->zig_target->is_native) {
|
||||
// LLVM creates invalid binaries on Windows sometimes.
|
||||
// See https://github.com/ziglang/zig/issues/508
|
||||
// As a workaround we do not use target native features on Windows.
|
||||
if (g->zig_target.os == OsWindows || g->zig_target.os == OsUefi) {
|
||||
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
|
||||
target_specific_cpu_args = "";
|
||||
target_specific_features = "";
|
||||
} else {
|
||||
@ -7892,9 +7850,59 @@ static void init(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_translate_c(CodeGen *g, Buf *full_path) {
|
||||
find_libc_include_path(g);
|
||||
static void detect_libc(CodeGen *g) {
|
||||
Error err;
|
||||
|
||||
if (g->libc != nullptr || g->libc_link_lib == nullptr)
|
||||
return;
|
||||
|
||||
if (g->zig_target->is_native) {
|
||||
g->libc = allocate<ZigLibCInstallation>(1);
|
||||
|
||||
// Look for zig-cache/native_libc.txt
|
||||
Buf *native_libc_txt = buf_alloc();
|
||||
os_path_join(&g->cache_dir, buf_create_from_str("native_libc.txt"), native_libc_txt);
|
||||
if ((err = zig_libc_parse(g->libc, native_libc_txt, g->zig_target, false))) {
|
||||
if ((err = zig_libc_find_native(g->libc, true))) {
|
||||
fprintf(stderr,
|
||||
"Unable to link against libc: Unable to find libc installation: %s\n"
|
||||
"See `zig libc --help` for more details.\n", err_str(err));
|
||||
exit(1);
|
||||
}
|
||||
if ((err = os_make_path(&g->cache_dir))) {
|
||||
fprintf(stderr, "Unable to create %s directory: %s\n",
|
||||
buf_ptr(&g->cache_dir), err_str(err));
|
||||
exit(1);
|
||||
}
|
||||
Buf *native_libc_tmp = buf_sprintf("%s.tmp", buf_ptr(native_libc_txt));
|
||||
FILE *file = fopen(buf_ptr(native_libc_tmp), "wb");
|
||||
if (file == nullptr) {
|
||||
fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
zig_libc_render(g->libc, file);
|
||||
if (fclose(file) != 0) {
|
||||
fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (rename(buf_ptr(native_libc_tmp), buf_ptr(native_libc_txt)) == -1) {
|
||||
fprintf(stderr, "Unable to create %s: %s\n", buf_ptr(native_libc_txt), strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) &&
|
||||
!target_is_darwin(g->zig_target))
|
||||
{
|
||||
// Currently darwin is the only platform that we can link libc on when not compiling natively,
|
||||
// without a cross compiling libc kit.
|
||||
fprintf(stderr,
|
||||
"Cannot link against libc for non-native OS '%s' without providing a libc installation file.\n"
|
||||
"See `zig libc --help` for more details.\n", get_target_os_name(g->zig_target->os));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_translate_c(CodeGen *g, Buf *full_path) {
|
||||
Buf *src_basename = buf_alloc();
|
||||
Buf *src_dirname = buf_alloc();
|
||||
os_path_split(full_path, src_dirname, src_basename);
|
||||
@ -7905,6 +7913,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
|
||||
g->root_import = import;
|
||||
import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
|
||||
|
||||
detect_libc(g);
|
||||
|
||||
init(g);
|
||||
|
||||
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) {
|
||||
}
|
||||
report_errors_and_maybe_exit(g);
|
||||
|
||||
if (!g->is_test_build && g->zig_target.os != OsFreestanding &&
|
||||
g->zig_target.os != OsUefi &&
|
||||
if (!g->is_test_build && g->zig_target->os != OsFreestanding &&
|
||||
g->zig_target->os != OsUefi &&
|
||||
!g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
|
||||
((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
|
||||
{
|
||||
g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
|
||||
}
|
||||
if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup &&
|
||||
if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup &&
|
||||
g->out_type == OutTypeLib && !g->is_static)
|
||||
{
|
||||
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) {
|
||||
}
|
||||
cache_buf(ch, compiler_id);
|
||||
cache_buf(ch, g->root_out_name);
|
||||
cache_buf(ch, g->zig_lib_dir);
|
||||
cache_buf(ch, g->zig_std_dir);
|
||||
cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);
|
||||
cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);
|
||||
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) {
|
||||
cache_int(ch, g->emit_file_type);
|
||||
cache_int(ch, g->build_mode);
|
||||
cache_int(ch, g->out_type);
|
||||
cache_int(ch, g->zig_target.arch.arch);
|
||||
cache_int(ch, g->zig_target.arch.sub_arch);
|
||||
cache_int(ch, g->zig_target.vendor);
|
||||
cache_int(ch, g->zig_target.os);
|
||||
cache_int(ch, g->zig_target.env_type);
|
||||
cache_int(ch, g->zig_target.oformat);
|
||||
cache_bool(ch, g->zig_target->is_native);
|
||||
cache_int(ch, g->zig_target->arch.arch);
|
||||
cache_int(ch, g->zig_target->arch.sub_arch);
|
||||
cache_int(ch, g->zig_target->vendor);
|
||||
cache_int(ch, g->zig_target->os);
|
||||
cache_int(ch, g->zig_target->env_type);
|
||||
cache_int(ch, g->subsystem);
|
||||
cache_bool(ch, g->is_static);
|
||||
cache_bool(ch, g->strip_debug_symbols);
|
||||
cache_bool(ch, g->is_test_build);
|
||||
cache_bool(ch, g->is_single_threaded);
|
||||
cache_bool(ch, g->is_native_target);
|
||||
cache_bool(ch, g->linker_rdynamic);
|
||||
cache_bool(ch, g->each_lib_rpath);
|
||||
cache_bool(ch, g->disable_pic);
|
||||
@ -8654,6 +8665,14 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
|
||||
cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len);
|
||||
cache_list_of_str(ch, g->clang_argv, g->clang_argv_len);
|
||||
cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
|
||||
if (g->libc) {
|
||||
cache_buf(ch, &g->libc->include_dir);
|
||||
cache_buf(ch, &g->libc->lib_dir);
|
||||
cache_buf(ch, &g->libc->static_lib_dir);
|
||||
cache_buf(ch, &g->libc->msvc_lib_dir);
|
||||
cache_buf(ch, &g->libc->kernel32_lib_dir);
|
||||
cache_buf(ch, &g->libc->dynamic_linker_path);
|
||||
}
|
||||
|
||||
buf_resize(digest, 0);
|
||||
if ((err = cache_hit(ch, digest)))
|
||||
@ -8668,19 +8687,19 @@ static void resolve_out_paths(CodeGen *g) {
|
||||
switch (g->emit_file_type) {
|
||||
case EmitFileTypeBinary:
|
||||
{
|
||||
const char *o_ext = target_o_file_ext(&g->zig_target);
|
||||
const char *o_ext = target_o_file_ext(g->zig_target);
|
||||
buf_append_str(o_basename, o_ext);
|
||||
break;
|
||||
}
|
||||
case EmitFileTypeAssembly:
|
||||
{
|
||||
const char *asm_ext = target_asm_file_ext(&g->zig_target);
|
||||
const char *asm_ext = target_asm_file_ext(g->zig_target);
|
||||
buf_append_str(o_basename, asm_ext);
|
||||
break;
|
||||
}
|
||||
case EmitFileTypeLLVMIr:
|
||||
{
|
||||
const char *llvm_ir_ext = target_llvm_ir_file_ext(&g->zig_target);
|
||||
const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
|
||||
buf_append_str(o_basename, llvm_ir_ext);
|
||||
break;
|
||||
}
|
||||
@ -8706,7 +8725,7 @@ static void resolve_out_paths(CodeGen *g) {
|
||||
|
||||
Buf basename = BUF_INIT;
|
||||
buf_init_from_buf(&basename, g->root_out_name);
|
||||
buf_append_str(&basename, target_exe_file_ext(&g->zig_target));
|
||||
buf_append_str(&basename, target_exe_file_ext(g->zig_target));
|
||||
if (g->enable_cache || g->is_test_build) {
|
||||
os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
|
||||
} else {
|
||||
@ -8719,7 +8738,7 @@ static void resolve_out_paths(CodeGen *g) {
|
||||
} else {
|
||||
Buf basename = BUF_INIT;
|
||||
buf_init_from_buf(&basename, g->root_out_name);
|
||||
buf_append_str(&basename, target_lib_file_ext(&g->zig_target, g->is_static,
|
||||
buf_append_str(&basename, target_lib_file_ext(g->zig_target, g->is_static,
|
||||
g->version_major, g->version_minor, g->version_patch));
|
||||
if (g->enable_cache) {
|
||||
os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
|
||||
@ -8732,11 +8751,12 @@ static void resolve_out_paths(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void codegen_build_and_link(CodeGen *g) {
|
||||
Error err;
|
||||
assert(g->out_type != OutTypeUnknown);
|
||||
|
||||
detect_libc(g);
|
||||
|
||||
Buf *stage1_dir = get_stage1_cache_path();
|
||||
Buf *artifact_dir = buf_alloc();
|
||||
Buf digest = BUF_INIT;
|
||||
|
@ -11,11 +11,12 @@
|
||||
#include "parser.hpp"
|
||||
#include "errmsg.hpp"
|
||||
#include "target.hpp"
|
||||
#include "libc_installation.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
|
||||
Buf *zig_lib_dir, Buf *override_std_dir);
|
||||
Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc);
|
||||
|
||||
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
|
||||
void 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);
|
||||
void codegen_set_strip(CodeGen *codegen, bool strip);
|
||||
void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
|
||||
void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
|
||||
void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
|
||||
void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
|
||||
void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
|
||||
void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir);
|
||||
void codegen_set_kernel32_lib_dir(CodeGen *codegen, Buf *kernel32_lib_dir);
|
||||
void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);
|
||||
void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
|
||||
void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib);
|
||||
LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib);
|
||||
|
@ -34,6 +34,8 @@ const char *err_str(Error err) {
|
||||
case ErrorPipeBusy: return "pipe busy";
|
||||
case ErrorPrimitiveTypeNotFound: return "primitive type not found";
|
||||
case ErrorCacheUnavailable: return "cache unavailable";
|
||||
case ErrorPathTooLong: return "path too long";
|
||||
case ErrorCCompilerCannotFindFile: return "C compiler cannot find file";
|
||||
}
|
||||
return "(invalid error)";
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ enum Error {
|
||||
ErrorPipeBusy,
|
||||
ErrorPrimitiveTypeNotFound,
|
||||
ErrorCacheUnavailable,
|
||||
ErrorPathTooLong,
|
||||
ErrorCCompilerCannotFindFile,
|
||||
};
|
||||
|
||||
const char *err_str(Error err);
|
||||
|
@ -18690,8 +18690,6 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
||||
if (type_is_invalid(cimport_result->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
find_libc_include_path(ira->codegen);
|
||||
|
||||
ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
|
||||
child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
|
||||
child_import->c_import_node = node;
|
||||
|
408
src/libc_installation.cpp
Normal file
408
src/libc_installation.cpp
Normal file
@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "libc_installation.hpp"
|
||||
#include "os.hpp"
|
||||
#include "windows_sdk.h"
|
||||
#include "target.hpp"
|
||||
|
||||
static const size_t zig_libc_keys_len = 6;
|
||||
|
||||
static const char *zig_libc_keys[] = {
|
||||
"include_dir",
|
||||
"lib_dir",
|
||||
"static_lib_dir",
|
||||
"msvc_lib_dir",
|
||||
"kernel32_lib_dir",
|
||||
"dynamic_linker_path",
|
||||
};
|
||||
|
||||
static bool zig_libc_match_key(Slice<uint8_t> name, Slice<uint8_t> value, bool *found_keys,
|
||||
size_t index, Buf *field_ptr)
|
||||
{
|
||||
if (!memEql(name, str(zig_libc_keys[index]))) return false;
|
||||
buf_init_from_mem(field_ptr, (const char*)value.ptr, value.len);
|
||||
found_keys[index] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void zig_libc_init_empty(ZigLibCInstallation *libc) {
|
||||
*libc = {};
|
||||
buf_init_from_str(&libc->include_dir, "");
|
||||
buf_init_from_str(&libc->lib_dir, "");
|
||||
buf_init_from_str(&libc->static_lib_dir, "");
|
||||
buf_init_from_str(&libc->msvc_lib_dir, "");
|
||||
buf_init_from_str(&libc->kernel32_lib_dir, "");
|
||||
buf_init_from_str(&libc->dynamic_linker_path, "");
|
||||
}
|
||||
|
||||
Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget *target, bool verbose) {
|
||||
Error err;
|
||||
zig_libc_init_empty(libc);
|
||||
|
||||
bool found_keys[6] = {}; // zig_libc_keys_len
|
||||
|
||||
Buf *contents = buf_alloc();
|
||||
if ((err = os_fetch_file_path(libc_file, contents, false))) {
|
||||
if (err != ErrorFileNotFound && verbose) {
|
||||
fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
SplitIterator it = memSplit(buf_to_slice(contents), str("\n"));
|
||||
for (;;) {
|
||||
Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);
|
||||
if (!opt_line.is_some)
|
||||
break;
|
||||
|
||||
if (opt_line.value.len == 0 || opt_line.value.ptr[0] == '#')
|
||||
continue;
|
||||
|
||||
SplitIterator line_it = memSplit(opt_line.value, str("="));
|
||||
Slice<uint8_t> name;
|
||||
if (!SplitIterator_next(&line_it).unwrap(&name)) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "missing equal sign after field name\n");
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
Slice<uint8_t> value = SplitIterator_rest(&line_it);
|
||||
bool match = false;
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->lib_dir);
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->static_lib_dir);
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir);
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->kernel32_lib_dir);
|
||||
match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->dynamic_linker_path);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
|
||||
if (!found_keys[i]) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "missing field: %s\n", zig_libc_keys[i]);
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_len(&libc->include_dir) == 0) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "include_dir may not be empty\n");
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
|
||||
if (buf_len(&libc->lib_dir) == 0) {
|
||||
if (!target_is_darwin(target)) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "lib_dir may not be empty for %s\n", get_target_os_name(target->os));
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_len(&libc->static_lib_dir) == 0) {
|
||||
if (!target_is_darwin(target) && target->os != OsWindows) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "static_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_len(&libc->msvc_lib_dir) == 0) {
|
||||
if (target->os == OsWindows) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_len(&libc->kernel32_lib_dir) == 0) {
|
||||
if (target->os == OsWindows) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", get_target_os_name(target->os));
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_len(&libc->dynamic_linker_path) == 0) {
|
||||
if (target->os == OsLinux) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "dynamic_linker_path may not be empty for %s\n", get_target_os_name(target->os));
|
||||
}
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
|
||||
Error err;
|
||||
if ((err = os_get_win32_ucrt_include_path(sdk, &self->include_dir))) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Unable to determine libc include path: %s\n", err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return ErrorNone;
|
||||
}
|
||||
static Error zig_libc_find_lib_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
|
||||
bool verbose)
|
||||
{
|
||||
Error err;
|
||||
if ((err = os_get_win32_ucrt_lib_path(sdk, &self->lib_dir, target->arch.arch))) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Unable to determine ucrt path: %s\n", err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return ErrorNone;
|
||||
}
|
||||
static Error zig_libc_find_kernel32_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
|
||||
bool verbose)
|
||||
{
|
||||
Error err;
|
||||
if ((err = os_get_win32_kern32_path(sdk, &self->kernel32_lib_dir, target->arch.arch))) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Unable to determine kernel32 path: %s\n", err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return ErrorNone;
|
||||
}
|
||||
static Error zig_libc_find_native_msvc_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
|
||||
if (sdk->msvc_lib_dir_ptr == nullptr) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Unable to determine vcruntime path\n");
|
||||
}
|
||||
return ErrorFileNotFound;
|
||||
}
|
||||
buf_init_from_mem(&self->msvc_lib_dir, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
|
||||
return ErrorNone;
|
||||
}
|
||||
#else
|
||||
static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, bool verbose) {
|
||||
const char *cc_exe = getenv("CC");
|
||||
cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
|
||||
ZigList<const char *> args = {};
|
||||
args.append("-E");
|
||||
args.append("-Wp,-v");
|
||||
args.append("-xc");
|
||||
args.append("/dev/null");
|
||||
Termination term;
|
||||
Buf *out_stderr = buf_alloc();
|
||||
Buf *out_stdout = buf_alloc();
|
||||
Error err;
|
||||
if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
|
||||
}
|
||||
return ErrorCCompileErrors;
|
||||
}
|
||||
char *prev_newline = buf_ptr(out_stderr);
|
||||
ZigList<const char *> search_paths = {};
|
||||
for (;;) {
|
||||
char *newline = strchr(prev_newline, '\n');
|
||||
if (newline == nullptr) {
|
||||
break;
|
||||
}
|
||||
*newline = 0;
|
||||
if (prev_newline[0] == ' ') {
|
||||
search_paths.append(prev_newline);
|
||||
}
|
||||
prev_newline = newline + 1;
|
||||
}
|
||||
if (search_paths.length == 0) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: '%s' cannot find libc headers\n", cc_exe);
|
||||
}
|
||||
return ErrorCCompileErrors;
|
||||
}
|
||||
for (size_t i = 0; i < search_paths.length; i += 1) {
|
||||
// search in reverse order
|
||||
const char *search_path = search_paths.items[search_paths.length - i - 1];
|
||||
// cut off spaces
|
||||
while (*search_path == ' ') {
|
||||
search_path += 1;
|
||||
}
|
||||
Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
|
||||
bool exists;
|
||||
if ((err = os_file_exists(stdlib_path, &exists))) {
|
||||
exists = false;
|
||||
}
|
||||
if (exists) {
|
||||
buf_init_from_str(&self->include_dir, search_path);
|
||||
return ErrorNone;
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe);
|
||||
}
|
||||
return ErrorFileNotFound;
|
||||
}
|
||||
#if !defined(ZIG_OS_DARWIN)
|
||||
static Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
|
||||
const char *cc_exe = getenv("CC");
|
||||
cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
|
||||
ZigList<const char *> args = {};
|
||||
args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
|
||||
Termination term;
|
||||
Buf *out_stderr = buf_alloc();
|
||||
Buf *out_stdout = buf_alloc();
|
||||
Error err;
|
||||
if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
|
||||
}
|
||||
return ErrorCCompileErrors;
|
||||
}
|
||||
if (buf_ends_with_str(out_stdout, "\n")) {
|
||||
buf_resize(out_stdout, buf_len(out_stdout) - 1);
|
||||
}
|
||||
if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
|
||||
return ErrorCCompilerCannotFindFile;
|
||||
}
|
||||
if (want_dirname) {
|
||||
os_path_dirname(out_stdout, out);
|
||||
} else {
|
||||
buf_init_from_buf(out, out_stdout);
|
||||
}
|
||||
return ErrorNone;
|
||||
}
|
||||
static Error zig_libc_find_native_lib_dir_posix(ZigLibCInstallation *self, bool verbose) {
|
||||
return zig_libc_cc_print_file_name("crt1.o", &self->lib_dir, true, verbose);
|
||||
}
|
||||
|
||||
static Error zig_libc_find_native_static_lib_dir_posix(ZigLibCInstallation *self, bool verbose) {
|
||||
return zig_libc_cc_print_file_name("crtbegin.o", &self->static_lib_dir, true, verbose);
|
||||
}
|
||||
#endif
|
||||
|
||||
static Error zig_libc_find_native_dynamic_linker_posix(ZigLibCInstallation *self, bool verbose) {
|
||||
#if defined(ZIG_OS_LINUX)
|
||||
Error err;
|
||||
static const char *dyn_tests[] = {
|
||||
"ld-linux-x86-64.so.2",
|
||||
"ld-musl-x86_64.so.1",
|
||||
};
|
||||
for (size_t i = 0; i < array_length(dyn_tests); i += 1) {
|
||||
const char *lib_name = dyn_tests[i];
|
||||
if ((err = zig_libc_cc_print_file_name(lib_name, &self->dynamic_linker_path, false, true))) {
|
||||
if (err != ErrorCCompilerCannotFindFile)
|
||||
return err;
|
||||
continue;
|
||||
}
|
||||
return ErrorNone;
|
||||
}
|
||||
#endif
|
||||
ZigTarget native_target;
|
||||
get_native_target(&native_target);
|
||||
Buf *dynamic_linker_path = target_dynamic_linker(&native_target);
|
||||
buf_init_from_buf(&self->dynamic_linker_path, dynamic_linker_path);
|
||||
return ErrorNone;
|
||||
}
|
||||
#endif
|
||||
|
||||
void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
|
||||
fprintf(file,
|
||||
"# The directory that contains `stdlib.h`.\n"
|
||||
"# On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`\n"
|
||||
"include_dir=%s\n"
|
||||
"\n"
|
||||
"# The directory that contains `crt1.o`.\n"
|
||||
"# On Linux, can be found with `cc -print-file-name=crt1.o`.\n"
|
||||
"# Not needed when targeting MacOS.\n"
|
||||
"lib_dir=%s\n"
|
||||
"\n"
|
||||
"# The directory that contains `crtbegin.o`.\n"
|
||||
"# On Linux, can be found with `cc -print-file-name=crtbegin.o`.\n"
|
||||
"# Not needed when targeting MacOS or Windows.\n"
|
||||
"static_lib_dir=%s\n"
|
||||
"\n"
|
||||
"# The directory that contains `vcruntime.lib`.\n"
|
||||
"# Only needed when targeting Windows.\n"
|
||||
"msvc_lib_dir=%s\n"
|
||||
"\n"
|
||||
"# The directory that contains `kernel32.lib`.\n"
|
||||
"# Only needed when targeting Windows.\n"
|
||||
"kernel32_lib_dir=%s\n"
|
||||
"\n"
|
||||
"# The full path to the dynamic linker, on the target system.\n"
|
||||
"# Only needed when targeting Linux.\n"
|
||||
"dynamic_linker_path=%s\n"
|
||||
"\n"
|
||||
,
|
||||
buf_ptr(&self->include_dir),
|
||||
buf_ptr(&self->lib_dir),
|
||||
buf_ptr(&self->static_lib_dir),
|
||||
buf_ptr(&self->msvc_lib_dir),
|
||||
buf_ptr(&self->kernel32_lib_dir),
|
||||
buf_ptr(&self->dynamic_linker_path)
|
||||
);
|
||||
}
|
||||
|
||||
Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
|
||||
Error err;
|
||||
zig_libc_init_empty(self);
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
ZigTarget native_target;
|
||||
get_native_target(&native_target);
|
||||
ZigWindowsSDK *sdk;
|
||||
switch (zig_find_windows_sdk(&sdk)) {
|
||||
case ZigFindWindowsSdkErrorNone:
|
||||
if ((err = zig_libc_find_native_msvc_lib_dir(self, sdk, verbose)))
|
||||
return err;
|
||||
if ((err = zig_libc_find_kernel32_lib_dir(self, sdk, &native_target, verbose)))
|
||||
return err;
|
||||
if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
|
||||
return err;
|
||||
if ((err = zig_libc_find_lib_dir_windows(self, sdk, &native_target, verbose)))
|
||||
return err;
|
||||
return ErrorNone;
|
||||
case ZigFindWindowsSdkErrorOutOfMemory:
|
||||
return ErrorNoMem;
|
||||
case ZigFindWindowsSdkErrorNotFound:
|
||||
return ErrorFileNotFound;
|
||||
case ZigFindWindowsSdkErrorPathTooLong:
|
||||
return ErrorPathTooLong;
|
||||
}
|
||||
zig_unreachable();
|
||||
#else
|
||||
if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
|
||||
return err;
|
||||
#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD)
|
||||
buf_init_from_str(&self->lib_dir, "/usr/lib");
|
||||
buf_init_from_str(&self->static_lib_dir, "/usr/lib");
|
||||
#elif !defined(ZIG_OS_DARWIN)
|
||||
if ((err = zig_libc_find_native_lib_dir_posix(self, verbose)))
|
||||
return err;
|
||||
if ((err = zig_libc_find_native_static_lib_dir_posix(self, verbose)))
|
||||
return err;
|
||||
#endif
|
||||
if ((err = zig_libc_find_native_dynamic_linker_posix(self, verbose)))
|
||||
return err;
|
||||
return ErrorNone;
|
||||
#endif
|
||||
}
|
33
src/libc_installation.hpp
Normal file
33
src/libc_installation.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_LIBC_INSTALLATION_HPP
|
||||
#define ZIG_LIBC_INSTALLATION_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "error.hpp"
|
||||
#include "target.hpp"
|
||||
|
||||
// Must be synchronized with zig_libc_keys
|
||||
struct ZigLibCInstallation {
|
||||
Buf include_dir;
|
||||
Buf lib_dir;
|
||||
Buf static_lib_dir;
|
||||
Buf msvc_lib_dir;
|
||||
Buf kernel32_lib_dir;
|
||||
Buf dynamic_linker_path;
|
||||
};
|
||||
|
||||
Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file,
|
||||
const ZigTarget *target, bool verbose);
|
||||
void zig_libc_render(ZigLibCInstallation *self, FILE *file);
|
||||
|
||||
Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
|
||||
|
||||
#endif
|
149
src/link.cpp
149
src/link.cpp
@ -18,31 +18,32 @@ struct LinkJob {
|
||||
};
|
||||
|
||||
static const char *get_libc_file(CodeGen *g, const char *file) {
|
||||
assert(g->libc != nullptr);
|
||||
Buf *out_buf = buf_alloc();
|
||||
os_path_join(g->libc_lib_dir, buf_create_from_str(file), out_buf);
|
||||
os_path_join(&g->libc->lib_dir, buf_create_from_str(file), out_buf);
|
||||
return buf_ptr(out_buf);
|
||||
}
|
||||
|
||||
static const char *get_libc_static_file(CodeGen *g, const char *file) {
|
||||
assert(g->libc != nullptr);
|
||||
Buf *out_buf = buf_alloc();
|
||||
os_path_join(g->libc_static_lib_dir, buf_create_from_str(file), out_buf);
|
||||
os_path_join(&g->libc->static_lib_dir, buf_create_from_str(file), out_buf);
|
||||
return buf_ptr(out_buf);
|
||||
}
|
||||
|
||||
static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {
|
||||
ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
|
||||
|
||||
// The Mach-O LLD code is not well maintained, and trips an assertion
|
||||
// when we link compiler_rt and builtin as libraries rather than objects.
|
||||
// Here we workaround this by having compiler_rt and builtin be objects.
|
||||
// TODO write our own linker. https://github.com/ziglang/zig/issues/1535
|
||||
OutType child_out_type = OutTypeLib;
|
||||
if (parent_gen->zig_target.os == OsMacOSX) {
|
||||
if (parent_gen->zig_target->os == OsMacOSX) {
|
||||
child_out_type = OutTypeObj;
|
||||
}
|
||||
|
||||
CodeGen *child_gen = codegen_create(full_path, child_target, child_out_type,
|
||||
parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir);
|
||||
CodeGen *child_gen = codegen_create(full_path, parent_gen->zig_target, child_out_type,
|
||||
parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir,
|
||||
parent_gen->libc);
|
||||
|
||||
child_gen->out_h_path = nullptr;
|
||||
child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
|
||||
@ -171,62 +172,11 @@ static void add_rpath(LinkJob *lj, Buf *rpath) {
|
||||
lj->rpath_table.put(rpath, true);
|
||||
}
|
||||
|
||||
static Buf *try_dynamic_linker_path(const char *ld_name) {
|
||||
const char *cc_exe = getenv("CC");
|
||||
cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
|
||||
ZigList<const char *> args = {};
|
||||
args.append(buf_ptr(buf_sprintf("-print-file-name=%s", ld_name)));
|
||||
Termination term;
|
||||
Buf *out_stderr = buf_alloc();
|
||||
Buf *out_stdout = buf_alloc();
|
||||
int err;
|
||||
if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
|
||||
return nullptr;
|
||||
}
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (buf_ends_with_str(out_stdout, "\n")) {
|
||||
buf_resize(out_stdout, buf_len(out_stdout) - 1);
|
||||
}
|
||||
if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, ld_name)) {
|
||||
return nullptr;
|
||||
}
|
||||
return out_stdout;
|
||||
}
|
||||
|
||||
static Buf *get_dynamic_linker_path(CodeGen *g) {
|
||||
if (g->zig_target.os == OsFreeBSD) {
|
||||
return buf_create_from_str("/libexec/ld-elf.so.1");
|
||||
}
|
||||
if (g->zig_target.os == OsNetBSD) {
|
||||
return buf_create_from_str("/libexec/ld.elf_so");
|
||||
}
|
||||
if (g->is_native_target && g->zig_target.arch.arch == ZigLLVM_x86_64) {
|
||||
static const char *ld_names[] = {
|
||||
"ld-linux-x86-64.so.2",
|
||||
"ld-musl-x86_64.so.1",
|
||||
};
|
||||
for (size_t i = 0; i < array_length(ld_names); i += 1) {
|
||||
const char *ld_name = ld_names[i];
|
||||
Buf *result = try_dynamic_linker_path(ld_name);
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target_dynamic_linker(&g->zig_target);
|
||||
}
|
||||
|
||||
static void construct_linker_job_elf(LinkJob *lj) {
|
||||
CodeGen *g = lj->codegen;
|
||||
|
||||
lj->args.append("-error-limit=0");
|
||||
|
||||
if (g->libc_link_lib != nullptr) {
|
||||
find_libc_lib_path(g);
|
||||
}
|
||||
|
||||
if (g->linker_script) {
|
||||
lj->args.append("-T");
|
||||
lj->args.append(g->linker_script);
|
||||
@ -235,14 +185,14 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
lj->args.append("--gc-sections");
|
||||
|
||||
lj->args.append("-m");
|
||||
lj->args.append(getLDMOption(&g->zig_target));
|
||||
lj->args.append(getLDMOption(g->zig_target));
|
||||
|
||||
bool is_lib = g->out_type == OutTypeLib;
|
||||
bool shared = !g->is_static && is_lib;
|
||||
Buf *soname = nullptr;
|
||||
if (g->is_static) {
|
||||
if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb ||
|
||||
g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb)
|
||||
if (g->zig_target->arch.arch == ZigLLVM_arm || g->zig_target->arch.arch == ZigLLVM_armeb ||
|
||||
g->zig_target->arch.arch == ZigLLVM_thumb || g->zig_target->arch.arch == ZigLLVM_thumbeb)
|
||||
{
|
||||
lj->args.append("-Bstatic");
|
||||
} else {
|
||||
@ -264,13 +214,13 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
if (lj->link_in_crt) {
|
||||
const char *crt1o;
|
||||
const char *crtbegino;
|
||||
if (g->zig_target.os == OsNetBSD) {
|
||||
crt1o = "crt0.o";
|
||||
crtbegino = "crtbegin.o";
|
||||
} else if (g->is_static) {
|
||||
if (g->zig_target->os == OsNetBSD) {
|
||||
crt1o = "crt0.o";
|
||||
crtbegino = "crtbegin.o";
|
||||
} else if (g->is_static) {
|
||||
crt1o = "crt1.o";
|
||||
crtbegino = "crtbeginT.o";
|
||||
} else {
|
||||
} else {
|
||||
crt1o = "Scrt1.o";
|
||||
crtbegino = "crtbegin.o";
|
||||
}
|
||||
@ -311,23 +261,19 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
}
|
||||
|
||||
if (g->libc_link_lib != nullptr) {
|
||||
assert(g->libc != nullptr);
|
||||
lj->args.append("-L");
|
||||
lj->args.append(buf_ptr(g->libc_lib_dir));
|
||||
lj->args.append(buf_ptr(&g->libc->lib_dir));
|
||||
|
||||
lj->args.append("-L");
|
||||
lj->args.append(buf_ptr(g->libc_static_lib_dir));
|
||||
}
|
||||
lj->args.append(buf_ptr(&g->libc->static_lib_dir));
|
||||
|
||||
if (!g->is_static) {
|
||||
if (g->dynamic_linker != nullptr) {
|
||||
assert(buf_len(g->dynamic_linker) != 0);
|
||||
if (!g->is_static) {
|
||||
assert(buf_len(&g->libc->dynamic_linker_path) != 0);
|
||||
lj->args.append("-dynamic-linker");
|
||||
lj->args.append(buf_ptr(g->dynamic_linker));
|
||||
} else {
|
||||
Buf *resolved_dynamic_linker = get_dynamic_linker_path(g);
|
||||
lj->args.append("-dynamic-linker");
|
||||
lj->args.append(buf_ptr(resolved_dynamic_linker));
|
||||
lj->args.append(buf_ptr(&g->libc->dynamic_linker_path));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (shared) {
|
||||
@ -397,11 +343,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
lj->args.append(get_libc_file(g, "crtn.o"));
|
||||
}
|
||||
|
||||
if (!g->is_native_target) {
|
||||
if (!g->zig_target->is_native) {
|
||||
lj->args.append("--allow-shlib-undefined");
|
||||
}
|
||||
|
||||
if (g->zig_target.os == OsZen) {
|
||||
if (g->zig_target->os == OsZen) {
|
||||
lj->args.append("-e");
|
||||
lj->args.append("_start");
|
||||
|
||||
@ -429,11 +375,11 @@ static void construct_linker_job_wasm(LinkJob *lj) {
|
||||
//}
|
||||
|
||||
static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
|
||||
if (g->zig_target.arch.arch == ZigLLVM_x86) {
|
||||
if (g->zig_target->arch.arch == ZigLLVM_x86) {
|
||||
list->append("-MACHINE:X86");
|
||||
} else if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
|
||||
} else if (g->zig_target->arch.arch == ZigLLVM_x86_64) {
|
||||
list->append("-MACHINE:X64");
|
||||
} else if (g->zig_target.arch.arch == ZigLLVM_arm) {
|
||||
} else if (g->zig_target->arch.arch == ZigLLVM_arm) {
|
||||
list->append("-MACHINE:ARM");
|
||||
}
|
||||
}
|
||||
@ -592,10 +538,6 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
|
||||
lj->args.append("/ERRORLIMIT:0");
|
||||
|
||||
if (g->libc_link_lib != nullptr) {
|
||||
find_libc_lib_path(g);
|
||||
}
|
||||
|
||||
lj->args.append("/NOLOGO");
|
||||
|
||||
if (!g->strip_debug_symbols) {
|
||||
@ -650,13 +592,11 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
|
||||
|
||||
if (g->libc_link_lib != nullptr) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir))));
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir))));
|
||||
assert(g->libc != nullptr);
|
||||
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir))));
|
||||
if (g->libc_static_lib_dir != nullptr) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir))));
|
||||
}
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->lib_dir))));
|
||||
}
|
||||
|
||||
if (is_library && !g->is_static) {
|
||||
@ -691,7 +631,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
continue;
|
||||
}
|
||||
if (link_lib->provided_explicitly) {
|
||||
if (lj->codegen->zig_target.env_type == ZigLLVM_GNU) {
|
||||
if (lj->codegen->zig_target->env_type == ZigLLVM_GNU) {
|
||||
Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
|
||||
lj->args.append(buf_ptr(arg));
|
||||
}
|
||||
@ -721,7 +661,8 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
|
||||
gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
|
||||
Buf diag = BUF_INIT;
|
||||
if (!zig_lld_link(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
|
||||
ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target);
|
||||
if (!zig_lld_link(target_ofmt, gen_lib_args.items, gen_lib_args.length, &diag)) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&diag));
|
||||
exit(1);
|
||||
}
|
||||
@ -790,7 +731,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
|
||||
platform->kind = MacOS;
|
||||
} else if (g->mios_version_min) {
|
||||
platform->kind = IPhoneOS;
|
||||
} else if (g->zig_target.os == OsMacOSX) {
|
||||
} else if (g->zig_target->os == OsMacOSX) {
|
||||
platform->kind = MacOS;
|
||||
g->mmacosx_version_min = buf_create_from_str("10.10");
|
||||
} else {
|
||||
@ -817,8 +758,8 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
|
||||
}
|
||||
|
||||
if (platform->kind == IPhoneOS &&
|
||||
(g->zig_target.arch.arch == ZigLLVM_x86 ||
|
||||
g->zig_target.arch.arch == ZigLLVM_x86_64))
|
||||
(g->zig_target->arch.arch == ZigLLVM_x86 ||
|
||||
g->zig_target->arch.arch == ZigLLVM_x86_64))
|
||||
{
|
||||
platform->kind = IPhoneOSSimulator;
|
||||
}
|
||||
@ -882,7 +823,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
|
||||
}
|
||||
|
||||
lj->args.append("-arch");
|
||||
lj->args.append(get_darwin_arch_string(&g->zig_target));
|
||||
lj->args.append(get_darwin_arch_string(g->zig_target));
|
||||
|
||||
DarwinPlatform platform;
|
||||
get_darwin_platform(lj, &platform);
|
||||
@ -939,7 +880,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
|
||||
}
|
||||
break;
|
||||
case IPhoneOS:
|
||||
if (g->zig_target.arch.arch == ZigLLVM_aarch64) {
|
||||
if (g->zig_target->arch.arch == ZigLLVM_aarch64) {
|
||||
// iOS does not need any crt1 files for arm64
|
||||
} else if (darwin_version_lt(&platform, 3, 1)) {
|
||||
lj->args.append("-lcrt1.o");
|
||||
@ -969,7 +910,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
|
||||
lj->args.append(buf_ptr(compiler_rt_o_path));
|
||||
}
|
||||
|
||||
if (g->is_native_target) {
|
||||
if (g->zig_target->is_native) {
|
||||
for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
|
||||
LinkLib *link_lib = g->link_libs_list.at(lib_i);
|
||||
if (buf_eql_str(link_lib->name, "c")) {
|
||||
@ -1010,7 +951,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
|
||||
}
|
||||
|
||||
static void construct_linker_job(LinkJob *lj) {
|
||||
switch (lj->codegen->zig_target.oformat) {
|
||||
switch (target_object_format(lj->codegen->zig_target)) {
|
||||
case ZigLLVM_UnknownObjectFormat:
|
||||
zig_unreachable();
|
||||
|
||||
@ -1050,7 +991,7 @@ void codegen_link(CodeGen *g) {
|
||||
for (size_t i = 0; i < g->link_objects.length; i += 1) {
|
||||
file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
|
||||
}
|
||||
ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target.os);
|
||||
ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
|
||||
codegen_add_time_event(g, "LLVM Link");
|
||||
if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
|
||||
fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
|
||||
@ -1075,7 +1016,7 @@ void codegen_link(CodeGen *g) {
|
||||
Buf diag = BUF_INIT;
|
||||
|
||||
codegen_add_time_event(g, "LLVM Link");
|
||||
if (g->system_linker_hack && g->zig_target.os == OsMacOSX) {
|
||||
if (g->system_linker_hack && g->zig_target->os == OsMacOSX) {
|
||||
Termination term;
|
||||
ZigList<const char *> args = {};
|
||||
for (size_t i = 1; i < lj.args.length; i += 1) {
|
||||
@ -1085,7 +1026,7 @@ void codegen_link(CodeGen *g) {
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
exit(1);
|
||||
}
|
||||
} else if (!zig_lld_link(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
|
||||
} else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&diag));
|
||||
exit(1);
|
||||
}
|
||||
|
127
src/main.cpp
127
src/main.cpp
@ -13,6 +13,7 @@
|
||||
#include "error.hpp"
|
||||
#include "os.hpp"
|
||||
#include "target.hpp"
|
||||
#include "libc_installation.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -36,6 +37,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
||||
" id print the base64-encoded compiler id\n"
|
||||
" init-exe initialize a `zig build` application in the cwd\n"
|
||||
" init-lib initialize a `zig build` library in the cwd\n"
|
||||
" libc [paths_file] Display native libc paths file or validate one\n"
|
||||
" run [source] create executable and run immediately\n"
|
||||
" translate-c [source] convert c code to zig code\n"
|
||||
" targets list available compilation targets\n"
|
||||
@ -53,7 +55,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
||||
" --enable-valgrind include valgrind client requests release builds\n"
|
||||
" --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
|
||||
" -ftime-report print timing diagnostics\n"
|
||||
" --libc-include-dir [path] directory where libc stdlib.h resides\n"
|
||||
" --libc [file] Provide a file which specifies libc paths\n"
|
||||
" --name [name] override output name\n"
|
||||
" --output [file] override destination path\n"
|
||||
" --output-h [file] generate header file\n"
|
||||
@ -82,10 +84,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
||||
"Link Options:\n"
|
||||
" --dynamic-linker [path] set the path to ld.so\n"
|
||||
" --each-lib-rpath add rpath for each used dynamic library\n"
|
||||
" --libc-lib-dir [path] directory where libc crt1.o resides\n"
|
||||
" --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
|
||||
" --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n"
|
||||
" --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n"
|
||||
" --library [lib] link against lib\n"
|
||||
" --forbid-library [lib] make it an error to link against lib\n"
|
||||
" --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) {
|
||||
return return_code;
|
||||
}
|
||||
|
||||
static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
|
||||
fprintf(file,
|
||||
"Usage: %s libc\n"
|
||||
"\n"
|
||||
"Detect the native libc installation and print the resulting paths to stdout.\n"
|
||||
"You can save this into a file and then edit the paths to create a cross\n"
|
||||
"compilation libc kit. Then you can pass `--libc [file]` for Zig to use it.\n"
|
||||
"\n"
|
||||
"When compiling natively and no `--libc` argument provided, Zig automatically\n"
|
||||
"creates zig-cache/native_libc.txt so that it does not have to detect libc\n"
|
||||
"on every invocation. You can remove this file to have Zig re-detect the\n"
|
||||
"native libc.\n"
|
||||
"\n\n"
|
||||
"Usage: %s libc [file]\n"
|
||||
"\n"
|
||||
"Parse a libc installation text file and validate it.\n"
|
||||
, arg0, arg0);
|
||||
return return_code;
|
||||
}
|
||||
|
||||
static const char *ZIG_ZEN = "\n"
|
||||
" * Communicate intent precisely.\n"
|
||||
" * Edge cases matter.\n"
|
||||
@ -169,6 +187,7 @@ enum Cmd {
|
||||
CmdTranslateC,
|
||||
CmdVersion,
|
||||
CmdZen,
|
||||
CmdLibC,
|
||||
};
|
||||
|
||||
static const char *default_zig_cache_name = "zig-cache";
|
||||
@ -359,12 +378,7 @@ int main(int argc, char **argv) {
|
||||
bool verbose_cimport = false;
|
||||
ErrColor color = ErrColorAuto;
|
||||
CacheOpt enable_cache = CacheOptAuto;
|
||||
const char *libc_lib_dir = nullptr;
|
||||
const char *libc_static_lib_dir = nullptr;
|
||||
const char *libc_include_dir = nullptr;
|
||||
const char *msvc_lib_dir = nullptr;
|
||||
const char *kernel32_lib_dir = nullptr;
|
||||
const char *dynamic_linker = nullptr;
|
||||
const char *libc_txt = nullptr;
|
||||
ZigList<const char *> clang_argv = {0};
|
||||
ZigList<const char *> llvm_argv = {0};
|
||||
ZigList<const char *> lib_dirs = {0};
|
||||
@ -434,8 +448,10 @@ int main(int argc, char **argv) {
|
||||
Buf *build_runner_path = buf_alloc();
|
||||
os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
|
||||
|
||||
CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
|
||||
override_std_dir);
|
||||
ZigTarget target;
|
||||
get_native_target(&target);
|
||||
CodeGen *g = codegen_create(build_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
|
||||
override_std_dir, nullptr);
|
||||
g->valgrind_support = valgrind_support;
|
||||
g->enable_time_report = timing_info;
|
||||
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) {
|
||||
return (term.how == TerminationIdClean) ? term.code : -1;
|
||||
} else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
|
||||
init_all_targets();
|
||||
ZigTarget target;
|
||||
get_native_target(&target);
|
||||
Buf *fmt_runner_path = buf_alloc();
|
||||
os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
|
||||
CodeGen *g = codegen_create(fmt_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
|
||||
nullptr);
|
||||
CodeGen *g = codegen_create(fmt_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
|
||||
nullptr, nullptr);
|
||||
g->valgrind_support = valgrind_support;
|
||||
g->is_single_threaded = true;
|
||||
codegen_set_out_name(g, buf_create_from_str("fmt"));
|
||||
@ -557,7 +575,11 @@ int main(int argc, char **argv) {
|
||||
} else if (strcmp(arg, "--release-small") == 0) {
|
||||
build_mode = BuildModeSmallRelease;
|
||||
} else if (strcmp(arg, "--help") == 0) {
|
||||
return print_full_usage(arg0, stderr, EXIT_FAILURE);
|
||||
if (cmd == CmdLibC) {
|
||||
return print_libc_usage(arg0, stderr, EXIT_FAILURE);
|
||||
} else {
|
||||
return print_full_usage(arg0, stderr, EXIT_FAILURE);
|
||||
}
|
||||
} else if (strcmp(arg, "--strip") == 0) {
|
||||
strip = true;
|
||||
} else if (strcmp(arg, "--static") == 0) {
|
||||
@ -658,18 +680,8 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
} else if (strcmp(arg, "--name") == 0) {
|
||||
out_name = argv[i];
|
||||
} else if (strcmp(arg, "--libc-lib-dir") == 0) {
|
||||
libc_lib_dir = argv[i];
|
||||
} else if (strcmp(arg, "--libc-static-lib-dir") == 0) {
|
||||
libc_static_lib_dir = argv[i];
|
||||
} else if (strcmp(arg, "--libc-include-dir") == 0) {
|
||||
libc_include_dir = argv[i];
|
||||
} else if (strcmp(arg, "--msvc-lib-dir") == 0) {
|
||||
msvc_lib_dir = argv[i];
|
||||
} else if (strcmp(arg, "--kernel32-lib-dir") == 0) {
|
||||
kernel32_lib_dir = argv[i];
|
||||
} else if (strcmp(arg, "--dynamic-linker") == 0) {
|
||||
dynamic_linker = argv[i];
|
||||
} else if (strcmp(arg, "--libc") == 0) {
|
||||
libc_txt = argv[i];
|
||||
} else if (strcmp(arg, "-isystem") == 0) {
|
||||
clang_argv.append("-isystem");
|
||||
clang_argv.append(argv[i]);
|
||||
@ -778,6 +790,8 @@ int main(int argc, char **argv) {
|
||||
cmd = CmdVersion;
|
||||
} else if (strcmp(arg, "zen") == 0) {
|
||||
cmd = CmdZen;
|
||||
} else if (strcmp(arg, "libc") == 0) {
|
||||
cmd = CmdLibC;
|
||||
} else if (strcmp(arg, "translate-c") == 0) {
|
||||
cmd = CmdTranslateC;
|
||||
} else if (strcmp(arg, "test") == 0) {
|
||||
@ -797,6 +811,7 @@ int main(int argc, char **argv) {
|
||||
case CmdRun:
|
||||
case CmdTranslateC:
|
||||
case CmdTest:
|
||||
case CmdLibC:
|
||||
if (!in_file) {
|
||||
in_file = arg;
|
||||
if (cmd == CmdRun) {
|
||||
@ -828,27 +843,25 @@ int main(int argc, char **argv) {
|
||||
|
||||
init_all_targets();
|
||||
|
||||
ZigTarget alloc_target;
|
||||
ZigTarget *target;
|
||||
ZigTarget target;
|
||||
if (!target_arch && !target_os && !target_environ) {
|
||||
target = nullptr;
|
||||
get_native_target(&target);
|
||||
} else {
|
||||
target = &alloc_target;
|
||||
get_unknown_target(target);
|
||||
get_unknown_target(&target);
|
||||
if (target_arch) {
|
||||
if (parse_target_arch(target_arch, &target->arch)) {
|
||||
if (parse_target_arch(target_arch, &target.arch)) {
|
||||
fprintf(stderr, "invalid --target-arch argument\n");
|
||||
return print_error_usage(arg0);
|
||||
}
|
||||
}
|
||||
if (target_os) {
|
||||
if (parse_target_os(target_os, &target->os)) {
|
||||
if (parse_target_os(target_os, &target.os)) {
|
||||
fprintf(stderr, "invalid --target-os argument\n");
|
||||
return print_error_usage(arg0);
|
||||
}
|
||||
}
|
||||
if (target_environ) {
|
||||
if (parse_target_environ(target_environ, &target->env_type)) {
|
||||
if (parse_target_environ(target_environ, &target.env_type)) {
|
||||
fprintf(stderr, "invalid --target-environ argument\n");
|
||||
return print_error_usage(arg0);
|
||||
}
|
||||
@ -856,8 +869,22 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CmdLibC: {
|
||||
if (in_file) {
|
||||
ZigLibCInstallation libc;
|
||||
if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
ZigLibCInstallation libc;
|
||||
if ((err = zig_libc_find_native(&libc, true)))
|
||||
return EXIT_FAILURE;
|
||||
zig_libc_render(&libc, stdout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
case CmdBuiltin: {
|
||||
CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir);
|
||||
CodeGen *g = codegen_create(nullptr, &target, out_type, build_mode, get_zig_lib_dir(), override_std_dir,
|
||||
nullptr);
|
||||
g->valgrind_support = valgrind_support;
|
||||
g->is_single_threaded = is_single_threaded;
|
||||
Buf *builtin_source = codegen_generate_builtin_source(g);
|
||||
@ -917,8 +944,16 @@ int main(int argc, char **argv) {
|
||||
if (cmd == CmdRun && buf_out_name == nullptr) {
|
||||
buf_out_name = buf_create_from_str("run");
|
||||
}
|
||||
CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(),
|
||||
override_std_dir);
|
||||
ZigLibCInstallation *libc = nullptr;
|
||||
if (libc_txt != nullptr) {
|
||||
libc = allocate<ZigLibCInstallation>(1);
|
||||
if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {
|
||||
fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
CodeGen *g = codegen_create(zig_root_source_file, &target, out_type, build_mode, get_zig_lib_dir(),
|
||||
override_std_dir, libc);
|
||||
g->valgrind_support = valgrind_support;
|
||||
g->subsystem = subsystem;
|
||||
|
||||
@ -944,18 +979,6 @@ int main(int argc, char **argv) {
|
||||
codegen_set_llvm_argv(g, llvm_argv.items, llvm_argv.length);
|
||||
codegen_set_strip(g, strip);
|
||||
codegen_set_is_static(g, is_static);
|
||||
if (libc_lib_dir)
|
||||
codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
|
||||
if (libc_static_lib_dir)
|
||||
codegen_set_libc_static_lib_dir(g, buf_create_from_str(libc_static_lib_dir));
|
||||
if (libc_include_dir)
|
||||
codegen_set_libc_include_dir(g, buf_create_from_str(libc_include_dir));
|
||||
if (msvc_lib_dir)
|
||||
codegen_set_msvc_lib_dir(g, buf_create_from_str(msvc_lib_dir));
|
||||
if (kernel32_lib_dir)
|
||||
codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir));
|
||||
if (dynamic_linker)
|
||||
codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
|
||||
g->verbose_tokenize = verbose_tokenize;
|
||||
g->verbose_ast = verbose_ast;
|
||||
g->verbose_link = verbose_link;
|
||||
@ -1086,7 +1109,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!target_can_exec(&native, target)) {
|
||||
if (!target_can_exec(&native, &target)) {
|
||||
fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",
|
||||
buf_ptr(test_exe_path));
|
||||
return 0;
|
||||
|
14
src/os.cpp
14
src/os.cpp
@ -1550,7 +1550,7 @@ void os_stderr_set_color(TermColor color) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
|
||||
Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
buf_resize(output_buf, 0);
|
||||
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
|
||||
buf_init_from_buf(tmp_buf, output_buf);
|
||||
buf_append_str(tmp_buf, "ucrt.lib");
|
||||
if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
|
||||
return 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
else {
|
||||
buf_resize(output_buf, 0);
|
||||
@ -1582,12 +1582,12 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
|
||||
#endif
|
||||
}
|
||||
|
||||
int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
|
||||
Error os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
buf_resize(output_buf, 0);
|
||||
buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
|
||||
if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
|
||||
return 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
else {
|
||||
buf_resize(output_buf, 0);
|
||||
@ -1598,7 +1598,7 @@ int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
|
||||
Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
{
|
||||
buf_resize(output_buf, 0);
|
||||
@ -1620,7 +1620,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
|
||||
buf_init_from_buf(tmp_buf, output_buf);
|
||||
buf_append_str(tmp_buf, "kernel32.lib");
|
||||
if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
|
||||
return 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -1643,7 +1643,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
|
||||
buf_init_from_buf(tmp_buf, output_buf);
|
||||
buf_append_str(tmp_buf, "kernel32.lib");
|
||||
if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
|
||||
return 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
}
|
||||
return ErrorFileNotFound;
|
||||
|
@ -135,9 +135,9 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);
|
||||
|
||||
Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);
|
||||
|
||||
int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
|
||||
int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
|
||||
int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
|
||||
Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
|
||||
Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
|
||||
Error ATTRIBUTE_MUST_USE os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
|
||||
|
||||
Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);
|
||||
|
||||
|
125
src/target.cpp
125
src/target.cpp
@ -214,7 +214,7 @@ size_t target_oformat_count(void) {
|
||||
return array_length(oformat_list);
|
||||
}
|
||||
|
||||
const ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {
|
||||
ZigLLVM_ObjectFormatType get_target_oformat(size_t index) {
|
||||
return oformat_list[index];
|
||||
}
|
||||
|
||||
@ -443,14 +443,16 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) {
|
||||
|
||||
void get_native_target(ZigTarget *target) {
|
||||
ZigLLVM_OSType os_type;
|
||||
ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
|
||||
ZigLLVMGetNativeTarget(
|
||||
&target->arch.arch,
|
||||
&target->arch.sub_arch,
|
||||
&target->vendor,
|
||||
&os_type,
|
||||
&target->env_type,
|
||||
&target->oformat);
|
||||
&oformat);
|
||||
target->os = get_zig_os_type(os_type);
|
||||
target->is_native = true;
|
||||
}
|
||||
|
||||
void get_unknown_target(ZigTarget *target) {
|
||||
@ -459,7 +461,7 @@ void get_unknown_target(ZigTarget *target) {
|
||||
target->vendor = ZigLLVM_UnknownVendor;
|
||||
target->os = OsFreestanding;
|
||||
target->env_type = ZigLLVM_UnknownEnvironment;
|
||||
target->oformat = ZigLLVM_UnknownObjectFormat;
|
||||
target->is_native = false;
|
||||
}
|
||||
|
||||
static 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) {
|
||||
}
|
||||
}
|
||||
|
||||
void resolve_target_object_format(ZigTarget *target) {
|
||||
if (target->oformat != ZigLLVM_UnknownObjectFormat) {
|
||||
return;
|
||||
ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) {
|
||||
if (target->os == OsUefi || target->os == OsWindows) {
|
||||
return ZigLLVM_COFF;
|
||||
} else if (target_is_darwin(target)) {
|
||||
return ZigLLVM_MachO;
|
||||
}
|
||||
|
||||
switch (target->arch.arch) {
|
||||
case ZigLLVM_UnknownArch:
|
||||
case ZigLLVM_aarch64:
|
||||
case ZigLLVM_arm:
|
||||
case ZigLLVM_thumb:
|
||||
case ZigLLVM_x86:
|
||||
case ZigLLVM_x86_64:
|
||||
if (target_is_darwin(target)) {
|
||||
target->oformat = ZigLLVM_MachO;
|
||||
} else if (target->os == OsWindows) {
|
||||
target->oformat = ZigLLVM_COFF;
|
||||
} else {
|
||||
target->oformat = ZigLLVM_ELF;
|
||||
}
|
||||
return;
|
||||
|
||||
case ZigLLVM_aarch64_be:
|
||||
case ZigLLVM_amdgcn:
|
||||
case ZigLLVM_amdil:
|
||||
case ZigLLVM_amdil64:
|
||||
case ZigLLVM_armeb:
|
||||
case ZigLLVM_arc:
|
||||
case ZigLLVM_avr:
|
||||
case ZigLLVM_bpfeb:
|
||||
case ZigLLVM_bpfel:
|
||||
case ZigLLVM_hexagon:
|
||||
case ZigLLVM_lanai:
|
||||
case ZigLLVM_hsail:
|
||||
case ZigLLVM_hsail64:
|
||||
case ZigLLVM_kalimba:
|
||||
case ZigLLVM_le32:
|
||||
case ZigLLVM_le64:
|
||||
case ZigLLVM_mips:
|
||||
case ZigLLVM_mips64:
|
||||
case ZigLLVM_mips64el:
|
||||
case ZigLLVM_mipsel:
|
||||
case ZigLLVM_msp430:
|
||||
case ZigLLVM_nios2:
|
||||
case ZigLLVM_nvptx:
|
||||
case ZigLLVM_nvptx64:
|
||||
case ZigLLVM_ppc64le:
|
||||
case ZigLLVM_r600:
|
||||
case ZigLLVM_renderscript32:
|
||||
case ZigLLVM_renderscript64:
|
||||
case ZigLLVM_riscv32:
|
||||
case ZigLLVM_riscv64:
|
||||
case ZigLLVM_shave:
|
||||
case ZigLLVM_sparc:
|
||||
case ZigLLVM_sparcel:
|
||||
case ZigLLVM_sparcv9:
|
||||
case ZigLLVM_spir:
|
||||
case ZigLLVM_spir64:
|
||||
case ZigLLVM_systemz:
|
||||
case ZigLLVM_tce:
|
||||
case ZigLLVM_tcele:
|
||||
case ZigLLVM_thumbeb:
|
||||
case ZigLLVM_xcore:
|
||||
target->oformat= ZigLLVM_ELF;
|
||||
return;
|
||||
|
||||
case ZigLLVM_wasm32:
|
||||
case ZigLLVM_wasm64:
|
||||
target->oformat = ZigLLVM_Wasm;
|
||||
return;
|
||||
|
||||
case ZigLLVM_ppc:
|
||||
case ZigLLVM_ppc64:
|
||||
if (target_is_darwin(target)) {
|
||||
target->oformat = ZigLLVM_MachO;
|
||||
} else {
|
||||
target->oformat= ZigLLVM_ELF;
|
||||
}
|
||||
return;
|
||||
if (target->arch.arch == ZigLLVM_wasm32 ||
|
||||
target->arch.arch == ZigLLVM_wasm64)
|
||||
{
|
||||
return ZigLLVM_Wasm;
|
||||
}
|
||||
return ZigLLVM_ELF;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return target->os == OsFreestanding;
|
||||
}
|
||||
|
||||
const char *target_o_file_ext(ZigTarget *target) {
|
||||
const char *target_o_file_ext(const ZigTarget *target) {
|
||||
if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
|
||||
return ".obj";
|
||||
} else {
|
||||
@ -820,15 +755,15 @@ const char *target_o_file_ext(ZigTarget *target) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *target_asm_file_ext(ZigTarget *target) {
|
||||
const char *target_asm_file_ext(const ZigTarget *target) {
|
||||
return ".s";
|
||||
}
|
||||
|
||||
const char *target_llvm_ir_file_ext(ZigTarget *target) {
|
||||
const char *target_llvm_ir_file_ext(const ZigTarget *target) {
|
||||
return ".ll";
|
||||
}
|
||||
|
||||
const char *target_exe_file_ext(ZigTarget *target) {
|
||||
const char *target_exe_file_ext(const ZigTarget *target) {
|
||||
if (target->os == OsWindows) {
|
||||
return ".exe";
|
||||
} else if (target->os == OsUefi) {
|
||||
@ -838,7 +773,9 @@ const char *target_exe_file_ext(ZigTarget *target) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) {
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
size_t version_major, size_t version_minor, size_t version_patch)
|
||||
{
|
||||
if (target->os == OsWindows || target->os == OsUefi) {
|
||||
if (is_static) {
|
||||
return ".lib";
|
||||
@ -860,7 +797,7 @@ enum FloatAbi {
|
||||
FloatAbiSoftFp,
|
||||
};
|
||||
|
||||
static FloatAbi get_float_abi(ZigTarget *target) {
|
||||
static FloatAbi get_float_abi(const ZigTarget *target) {
|
||||
const ZigLLVM_EnvironmentType env = target->env_type;
|
||||
if (env == ZigLLVM_GNUEABIHF ||
|
||||
env == ZigLLVM_EABIHF ||
|
||||
@ -876,7 +813,14 @@ static bool is_64_bit(ZigLLVM_ArchType arch) {
|
||||
return get_arch_pointer_bit_width(arch) == 64;
|
||||
}
|
||||
|
||||
Buf *target_dynamic_linker(ZigTarget *target) {
|
||||
Buf *target_dynamic_linker(const ZigTarget *target) {
|
||||
if (target->os == OsFreeBSD) {
|
||||
return buf_create_from_str("/libexec/ld-elf.so.1");
|
||||
}
|
||||
if (target->os == OsNetBSD) {
|
||||
return buf_create_from_str("/libexec/ld.elf_so");
|
||||
}
|
||||
|
||||
const ZigLLVM_ArchType arch = target->arch.arch;
|
||||
const ZigLLVM_EnvironmentType env = target->env_type;
|
||||
|
||||
@ -1098,3 +1042,10 @@ bool target_has_valgrind_support(const ZigTarget *target) {
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
bool target_requires_libc(const ZigTarget *target) {
|
||||
// On Darwin, we always link libSystem which contains libc.
|
||||
// Similarly on FreeBSD and NetBSD we always link system libc
|
||||
// since this is the stable syscall interface.
|
||||
return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ struct ZigTarget {
|
||||
ZigLLVM_VendorType vendor;
|
||||
Os os;
|
||||
ZigLLVM_EnvironmentType env_type;
|
||||
ZigLLVM_ObjectFormatType oformat;
|
||||
bool is_native;
|
||||
};
|
||||
|
||||
enum CIntType {
|
||||
@ -105,8 +105,9 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index);
|
||||
|
||||
|
||||
size_t target_oformat_count(void);
|
||||
const ZigLLVM_ObjectFormatType get_target_oformat(size_t index);
|
||||
ZigLLVM_ObjectFormatType get_target_oformat(size_t index);
|
||||
const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat);
|
||||
ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target);
|
||||
|
||||
void get_native_target(ZigTarget *target);
|
||||
void get_unknown_target(ZigTarget *target);
|
||||
@ -123,13 +124,14 @@ void resolve_target_object_format(ZigTarget *target);
|
||||
|
||||
uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
|
||||
|
||||
const char *target_o_file_ext(ZigTarget *target);
|
||||
const char *target_asm_file_ext(ZigTarget *target);
|
||||
const char *target_llvm_ir_file_ext(ZigTarget *target);
|
||||
const char *target_exe_file_ext(ZigTarget *target);
|
||||
const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch);
|
||||
const char *target_o_file_ext(const ZigTarget *target);
|
||||
const char *target_asm_file_ext(const ZigTarget *target);
|
||||
const char *target_llvm_ir_file_ext(const ZigTarget *target);
|
||||
const char *target_exe_file_ext(const ZigTarget *target);
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
size_t version_major, size_t version_minor, size_t version_patch);
|
||||
|
||||
Buf *target_dynamic_linker(ZigTarget *target);
|
||||
Buf *target_dynamic_linker(const ZigTarget *target);
|
||||
|
||||
bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
|
||||
ZigLLVM_OSType get_llvm_os_type(Os os_type);
|
||||
@ -138,5 +140,6 @@ bool target_is_arm(const ZigTarget *target);
|
||||
bool target_allows_addr_zero(const ZigTarget *target);
|
||||
bool target_has_valgrind_support(const ZigTarget *target);
|
||||
bool target_is_darwin(const ZigTarget *target);
|
||||
bool target_requires_libc(const ZigTarget *target);
|
||||
|
||||
#endif
|
||||
|
@ -4776,7 +4776,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
|
||||
clang_argv.append("-x");
|
||||
clang_argv.append("c");
|
||||
|
||||
if (c->codegen->is_native_target) {
|
||||
if (c->codegen->zig_target->is_native) {
|
||||
char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");
|
||||
if (ZIG_PARSEC_CFLAGS) {
|
||||
Buf tmp_buf = BUF_INIT;
|
||||
@ -4798,9 +4798,9 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
|
||||
clang_argv.append("-isystem");
|
||||
clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
|
||||
|
||||
if (codegen->libc_include_dir != nullptr) {
|
||||
if (codegen->libc != nullptr) {
|
||||
clang_argv.append("-isystem");
|
||||
clang_argv.append(buf_ptr(codegen->libc_include_dir));
|
||||
clang_argv.append(buf_ptr(&codegen->libc->include_dir));
|
||||
}
|
||||
|
||||
// windows c runtime requires -D_DEBUG if using debug libraries
|
||||
@ -4820,7 +4820,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
|
||||
clang_argv.append("-Xclang");
|
||||
clang_argv.append("-detailed-preprocessing-record");
|
||||
|
||||
if (!c->codegen->is_native_target) {
|
||||
if (!c->codegen->zig_target->is_native) {
|
||||
clang_argv.append("-target");
|
||||
clang_argv.append(buf_ptr(&c->codegen->triple_str));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user