authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-10-08 13:24:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-10-09 13:15:14-04:00
log5a3c02137e6a15d3b8c1fb3595d55003ea44139a
treeda14bf7f1a691d133747721f7e84ff87dcbb5512
parentd40c4e7c896c5dfed9dd35e8c0d2117f7cf5c53c
signature Commit is signed but in an unrecognized format.

support building static libraries

closes #1493 closes #54

7 files changed, 71 insertions(+), 25 deletions(-)

src/codegen.cpp+3-1
......@@ -7487,7 +7487,9 @@ static void gen_root_source(CodeGen *g) {
74877487 {
74887488 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
74897489 }
7490 if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
7490 if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup &&
7491 g->out_type == OutTypeLib && !g->is_static)
7492 {
74917493 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
74927494 }
74937495
src/link.cpp+23-20
......@@ -29,9 +29,9 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {
2929 return buf_ptr(out_buf);
3030}
3131
32static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path) {
32static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {
3333 ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
34 CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj, parent_gen->build_mode,
34 CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeLib, parent_gen->build_mode,
3535 parent_gen->zig_lib_dir);
3636
3737 child_gen->out_h_path = nullptr;
......@@ -43,32 +43,26 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
4343 child_gen->verbose_cimport = parent_gen->verbose_cimport;
4444
4545 codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
46 codegen_set_is_static(child_gen, parent_gen->is_static);
46 codegen_set_is_static(child_gen, true);
4747
48 codegen_set_out_name(child_gen, buf_create_from_str(oname));
48 codegen_set_out_name(child_gen, buf_create_from_str(aname));
4949
5050 codegen_set_errmsg_color(child_gen, parent_gen->err_color);
5151
5252 codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);
5353 codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min);
5454
55 for (size_t i = 0; i < parent_gen->link_libs_list.length; i += 1) {
56 LinkLib *link_lib = parent_gen->link_libs_list.at(i);
57 LinkLib *new_link_lib = codegen_add_link_lib(child_gen, link_lib->name);
58 new_link_lib->provided_explicitly = link_lib->provided_explicitly;
59 }
60
6155 child_gen->enable_cache = true;
6256 codegen_build_and_link(child_gen);
6357 return &child_gen->output_file_path;
6458}
6559
66static Buf *build_o(CodeGen *parent_gen, const char *oname) {
67 Buf *source_basename = buf_sprintf("%s.zig", oname);
60static Buf *build_a(CodeGen *parent_gen, const char *aname) {
61 Buf *source_basename = buf_sprintf("%s.zig", aname);
6862 Buf *full_path = buf_alloc();
6963 os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
7064
71 return build_o_raw(parent_gen, oname, full_path);
65 return build_a_raw(parent_gen, aname, full_path);
7266}
7367
7468static Buf *build_compiler_rt(CodeGen *parent_gen) {
......@@ -77,7 +71,7 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) {
7771 Buf *full_path = buf_alloc();
7872 os_path_join(dir_path, buf_create_from_str("index.zig"), full_path);
7973
80 return build_o_raw(parent_gen, "compiler_rt", full_path);
74 return build_a_raw(parent_gen, "compiler_rt", full_path);
8175}
8276
8377static const char *get_darwin_arch_string(const ZigTarget *t) {
......@@ -317,8 +311,8 @@ static void construct_linker_job_elf(LinkJob *lj) {
317311
318312 if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) {
319313 if (g->libc_link_lib == nullptr) {
320 Buf *builtin_o_path = build_o(g, "builtin");
321 lj->args.append(buf_ptr(builtin_o_path));
314 Buf *builtin_a_path = build_a(g, "builtin");
315 lj->args.append(buf_ptr(builtin_a_path));
322316 }
323317
324318 // sometimes libgcc is missing stuff, so we still build compiler_rt and rely on weak linkage
......@@ -548,8 +542,8 @@ static void construct_linker_job_coff(LinkJob *lj) {
548542
549543 if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) {
550544 if (g->libc_link_lib == nullptr) {
551 Buf *builtin_o_path = build_o(g, "builtin");
552 lj->args.append(buf_ptr(builtin_o_path));
545 Buf *builtin_a_path = build_a(g, "builtin");
546 lj->args.append(buf_ptr(builtin_a_path));
553547 }
554548
555549 // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
......@@ -960,8 +954,17 @@ void codegen_link(CodeGen *g) {
960954 }
961955
962956 if (g->out_type == OutTypeLib && g->is_static) {
963 fprintf(stderr, "Zig does not yet support creating static libraries\nSee https://github.com/ziglang/zig/issues/1493\n");
964 exit(1);
957 ZigList<const char *> file_names = {};
958 for (size_t i = 0; i < g->link_objects.length; i += 1) {
959 file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
960 }
961 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target.os);
962 codegen_add_time_event(g, "LLVM Link");
963 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
964 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
965 exit(1);
966 }
967 return;
965968 }
966969
967970 lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe);
src/target.cpp+1-1
......@@ -250,7 +250,7 @@ Os get_target_os(size_t index) {
250250 return os_list[index];
251251}
252252
253static ZigLLVM_OSType get_llvm_os_type(Os os_type) {
253ZigLLVM_OSType get_llvm_os_type(Os os_type) {
254254 switch (os_type) {
255255 case OsFreestanding:
256256 case OsZen:
src/target.hpp+1-1
......@@ -119,6 +119,6 @@ const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t versio
119119Buf *target_dynamic_linker(ZigTarget *target);
120120
121121bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
122
122ZigLLVM_OSType get_llvm_os_type(Os os_type);
123123
124124#endif
src/zig_llvm.cpp+39-1
......@@ -32,6 +32,8 @@
3232#include <llvm/IR/Verifier.h>
3333#include <llvm/InitializePasses.h>
3434#include <llvm/MC/SubtargetFeature.h>
35#include <llvm/Object/Archive.h>
36#include <llvm/Object/ArchiveWriter.h>
3537#include <llvm/PassRegistry.h>
3638#include <llvm/Support/FileSystem.h>
3739#include <llvm/Support/TargetParser.h>
......@@ -40,8 +42,8 @@
4042#include <llvm/Target/TargetMachine.h>
4143#include <llvm/Transforms/Coroutines.h>
4244#include <llvm/Transforms/IPO.h>
43#include <llvm/Transforms/IPO/PassManagerBuilder.h>
4445#include <llvm/Transforms/IPO/AlwaysInliner.h>
46#include <llvm/Transforms/IPO/PassManagerBuilder.h>
4547#include <llvm/Transforms/Scalar.h>
4648#include <llvm/Transforms/Utils.h>
4749
......@@ -854,6 +856,42 @@ class MyOStream: public raw_ostream {
854856 size_t pos;
855857};
856858
859bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
860 ZigLLVM_OSType os_type)
861{
862 object::Archive::Kind kind;
863 switch (os_type) {
864 case ZigLLVM_Win32:
865 // For some reason llvm-lib passes K_GNU on windows.
866 // See lib/ToolDrivers/llvm-lib/LibDriver.cpp:168 in libDriverMain
867 kind = object::Archive::K_GNU;
868 break;
869 case ZigLLVM_Linux:
870 kind = object::Archive::K_GNU;
871 break;
872 case ZigLLVM_Darwin:
873 case ZigLLVM_IOS:
874 kind = object::Archive::K_DARWIN;
875 break;
876 case ZigLLVM_OpenBSD:
877 case ZigLLVM_FreeBSD:
878 kind = object::Archive::K_BSD;
879 break;
880 default:
881 kind = object::Archive::K_GNU;
882 }
883 SmallVector<NewArchiveMember, 4> new_members;
884 for (size_t i = 0; i < file_name_count; i += 1) {
885 Expected<NewArchiveMember> new_member = NewArchiveMember::getFile(file_names[i], true);
886 Error err = new_member.takeError();
887 if (err) return true;
888 new_members.push_back(std::move(*new_member));
889 }
890 Error err = writeArchive(archive_name, new_members, true, kind, true, false, nullptr);
891 if (err) return true;
892 return false;
893}
894
857895
858896bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
859897 void (*append_diagnostic)(void *, const char *, size_t), void *context)
src/zig_llvm.h+3
......@@ -406,6 +406,9 @@ ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentT
406406ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
407407 void (*append_diagnostic)(void *, const char *, size_t), void *context);
408408
409ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count,
410 enum ZigLLVM_OSType os_type);
411
409412ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,
410413 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
411414 enum ZigLLVM_ObjectFormatType *oformat);
std/special/bootstrap_lib.zig+1-1
......@@ -1,4 +1,4 @@
1// This file is included in the compilation unit when exporting a library on windows.
1// This file is included in the compilation unit when exporting a DLL on windows.
22
33const std = @import("std");
44const builtin = @import("builtin");