building DLLs on Windows works better

master
Andrew Kelley 2019-02-25 13:34:25 -05:00
parent e76ce2c1d0
commit 525c2eaf5d
9 changed files with 66 additions and 9 deletions

View File

@ -1743,6 +1743,7 @@ struct CodeGen {
Buf triple_str;
Buf global_asm;
Buf *out_h_path;
Buf *out_lib_path;
Buf artifact_dir;
Buf output_file_path;
Buf o_file_output_path;

View File

@ -175,6 +175,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {
g->out_h_path = h_path;
}
void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path) {
g->out_lib_path = lib_path;
}
void codegen_set_output_path(CodeGen *g, Buf *path) {
g->wanted_output_file_path = path;
}
@ -8201,7 +8205,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
args.append("-c");
args.append(buf_ptr(c_source_file));
if (!g->disable_pic) {
if (!g->disable_pic && target_supports_fpic(g->zig_target)) {
args.append("-fPIC");
}

View File

@ -41,6 +41,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter);
void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
void codegen_set_output_h_path(CodeGen *g, Buf *h_path);
void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path);
void codegen_set_output_path(CodeGen *g, Buf *path);
void codegen_add_time_event(CodeGen *g, const char *name);
void codegen_print_timing_report(CodeGen *g, FILE *f);

View File

@ -554,6 +554,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
bool is_library = g->out_type == OutTypeLib;
switch (g->subsystem) {
case TargetSubsystemAuto:
add_nt_link_args(lj, is_library);
break;
case TargetSubsystemConsole:
lj->args.append("/SUBSYSTEM:console");

View File

@ -60,6 +60,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" --name [name] override output name\n"
" --output [file] override destination path\n"
" --output-h [file] generate header file\n"
" --output-lib [file] override import library path\n"
" --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
" --pkg-end pop current pkg\n"
" --release-fast build with optimizations on and safety off\n"
@ -375,6 +376,7 @@ int main(int argc, char **argv) {
const char *in_file = nullptr;
const char *out_file = nullptr;
const char *out_file_h = nullptr;
const char *out_file_lib = nullptr;
bool strip = false;
bool is_static = false;
OutType out_type = OutTypeUnknown;
@ -661,6 +663,8 @@ int main(int argc, char **argv) {
out_file = argv[i];
} else if (strcmp(arg, "--output-h") == 0) {
out_file_h = argv[i];
} else if (strcmp(arg, "--output-lib") == 0) {
out_file_lib = argv[i];
} else if (strcmp(arg, "--color") == 0) {
if (strcmp(argv[i], "auto") == 0) {
color = ErrColorAuto;
@ -1094,6 +1098,8 @@ int main(int argc, char **argv) {
codegen_set_output_path(g, buf_create_from_str(out_file));
if (out_file_h != nullptr && (out_type == OutTypeObj || out_type == OutTypeLib))
codegen_set_output_h_path(g, buf_create_from_str(out_file_h));
if (out_file_lib != nullptr && out_type == OutTypeLib && !is_static)
codegen_set_output_lib_path(g, buf_create_from_str(out_file_lib));
add_package(g, cur_pkg, g->root_package);

View File

@ -1049,3 +1049,9 @@ bool target_requires_libc(const ZigTarget *target) {
// since this is the stable syscall interface.
return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD);
}
bool target_supports_fpic(const ZigTarget *target) {
// This is not whether the target supports Position Independent Code, but whether the -fPIC
// C compiler argument is valid.
return target->os != OsWindows;
}

View File

@ -141,5 +141,6 @@ bool target_allows_addr_zero(const ZigTarget *target);
bool target_has_valgrind_support(const ZigTarget *target);
bool target_is_darwin(const ZigTarget *target);
bool target_requires_libc(const ZigTarget *target);
bool target_supports_fpic(const ZigTarget *target);
#endif

View File

@ -815,6 +815,7 @@ pub const LibExeObjStep = struct {
linker_script: ?[]const u8,
out_filename: []const u8,
output_path: ?[]const u8,
output_lib_path: ?[]const u8,
static: bool,
version: Version,
object_files: ArrayList([]const u8),
@ -839,6 +840,7 @@ pub const LibExeObjStep = struct {
root_src: ?[]const u8,
output_h_path: ?[]const u8,
out_h_filename: []const u8,
out_lib_filename: []const u8,
assembly_files: ArrayList([]const u8),
packages: ArrayList(Pkg),
build_options_contents: std.Buffer,
@ -901,10 +903,12 @@ pub const LibExeObjStep = struct {
.frameworks = BufSet.init(builder.allocator),
.step = Step.init(name, builder.allocator, make),
.output_path = null,
.output_lib_path = null,
.output_h_path = null,
.version = ver,
.out_filename = undefined,
.out_h_filename = builder.fmt("{}.h", name),
.out_lib_filename = undefined,
.major_only_filename = undefined,
.name_only_filename = undefined,
.object_files = ArrayList([]const u8).init(builder.allocator),
@ -941,21 +945,32 @@ pub const LibExeObjStep = struct {
},
Kind.Lib => {
if (self.static) {
self.out_filename = self.builder.fmt("lib{}.a", self.name);
switch (self.target.getOs()) {
builtin.Os.windows => {
self.out_filename = self.builder.fmt("{}.lib", self.name);
},
else => {
self.out_filename = self.builder.fmt("lib{}.a", self.name);
},
}
self.out_lib_filename = self.out_filename;
} else {
switch (self.target.getOs()) {
builtin.Os.ios, builtin.Os.macosx => {
self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
self.out_lib_filename = self.out_filename;
},
builtin.Os.windows => {
self.out_filename = self.builder.fmt("{}.dll", self.name);
self.out_lib_filename = self.builder.fmt("{}.lib", self.name);
},
else => {
self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);
self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
self.out_lib_filename = self.out_filename;
},
}
}
@ -990,7 +1005,11 @@ pub const LibExeObjStep = struct {
self.step.dependOn(&lib.step);
self.full_path_libs.append(lib.getOutputPath()) catch unreachable;
if (lib.static or self.target.isWindows()) {
self.object_files.append(lib.getOutputLibPath()) catch unreachable;
} else {
self.full_path_libs.append(lib.getOutputPath()) catch unreachable;
}
// TODO should be some kind of isolated directory that only has this header in it
self.include_dirs.append(self.builder.cache_root) catch unreachable;
@ -1060,6 +1079,22 @@ pub const LibExeObjStep = struct {
) catch unreachable;
}
pub fn setOutputLibPath(self: *LibExeObjStep, file_path: []const u8) void {
assert(self.kind == Kind.Lib);
if (self.static)
return self.setOutputPath(file_path);
self.output_lib_path = file_path;
}
pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 {
assert(self.kind == Kind.Lib);
return if (self.output_lib_path) |output_lib_path| output_lib_path else os.path.join(
self.builder.allocator,
[][]const u8{ self.builder.cache_root, self.out_lib_filename },
) catch unreachable;
}
pub fn setOutputHPath(self: *LibExeObjStep, file_path: []const u8) void {
self.output_h_path = file_path;
@ -1225,6 +1260,12 @@ pub const LibExeObjStep = struct {
zig_args.append("--output") catch unreachable;
zig_args.append(output_path) catch unreachable;
if (self.kind == Kind.Lib and !self.static) {
const output_lib_path = builder.pathFromRoot(self.getOutputLibPath());
zig_args.append("--output-lib") catch unreachable;
zig_args.append(output_lib_path) catch unreachable;
}
if (self.kind != Kind.Exe) {
const output_h_path = self.getOutputHPath();
zig_args.append("--output-h") catch unreachable;

View File

@ -7,12 +7,8 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
cases.addC("example/hello_world/hello_libc.zig");
cases.add("example/cat/main.zig");
cases.add("example/guess_number/main.zig");
if (!is_windows) {
// TODO get this test passing on windows
// See https://github.com/ziglang/zig/issues/538
cases.addBuildFile("example/shared_library/build.zig");
cases.addBuildFile("example/mix_o_files/build.zig");
}
cases.addBuildFile("example/shared_library/build.zig");
cases.addBuildFile("example/mix_o_files/build.zig");
if (builtin.os != builtin.Os.macosx) {
// TODO https://github.com/ziglang/zig/issues/1126
cases.addBuildFile("test/standalone/issue_339/build.zig");