diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-10-16 01:14:28 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-10-16 01:14:28 -0400 |
| commit | d08c57741ae190c587c42861e71b0e361903733e (patch) | |
| tree | ee79c77ec4a568d90ae1cfaefa6fd786cc788926 | |
| parent | 78b753af9dd9818b9dc848f590330c61b2ca7c3f (diff) | |
| download | zig-d08c57741ae190c587c42861e71b0e361903733e.tar.gz zig-d08c57741ae190c587c42861e71b0e361903733e.zip | |
ability to make a DLL
See #302
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/analyze.cpp | 4 | ||||
| -rw-r--r-- | src/codegen.cpp | 3 | ||||
| -rw-r--r-- | src/link.cpp | 15 | ||||
| -rw-r--r-- | std/build.zig | 44 | ||||
| -rw-r--r-- | std/special/bootstrap_lib.zig | 9 |
7 files changed, 62 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f27404a530..f614c81e50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -587,6 +587,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_S install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") +install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap_lib.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") diff --git a/src/all_types.hpp b/src/all_types.hpp index 57ff028d40..a5244b87b8 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1456,6 +1456,7 @@ struct CodeGen { bool have_c_main; bool have_winmain; bool have_winmain_crt_startup; + bool have_dllmain_crt_startup; bool have_pub_panic; Buf *libc_lib_dir; Buf *libc_static_lib_dir; diff --git a/src/analyze.cpp b/src/analyze.cpp index 5e702964d3..3bb4fe6511 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3200,6 +3200,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) { g->have_winmain_crt_startup = true; + } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && + buf_eql_str(proto_name, "DllMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) + { + g->have_dllmain_crt_startup = true; } } diff --git a/src/codegen.cpp b/src/codegen.cpp index e119b714a8..2ffb2c49c2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5228,6 +5228,9 @@ static void gen_root_source(CodeGen *g) { { g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); } + if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { + g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); + } ImportTableEntry *import_with_panic; if (g->have_pub_panic) { import_with_panic = g->root_import; diff --git a/src/link.cpp b/src/link.cpp index 475e42fd7b..0a25471d3c 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -372,6 +372,7 @@ static void construct_linker_job_coff(LinkJob *lj) { // how to handle --target-environ gnu // These comments are a clue + bool is_library = g->out_type == OutTypeLib; //bool dll = g->out_type == OutTypeLib; //bool shared = !g->is_static && dll; //if (g->is_static) { @@ -422,13 +423,19 @@ static void construct_linker_job_coff(LinkJob *lj) { //lj->args.append(get_libc_static_file(g, "crtbegin.o")); } else { lj->args.append("-NODEFAULTLIB"); - if (g->have_winmain) { - lj->args.append("-ENTRY:WinMain"); - } else { - lj->args.append("-ENTRY:WinMainCRTStartup"); + if (!is_library) { + if (g->have_winmain) { + lj->args.append("-ENTRY:WinMain"); + } else { + lj->args.append("-ENTRY:WinMainCRTStartup"); + } } } + if (is_library && !g->is_static) { + lj->args.append("-DLL"); + } + for (size_t i = 0; i < g->lib_dirs.length; i += 1) { const char *lib_dir = g->lib_dirs.at(i); lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); diff --git a/std/build.zig b/std/build.zig index 22aac84199..4004a4db0e 100644 --- a/std/build.zig +++ b/std/build.zig @@ -636,6 +636,20 @@ pub const Builder = struct { pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 { return %%fmt_lib.allocPrint(self.allocator, format, args); } + + fn getCCExe(self: &Builder) -> []const u8 { + if (builtin.environ == builtin.Environ.msvc) { + return "cl.exe"; + } else { + return os.getEnvVarOwned(self.builder.allocator, "CC") %% |err| { + if (err == error.EnvironmentVariableNotFound) { + ([]const u8)("cc") + } else { + return err + } + }; + } + } }; const Version = struct { @@ -685,6 +699,17 @@ const Target = enum { else => false, }; } + + pub fn isWindows(self: &const Target) -> bool { + return switch (self.getOs()) { + builtin.Os.windows => true, + else => false, + }; + } + + pub fn wantSharedLibSymLinks(self: &const Target) -> bool { + return !self.isWindows(); + } }; pub const LibExeObjStep = struct { @@ -885,7 +910,7 @@ pub const LibExeObjStep = struct { self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name); }, builtin.Os.windows => { - self.out_filename = self.builder.fmt("lib{}.dll", self.name); + self.out_filename = self.builder.fmt("{}.dll", self.name); }, else => { self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", @@ -1200,7 +1225,7 @@ pub const LibExeObjStep = struct { %return builder.spawnChild(zig_args.toSliceConst()); - if (self.kind == Kind.Lib and !self.static) { + if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename); } @@ -1252,15 +1277,10 @@ pub const LibExeObjStep = struct { } fn makeC(self: &LibExeObjStep) -> %void { - const cc = os.getEnvVarOwned(self.builder.allocator, "CC") %% |err| { - if (err == error.EnvironmentVariableNotFound) { - ([]const u8)("cc") - } else { - return err - } - }; const builder = self.builder; + const cc = builder.getCCExe(); + assert(!self.is_zig); var cc_args = ArrayList([]const u8).init(builder.allocator); @@ -1390,8 +1410,10 @@ pub const LibExeObjStep = struct { %return builder.spawnChild(cc_args.toSliceConst()); - %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, - self.name_only_filename); + if (self.target.wantSharedLibSymLinks()) { + %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, + self.name_only_filename); + } } }, Kind.Exe => { diff --git a/std/special/bootstrap_lib.zig b/std/special/bootstrap_lib.zig new file mode 100644 index 0000000000..7412d64fa6 --- /dev/null +++ b/std/special/bootstrap_lib.zig @@ -0,0 +1,9 @@ +// This file is included in the compilation unit when exporting a library on windows. + +const std = @import("std"); + +export stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, + lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL +{ + return std.os.windows.TRUE; +} |
