authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-25 13:34:25-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-25 13:34:25-05:00
log525c2eaf5d49f537d4ccd48ab0c5bc1f52cc3204
treecf66d3fd2b48f894048dbdfae93e8f5ad1e6e22a
parente76ce2c1d0d3988359267fd3030a81a52ec99f3f

building DLLs on Windows works better


9 files changed, 66 insertions(+), 9 deletions(-)

src/all_types.hpp+1
...@@ -1743,6 +1743,7 @@ struct CodeGen {...@@ -1743,6 +1743,7 @@ struct CodeGen {
1743 Buf triple_str;1743 Buf triple_str;
1744 Buf global_asm;1744 Buf global_asm;
1745 Buf *out_h_path;1745 Buf *out_h_path;
1746 Buf *out_lib_path;
1746 Buf artifact_dir;1747 Buf artifact_dir;
1747 Buf output_file_path;1748 Buf output_file_path;
1748 Buf o_file_output_path;1749 Buf o_file_output_path;
src/codegen.cpp+5-1
...@@ -175,6 +175,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {...@@ -175,6 +175,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {
175 g->out_h_path = h_path;175 g->out_h_path = h_path;
176}176}
177177
178void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path) {
179 g->out_lib_path = lib_path;
180}
181
178void codegen_set_output_path(CodeGen *g, Buf *path) {182void codegen_set_output_path(CodeGen *g, Buf *path) {
179 g->wanted_output_file_path = path;183 g->wanted_output_file_path = path;
180}184}
...@@ -8201,7 +8205,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {...@@ -8201,7 +8205,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
8201 args.append("-c");8205 args.append("-c");
8202 args.append(buf_ptr(c_source_file));8206 args.append(buf_ptr(c_source_file));
82038207
8204 if (!g->disable_pic) {8208 if (!g->disable_pic && target_supports_fpic(g->zig_target)) {
8205 args.append("-fPIC");8209 args.append("-fPIC");
8206 }8210 }
82078211
src/codegen.hpp+1
...@@ -41,6 +41,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter);...@@ -41,6 +41,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter);
41void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);41void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
42void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);42void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
43void codegen_set_output_h_path(CodeGen *g, Buf *h_path);43void codegen_set_output_h_path(CodeGen *g, Buf *h_path);
44void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path);
44void codegen_set_output_path(CodeGen *g, Buf *path);45void codegen_set_output_path(CodeGen *g, Buf *path);
45void codegen_add_time_event(CodeGen *g, const char *name);46void codegen_add_time_event(CodeGen *g, const char *name);
46void codegen_print_timing_report(CodeGen *g, FILE *f);47void codegen_print_timing_report(CodeGen *g, FILE *f);
src/link.cpp+1
...@@ -554,6 +554,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -554,6 +554,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
554 bool is_library = g->out_type == OutTypeLib;554 bool is_library = g->out_type == OutTypeLib;
555 switch (g->subsystem) {555 switch (g->subsystem) {
556 case TargetSubsystemAuto:556 case TargetSubsystemAuto:
557 add_nt_link_args(lj, is_library);
557 break;558 break;
558 case TargetSubsystemConsole:559 case TargetSubsystemConsole:
559 lj->args.append("/SUBSYSTEM:console");560 lj->args.append("/SUBSYSTEM:console");
src/main.cpp+6
...@@ -60,6 +60,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -60,6 +60,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
60 " --name [name] override output name\n"60 " --name [name] override output name\n"
61 " --output [file] override destination path\n"61 " --output [file] override destination path\n"
62 " --output-h [file] generate header file\n"62 " --output-h [file] generate header file\n"
63 " --output-lib [file] override import library path\n"
63 " --pkg-begin [name] [path] make pkg available to import and push current pkg\n"64 " --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
64 " --pkg-end pop current pkg\n"65 " --pkg-end pop current pkg\n"
65 " --release-fast build with optimizations on and safety off\n"66 " --release-fast build with optimizations on and safety off\n"
...@@ -375,6 +376,7 @@ int main(int argc, char **argv) {...@@ -375,6 +376,7 @@ int main(int argc, char **argv) {
375 const char *in_file = nullptr;376 const char *in_file = nullptr;
376 const char *out_file = nullptr;377 const char *out_file = nullptr;
377 const char *out_file_h = nullptr;378 const char *out_file_h = nullptr;
379 const char *out_file_lib = nullptr;
378 bool strip = false;380 bool strip = false;
379 bool is_static = false;381 bool is_static = false;
380 OutType out_type = OutTypeUnknown;382 OutType out_type = OutTypeUnknown;
...@@ -661,6 +663,8 @@ int main(int argc, char **argv) {...@@ -661,6 +663,8 @@ int main(int argc, char **argv) {
661 out_file = argv[i];663 out_file = argv[i];
662 } else if (strcmp(arg, "--output-h") == 0) {664 } else if (strcmp(arg, "--output-h") == 0) {
663 out_file_h = argv[i];665 out_file_h = argv[i];
666 } else if (strcmp(arg, "--output-lib") == 0) {
667 out_file_lib = argv[i];
664 } else if (strcmp(arg, "--color") == 0) {668 } else if (strcmp(arg, "--color") == 0) {
665 if (strcmp(argv[i], "auto") == 0) {669 if (strcmp(argv[i], "auto") == 0) {
666 color = ErrColorAuto;670 color = ErrColorAuto;
...@@ -1094,6 +1098,8 @@ int main(int argc, char **argv) {...@@ -1094,6 +1098,8 @@ int main(int argc, char **argv) {
1094 codegen_set_output_path(g, buf_create_from_str(out_file));1098 codegen_set_output_path(g, buf_create_from_str(out_file));
1095 if (out_file_h != nullptr && (out_type == OutTypeObj || out_type == OutTypeLib))1099 if (out_file_h != nullptr && (out_type == OutTypeObj || out_type == OutTypeLib))
1096 codegen_set_output_h_path(g, buf_create_from_str(out_file_h));1100 codegen_set_output_h_path(g, buf_create_from_str(out_file_h));
1101 if (out_file_lib != nullptr && out_type == OutTypeLib && !is_static)
1102 codegen_set_output_lib_path(g, buf_create_from_str(out_file_lib));
10971103
10981104
1099 add_package(g, cur_pkg, g->root_package);1105 add_package(g, cur_pkg, g->root_package);
src/target.cpp+6
...@@ -1049,3 +1049,9 @@ bool target_requires_libc(const ZigTarget *target) {...@@ -1049,3 +1049,9 @@ bool target_requires_libc(const ZigTarget *target) {
1049 // since this is the stable syscall interface.1049 // since this is the stable syscall interface.
1050 return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);1050 return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);
1051}1051}
1052
1053bool target_supports_fpic(const ZigTarget *target) {
1054 // This is not whether the target supports Position Independent Code, but whether the -fPIC
1055 // C compiler argument is valid.
1056 return target->os != OsWindows;
1057}
src/target.hpp+1
...@@ -141,5 +141,6 @@ bool target_allows_addr_zero(const ZigTarget *target);...@@ -141,5 +141,6 @@ bool target_allows_addr_zero(const ZigTarget *target);
141bool target_has_valgrind_support(const ZigTarget *target);141bool target_has_valgrind_support(const ZigTarget *target);
142bool target_is_darwin(const ZigTarget *target);142bool target_is_darwin(const ZigTarget *target);
143bool target_requires_libc(const ZigTarget *target);143bool target_requires_libc(const ZigTarget *target);
144bool target_supports_fpic(const ZigTarget *target);
144145
145#endif146#endif
std/build.zig+43-2
...@@ -815,6 +815,7 @@ pub const LibExeObjStep = struct {...@@ -815,6 +815,7 @@ pub const LibExeObjStep = struct {
815 linker_script: ?[]const u8,815 linker_script: ?[]const u8,
816 out_filename: []const u8,816 out_filename: []const u8,
817 output_path: ?[]const u8,817 output_path: ?[]const u8,
818 output_lib_path: ?[]const u8,
818 static: bool,819 static: bool,
819 version: Version,820 version: Version,
820 object_files: ArrayList([]const u8),821 object_files: ArrayList([]const u8),
...@@ -839,6 +840,7 @@ pub const LibExeObjStep = struct {...@@ -839,6 +840,7 @@ pub const LibExeObjStep = struct {
839 root_src: ?[]const u8,840 root_src: ?[]const u8,
840 output_h_path: ?[]const u8,841 output_h_path: ?[]const u8,
841 out_h_filename: []const u8,842 out_h_filename: []const u8,
843 out_lib_filename: []const u8,
842 assembly_files: ArrayList([]const u8),844 assembly_files: ArrayList([]const u8),
843 packages: ArrayList(Pkg),845 packages: ArrayList(Pkg),
844 build_options_contents: std.Buffer,846 build_options_contents: std.Buffer,
...@@ -901,10 +903,12 @@ pub const LibExeObjStep = struct {...@@ -901,10 +903,12 @@ pub const LibExeObjStep = struct {
901 .frameworks = BufSet.init(builder.allocator),903 .frameworks = BufSet.init(builder.allocator),
902 .step = Step.init(name, builder.allocator, make),904 .step = Step.init(name, builder.allocator, make),
903 .output_path = null,905 .output_path = null,
906 .output_lib_path = null,
904 .output_h_path = null,907 .output_h_path = null,
905 .version = ver,908 .version = ver,
906 .out_filename = undefined,909 .out_filename = undefined,
907 .out_h_filename = builder.fmt("{}.h", name),910 .out_h_filename = builder.fmt("{}.h", name),
911 .out_lib_filename = undefined,
908 .major_only_filename = undefined,912 .major_only_filename = undefined,
909 .name_only_filename = undefined,913 .name_only_filename = undefined,
910 .object_files = ArrayList([]const u8).init(builder.allocator),914 .object_files = ArrayList([]const u8).init(builder.allocator),
...@@ -941,21 +945,32 @@ pub const LibExeObjStep = struct {...@@ -941,21 +945,32 @@ pub const LibExeObjStep = struct {
941 },945 },
942 Kind.Lib => {946 Kind.Lib => {
943 if (self.static) {947 if (self.static) {
944 self.out_filename = self.builder.fmt("lib{}.a", self.name);948 switch (self.target.getOs()) {
949 builtin.Os.windows => {
950 self.out_filename = self.builder.fmt("{}.lib", self.name);
951 },
952 else => {
953 self.out_filename = self.builder.fmt("lib{}.a", self.name);
954 },
955 }
956 self.out_lib_filename = self.out_filename;
945 } else {957 } else {
946 switch (self.target.getOs()) {958 switch (self.target.getOs()) {
947 builtin.Os.ios, builtin.Os.macosx => {959 builtin.Os.ios, builtin.Os.macosx => {
948 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);960 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
949 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);961 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
950 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);962 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
963 self.out_lib_filename = self.out_filename;
951 },964 },
952 builtin.Os.windows => {965 builtin.Os.windows => {
953 self.out_filename = self.builder.fmt("{}.dll", self.name);966 self.out_filename = self.builder.fmt("{}.dll", self.name);
967 self.out_lib_filename = self.builder.fmt("{}.lib", self.name);
954 },968 },
955 else => {969 else => {
956 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);970 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);
957 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);971 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
958 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);972 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
973 self.out_lib_filename = self.out_filename;
959 },974 },
960 }975 }
961 }976 }
...@@ -990,7 +1005,11 @@ pub const LibExeObjStep = struct {...@@ -990,7 +1005,11 @@ pub const LibExeObjStep = struct {
9901005
991 self.step.dependOn(&lib.step);1006 self.step.dependOn(&lib.step);
9921007
993 self.full_path_libs.append(lib.getOutputPath()) catch unreachable;1008 if (lib.static or self.target.isWindows()) {
1009 self.object_files.append(lib.getOutputLibPath()) catch unreachable;
1010 } else {
1011 self.full_path_libs.append(lib.getOutputPath()) catch unreachable;
1012 }
9941013
995 // TODO should be some kind of isolated directory that only has this header in it1014 // TODO should be some kind of isolated directory that only has this header in it
996 self.include_dirs.append(self.builder.cache_root) catch unreachable;1015 self.include_dirs.append(self.builder.cache_root) catch unreachable;
...@@ -1060,6 +1079,22 @@ pub const LibExeObjStep = struct {...@@ -1060,6 +1079,22 @@ pub const LibExeObjStep = struct {
1060 ) catch unreachable;1079 ) catch unreachable;
1061 }1080 }
10621081
1082 pub fn setOutputLibPath(self: *LibExeObjStep, file_path: []const u8) void {
1083 assert(self.kind == Kind.Lib);
1084 if (self.static)
1085 return self.setOutputPath(file_path);
1086
1087 self.output_lib_path = file_path;
1088 }
1089
1090 pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 {
1091 assert(self.kind == Kind.Lib);
1092 return if (self.output_lib_path) |output_lib_path| output_lib_path else os.path.join(
1093 self.builder.allocator,
1094 [][]const u8{ self.builder.cache_root, self.out_lib_filename },
1095 ) catch unreachable;
1096 }
1097
1063 pub fn setOutputHPath(self: *LibExeObjStep, file_path: []const u8) void {1098 pub fn setOutputHPath(self: *LibExeObjStep, file_path: []const u8) void {
1064 self.output_h_path = file_path;1099 self.output_h_path = file_path;
10651100
...@@ -1225,6 +1260,12 @@ pub const LibExeObjStep = struct {...@@ -1225,6 +1260,12 @@ pub const LibExeObjStep = struct {
1225 zig_args.append("--output") catch unreachable;1260 zig_args.append("--output") catch unreachable;
1226 zig_args.append(output_path) catch unreachable;1261 zig_args.append(output_path) catch unreachable;
12271262
1263 if (self.kind == Kind.Lib and !self.static) {
1264 const output_lib_path = builder.pathFromRoot(self.getOutputLibPath());
1265 zig_args.append("--output-lib") catch unreachable;
1266 zig_args.append(output_lib_path) catch unreachable;
1267 }
1268
1228 if (self.kind != Kind.Exe) {1269 if (self.kind != Kind.Exe) {
1229 const output_h_path = self.getOutputHPath();1270 const output_h_path = self.getOutputHPath();
1230 zig_args.append("--output-h") catch unreachable;1271 zig_args.append("--output-h") catch unreachable;
test/build_examples.zig+2-6
...@@ -7,12 +7,8 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {...@@ -7,12 +7,8 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
7 cases.addC("example/hello_world/hello_libc.zig");7 cases.addC("example/hello_world/hello_libc.zig");
8 cases.add("example/cat/main.zig");8 cases.add("example/cat/main.zig");
9 cases.add("example/guess_number/main.zig");9 cases.add("example/guess_number/main.zig");
10 if (!is_windows) {10 cases.addBuildFile("example/shared_library/build.zig");
11 // TODO get this test passing on windows11 cases.addBuildFile("example/mix_o_files/build.zig");
12 // See https://github.com/ziglang/zig/issues/538
13 cases.addBuildFile("example/shared_library/build.zig");
14 cases.addBuildFile("example/mix_o_files/build.zig");
15 }
16 if (builtin.os != builtin.Os.macosx) {12 if (builtin.os != builtin.Os.macosx) {
17 // TODO https://github.com/ziglang/zig/issues/112613 // TODO https://github.com/ziglang/zig/issues/1126
18 cases.addBuildFile("test/standalone/issue_339/build.zig");14 cases.addBuildFile("test/standalone/issue_339/build.zig");