authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-16 01:14:28-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-16 01:14:28-04:00
logd08c57741ae190c587c42861e71b0e361903733e
treeee79c77ec4a568d90ae1cfaefa6fd786cc788926
parent78b753af9dd9818b9dc848f590330c61b2ca7c3f

ability to make a DLL

See #302

7 files changed, 62 insertions(+), 15 deletions(-)

CMakeLists.txt+1
...@@ -587,6 +587,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_S...@@ -587,6 +587,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_S
587install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")587install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
588install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")588install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
589install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")589install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
590install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap_lib.zig" DESTINATION "${ZIG_STD_DEST}/special")
590install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")591install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")
591install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")592install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
592install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")593install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
src/all_types.hpp+1
...@@ -1456,6 +1456,7 @@ struct CodeGen {...@@ -1456,6 +1456,7 @@ struct CodeGen {
1456 bool have_c_main;1456 bool have_c_main;
1457 bool have_winmain;1457 bool have_winmain;
1458 bool have_winmain_crt_startup;1458 bool have_winmain_crt_startup;
1459 bool have_dllmain_crt_startup;
1459 bool have_pub_panic;1460 bool have_pub_panic;
1460 Buf *libc_lib_dir;1461 Buf *libc_lib_dir;
1461 Buf *libc_static_lib_dir;1462 Buf *libc_static_lib_dir;
src/analyze.cpp+4
...@@ -3200,6 +3200,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a...@@ -3200,6 +3200,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
3200 buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)3200 buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)
3201 {3201 {
3202 g->have_winmain_crt_startup = true;3202 g->have_winmain_crt_startup = true;
3203 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport &&
3204 buf_eql_str(proto_name, "DllMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)
3205 {
3206 g->have_dllmain_crt_startup = true;
3203 }3207 }
32043208
3205 }3209 }
src/codegen.cpp+3
...@@ -5228,6 +5228,9 @@ static void gen_root_source(CodeGen *g) {...@@ -5228,6 +5228,9 @@ static void gen_root_source(CodeGen *g) {
5228 {5228 {
5229 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");5229 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
5230 }5230 }
5231 if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
5232 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
5233 }
5231 ImportTableEntry *import_with_panic;5234 ImportTableEntry *import_with_panic;
5232 if (g->have_pub_panic) {5235 if (g->have_pub_panic) {
5233 import_with_panic = g->root_import;5236 import_with_panic = g->root_import;
src/link.cpp+11-4
...@@ -372,6 +372,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -372,6 +372,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
372 // how to handle --target-environ gnu372 // how to handle --target-environ gnu
373 // These comments are a clue373 // These comments are a clue
374374
375 bool is_library = g->out_type == OutTypeLib;
375 //bool dll = g->out_type == OutTypeLib;376 //bool dll = g->out_type == OutTypeLib;
376 //bool shared = !g->is_static && dll;377 //bool shared = !g->is_static && dll;
377 //if (g->is_static) {378 //if (g->is_static) {
...@@ -422,13 +423,19 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -422,13 +423,19 @@ static void construct_linker_job_coff(LinkJob *lj) {
422 //lj->args.append(get_libc_static_file(g, "crtbegin.o"));423 //lj->args.append(get_libc_static_file(g, "crtbegin.o"));
423 } else {424 } else {
424 lj->args.append("-NODEFAULTLIB");425 lj->args.append("-NODEFAULTLIB");
425 if (g->have_winmain) {426 if (!is_library) {
426 lj->args.append("-ENTRY:WinMain");427 if (g->have_winmain) {
427 } else {428 lj->args.append("-ENTRY:WinMain");
428 lj->args.append("-ENTRY:WinMainCRTStartup");429 } else {
430 lj->args.append("-ENTRY:WinMainCRTStartup");
431 }
429 }432 }
430 }433 }
431434
435 if (is_library && !g->is_static) {
436 lj->args.append("-DLL");
437 }
438
432 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {439 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
433 const char *lib_dir = g->lib_dirs.at(i);440 const char *lib_dir = g->lib_dirs.at(i);
434 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));441 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
std/build.zig+33-11
...@@ -636,6 +636,20 @@ pub const Builder = struct {...@@ -636,6 +636,20 @@ pub const Builder = struct {
636 pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {636 pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {
637 return %%fmt_lib.allocPrint(self.allocator, format, args);637 return %%fmt_lib.allocPrint(self.allocator, format, args);
638 }638 }
639
640 fn getCCExe(self: &Builder) -> []const u8 {
641 if (builtin.environ == builtin.Environ.msvc) {
642 return "cl.exe";
643 } else {
644 return os.getEnvVarOwned(self.builder.allocator, "CC") %% |err| {
645 if (err == error.EnvironmentVariableNotFound) {
646 ([]const u8)("cc")
647 } else {
648 return err
649 }
650 };
651 }
652 }
639};653};
640654
641const Version = struct {655const Version = struct {
...@@ -685,6 +699,17 @@ const Target = enum {...@@ -685,6 +699,17 @@ const Target = enum {
685 else => false,699 else => false,
686 };700 };
687 }701 }
702
703 pub fn isWindows(self: &const Target) -> bool {
704 return switch (self.getOs()) {
705 builtin.Os.windows => true,
706 else => false,
707 };
708 }
709
710 pub fn wantSharedLibSymLinks(self: &const Target) -> bool {
711 return !self.isWindows();
712 }
688};713};
689714
690pub const LibExeObjStep = struct {715pub const LibExeObjStep = struct {
...@@ -885,7 +910,7 @@ pub const LibExeObjStep = struct {...@@ -885,7 +910,7 @@ pub const LibExeObjStep = struct {
885 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);910 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
886 },911 },
887 builtin.Os.windows => {912 builtin.Os.windows => {
888 self.out_filename = self.builder.fmt("lib{}.dll", self.name);913 self.out_filename = self.builder.fmt("{}.dll", self.name);
889 },914 },
890 else => {915 else => {
891 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",916 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
...@@ -1200,7 +1225,7 @@ pub const LibExeObjStep = struct {...@@ -1200,7 +1225,7 @@ pub const LibExeObjStep = struct {
12001225
1201 %return builder.spawnChild(zig_args.toSliceConst());1226 %return builder.spawnChild(zig_args.toSliceConst());
12021227
1203 if (self.kind == Kind.Lib and !self.static) {1228 if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {
1204 %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,1229 %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1205 self.name_only_filename);1230 self.name_only_filename);
1206 }1231 }
...@@ -1252,15 +1277,10 @@ pub const LibExeObjStep = struct {...@@ -1252,15 +1277,10 @@ pub const LibExeObjStep = struct {
1252 }1277 }
12531278
1254 fn makeC(self: &LibExeObjStep) -> %void {1279 fn makeC(self: &LibExeObjStep) -> %void {
1255 const cc = os.getEnvVarOwned(self.builder.allocator, "CC") %% |err| {
1256 if (err == error.EnvironmentVariableNotFound) {
1257 ([]const u8)("cc")
1258 } else {
1259 return err
1260 }
1261 };
1262 const builder = self.builder;1280 const builder = self.builder;
12631281
1282 const cc = builder.getCCExe();
1283
1264 assert(!self.is_zig);1284 assert(!self.is_zig);
12651285
1266 var cc_args = ArrayList([]const u8).init(builder.allocator);1286 var cc_args = ArrayList([]const u8).init(builder.allocator);
...@@ -1390,8 +1410,10 @@ pub const LibExeObjStep = struct {...@@ -1390,8 +1410,10 @@ pub const LibExeObjStep = struct {
13901410
1391 %return builder.spawnChild(cc_args.toSliceConst());1411 %return builder.spawnChild(cc_args.toSliceConst());
13921412
1393 %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,1413 if (self.target.wantSharedLibSymLinks()) {
1394 self.name_only_filename);1414 %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1415 self.name_only_filename);
1416 }
1395 }1417 }
1396 },1418 },
1397 Kind.Exe => {1419 Kind.Exe => {
std/special/bootstrap_lib.zig created+9
...@@ -0,0 +1,9 @@
1// This file is included in the compilation unit when exporting a library on windows.
2
3const std = @import("std");
4
5export stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,
6 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL
7{
8 return std.os.windows.TRUE;
9}