Skip to content

Commit d08c577

Browse files
committed
ability to make a DLL
See #302
1 parent 78b753a commit d08c577

7 files changed

Lines changed: 62 additions & 15 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_S
587587
install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
588588
install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
589589
install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
590+
install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap_lib.zig" DESTINATION "${ZIG_STD_DEST}/special")
590591
install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")
591592
install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
592593
install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")

src/all_types.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,7 @@ struct CodeGen {
14561456
bool have_c_main;
14571457
bool have_winmain;
14581458
bool have_winmain_crt_startup;
1459+
bool have_dllmain_crt_startup;
14591460
bool have_pub_panic;
14601461
Buf *libc_lib_dir;
14611462
Buf *libc_static_lib_dir;

src/analyze.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,6 +3200,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
32003200
buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)
32013201
{
32023202
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;
32033207
}
32043208

32053209
}

src/codegen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5228,6 +5228,9 @@ static void gen_root_source(CodeGen *g) {
52285228
{
52295229
g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
52305230
}
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+
}
52315234
ImportTableEntry *import_with_panic;
52325235
if (g->have_pub_panic) {
52335236
import_with_panic = g->root_import;

src/link.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
372372
// how to handle --target-environ gnu
373373
// These comments are a clue
374374

375+
bool is_library = g->out_type == OutTypeLib;
375376
//bool dll = g->out_type == OutTypeLib;
376377
//bool shared = !g->is_static && dll;
377378
//if (g->is_static) {
@@ -422,13 +423,19 @@ static void construct_linker_job_coff(LinkJob *lj) {
422423
//lj->args.append(get_libc_static_file(g, "crtbegin.o"));
423424
} else {
424425
lj->args.append("-NODEFAULTLIB");
425-
if (g->have_winmain) {
426-
lj->args.append("-ENTRY:WinMain");
427-
} else {
428-
lj->args.append("-ENTRY:WinMainCRTStartup");
426+
if (!is_library) {
427+
if (g->have_winmain) {
428+
lj->args.append("-ENTRY:WinMain");
429+
} else {
430+
lj->args.append("-ENTRY:WinMainCRTStartup");
431+
}
429432
}
430433
}
431434

435+
if (is_library && !g->is_static) {
436+
lj->args.append("-DLL");
437+
}
438+
432439
for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
433440
const char *lib_dir = g->lib_dirs.at(i);
434441
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));

std/build.zig

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,20 @@ pub const Builder = struct {
636636
pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {
637637
return %%fmt_lib.allocPrint(self.allocator, format, args);
638638
}
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+
}
639653
};
640654

641655
const Version = struct {
@@ -685,6 +699,17 @@ const Target = enum {
685699
else => false,
686700
};
687701
}
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+
}
688713
};
689714

690715
pub const LibExeObjStep = struct {
@@ -885,7 +910,7 @@ pub const LibExeObjStep = struct {
885910
self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
886911
},
887912
builtin.Os.windows => {
888-
self.out_filename = self.builder.fmt("lib{}.dll", self.name);
913+
self.out_filename = self.builder.fmt("{}.dll", self.name);
889914
},
890915
else => {
891916
self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
@@ -1200,7 +1225,7 @@ pub const LibExeObjStep = struct {
12001225

12011226
%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()) {
12041229
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
12051230
self.name_only_filename);
12061231
}
@@ -1252,15 +1277,10 @@ pub const LibExeObjStep = struct {
12521277
}
12531278

12541279
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-
};
12621280
const builder = self.builder;
12631281

1282+
const cc = builder.getCCExe();
1283+
12641284
assert(!self.is_zig);
12651285

12661286
var cc_args = ArrayList([]const u8).init(builder.allocator);
@@ -1390,8 +1410,10 @@ pub const LibExeObjStep = struct {
13901410

13911411
%return builder.spawnChild(cc_args.toSliceConst());
13921412

1393-
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1394-
self.name_only_filename);
1413+
if (self.target.wantSharedLibSymLinks()) {
1414+
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1415+
self.name_only_filename);
1416+
}
13951417
}
13961418
},
13971419
Kind.Exe => {

std/special/bootstrap_lib.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// This file is included in the compilation unit when exporting a library on windows.
2+
3+
const std = @import("std");
4+
5+
export 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+
}

0 commit comments

Comments
 (0)