diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-03-12 17:32:32 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-03-12 17:32:32 -0400 |
| commit | 62486c35a483d759b29fa5da235da66590bde6d7 (patch) | |
| tree | 9325e41870f70db4d044345eaafd565a800adaf9 /src | |
| parent | 5734b7a37a75b927ca31e52ad915d7de125993d9 (diff) | |
| download | zig-62486c35a483d759b29fa5da235da66590bde6d7.tar.gz zig-62486c35a483d759b29fa5da235da66590bde6d7.zip | |
ability to build musl from source
bundles musl 1.1.21
See #514
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.cpp | 11 | ||||
| -rw-r--r-- | src/config.h.in | 2 | ||||
| -rw-r--r-- | src/install_files.h.in | 15 | ||||
| -rw-r--r-- | src/link.cpp | 159 | ||||
| -rw-r--r-- | src/main.cpp | 1 |
5 files changed, 178 insertions, 10 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 6ee41fff31..b1b9e46036 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8014,11 +8014,14 @@ static void detect_libc(CodeGen *g) { } 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", target_os_name(g->zig_target->os)); + "Zig is unable to provide a libc for the chosen target '%s-%s-%s'.\n" + "The target is non-native, so Zig also cannot use the native libc installation.\n" + "Choose a target which has a libc available, or provide a libc installation text file.\n" + "See `zig libc --help` for more details.\n", + target_arch_name(g->zig_target->arch), + target_os_name(g->zig_target->os), + target_abi_name(g->zig_target->abi)); exit(1); } } diff --git a/src/config.h.in b/src/config.h.in index 16896273b3..a99aab0d72 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -22,8 +22,6 @@ #define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@" #define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@" #define ZIG_LLVM_CONFIG_EXE "@LLVM_CONFIG_EXE@" -#define ZIG_STD_FILES "@ZIG_STD_FILES@" -#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@" #define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@" #endif diff --git a/src/install_files.h.in b/src/install_files.h.in new file mode 100644 index 0000000000..2c31c6d13c --- /dev/null +++ b/src/install_files.h.in @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_INSTALL_FILES_H +#define ZIG_INSTALL_FILES_H + +#define ZIG_MUSL_SRC_FILES "@ZIG_MUSL_SRC_FILES@" +#define ZIG_STD_FILES "@ZIG_STD_FILES@" +#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@" + +#endif diff --git a/src/link.cpp b/src/link.cpp index 222eeb87b7..854100897f 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -10,7 +10,7 @@ #include "codegen.hpp" #include "analyze.hpp" #include "compiler.hpp" - +#include "install_files.h" struct LinkJob { CodeGen *codegen; @@ -458,11 +458,157 @@ static void musl_add_cc_args(CodeGen *parent, CFile *c_file) { c_file->args.append("-fno-asynchronous-unwind-tables"); c_file->args.append("-ffunction-sections"); c_file->args.append("-fdata-sections"); +} - c_file->args.append("-fno-stack-protector"); - c_file->args.append("-DCRT"); +static const char *musl_arch_names[] = { + "aarch64", + "arm", + "generic", + "i386", + "m68k", + "microblaze", + "mips", + "mips64", + "mipsn32", + "or1k", + "powerpc", + "powerpc64", + "s390x", + "sh", + "x32", + "x86_64", +}; + +static bool is_musl_arch_name(const char *name) { + for (size_t i = 0; i < array_length(musl_arch_names); i += 1) { + if (strcmp(name, musl_arch_names[i]) == 0) + return true; + } + return false; } +static const char *build_musl(CodeGen *parent) { + CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); + codegen_set_out_name(child_gen, buf_create_from_str("c")); + child_gen->is_static = true; + + // When there is a src/<arch>/foo.* then it should substitute for src/foo.* + // Even a .s file can substitute for a .c file. + + enum MuslSrc { + MuslSrcAsm, + MuslSrcNormal, + MuslSrcO3, + }; + + HashMap<Buf *, MuslSrc, buf_hash, buf_eql_buf> source_table = {}; + source_table.init(1800); + + SplitIterator install_h_it = memSplit(str(ZIG_MUSL_SRC_FILES), str(";")); + const char *target_musl_arch_name = musl_arch_name(parent->zig_target); + for (;;) { + Optional<Slice<uint8_t>> opt_item = SplitIterator_next(&install_h_it); + if (!opt_item.is_some) break; + Buf *src_file = buf_create_from_slice(opt_item.value); + + MuslSrc src_kind; + if (buf_ends_with_str(src_file, ".c")) { + assert(buf_starts_with_str(src_file, "musl/src/")); + bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") || + buf_starts_with_str(src_file, "musl/src/string/") || + buf_starts_with_str(src_file, "musl/src/internal/"); + src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal; + } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) { + src_kind = MuslSrcAsm; + } else { + continue; + } + if (ZIG_OS_SEP_CHAR != '/') { + buf_replace(src_file, '/', ZIG_OS_SEP_CHAR); + } + source_table.put_unique(src_file, src_kind); + } + + ZigList<CFile *> c_source_files = {0}; + + Buf dirname = BUF_INIT; + Buf basename = BUF_INIT; + Buf noextbasename = BUF_INIT; + Buf dirbasename = BUF_INIT; + Buf before_arch_dir = BUF_INIT; + Buf override_c = BUF_INIT; + Buf override_s = BUF_INIT; + Buf override_S = BUF_INIT; + + auto source_it = source_table.entry_iterator(); + for (;;) { + auto *entry = source_it.next(); + if (!entry) break; + + Buf *src_file = entry->key; + MuslSrc src_kind = entry->value; + + os_path_split(src_file, &dirname, &basename); + os_path_extname(&basename, &noextbasename, nullptr); + os_path_split(&dirname, &before_arch_dir, &dirbasename); + if (is_musl_arch_name(buf_ptr(&dirbasename))) { + // We find these by explicitly looking for overrides. + continue; + } + // Look for an arch specific override. + buf_resize(&override_c, 0); + buf_resize(&override_s, 0); + buf_resize(&override_S, 0); + + buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + + if (source_table.maybe_get(&override_c) != nullptr) { + src_file = &override_c; + src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind; + } else if (source_table.maybe_get(&override_s) != nullptr) { + src_file = &override_s; + src_kind = MuslSrcAsm; + } else if (source_table.maybe_get(&override_S) != nullptr) { + src_file = &override_S; + src_kind = MuslSrcAsm; + } + + Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s", + buf_ptr(parent->zig_lib_dir), buf_ptr(src_file)); + + if (src_kind == MuslSrcAsm) { + codegen_add_assembly(child_gen, full_path); + } else { + CFile *c_file = allocate<CFile>(1); + c_file->source_path = buf_ptr(full_path); + musl_add_cc_args(parent, c_file); + c_file->args.append("-Wno-ignored-attributes"); + c_file->args.append("-Wno-bitwise-op-parentheses"); + c_file->args.append("-Wno-logical-op-parentheses"); + c_file->args.append("-Wno-dangling-else"); + c_file->args.append("-Wno-shift-op-parentheses"); + c_file->args.append("-Qunused-arguments"); + c_file->args.append("-Wno-unknown-pragmas"); + c_file->args.append("-Wno-string-plus-int"); + c_file->args.append("-Wno-parentheses"); + if (src_kind == MuslSrcO3) { + c_file->args.append("-O3"); + } + c_source_files.append(c_file); + } + } + + child_gen->c_source_files = c_source_files; + codegen_build_and_link(child_gen); + return buf_ptr(&child_gen->output_file_path); +} + + static const char *get_libc_crt_file(CodeGen *parent, const char *file) { if (parent->libc == nullptr && target_is_glibc(parent)) { if (strcmp(file, "crti.o") == 0) { @@ -620,12 +766,16 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { CFile *c_file = allocate<CFile>(1); c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c"); musl_add_cc_args(parent, c_file); + c_file->args.append("-fno-stack-protector"); + c_file->args.append("-DCRT"); return build_libc_object(parent, "crt1", c_file); } else if (strcmp(file, "Scrt1.o") == 0) { CFile *c_file = allocate<CFile>(1); c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c"); musl_add_cc_args(parent, c_file); c_file->args.append("-fPIC"); + c_file->args.append("-fno-stack-protector"); + c_file->args.append("-DCRT"); return build_libc_object(parent, "Scrt1", c_file); } else { zig_unreachable(); @@ -937,7 +1087,8 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append(build_dummy_so(g, "rt", 1)); lj->args.append(get_libc_crt_file(g, "libc_nonshared.a")); } else if (target_is_musl(g)) { - //lj->args.append(build_musl(g)); TODO + lj->args.append(build_libunwind(g)); + lj->args.append(build_musl(g)); } else { zig_unreachable(); } diff --git a/src/main.cpp b/src/main.cpp index 28da1cbbe7..af3b878b09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "codegen.hpp" #include "compiler.hpp" #include "config.h" +#include "install_files.h" #include "error.hpp" #include "os.hpp" #include "target.hpp" |
