Skip to content

Commit 1bd51dd

Browse files
committed
compiler: Support building FreeBSD Scrt1.o and stub shared libraries.
Only works for FreeBSD 14+. Note that we still default to targeting FreeBSD 13. Contributes to ziglang#2876.
1 parent 97f4bcd commit 1bd51dd

File tree

4 files changed

+1165
-2
lines changed

4 files changed

+1165
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ set(ZIG_STAGE2_SOURCES
586586
src/codegen/spirv/spec.zig
587587
src/crash_report.zig
588588
src/dev.zig
589+
src/libs/freebsd.zig
589590
src/libs/glibc.zig
590591
src/introspect.zig
591592
src/libs/libcxx.zig

src/Compilation.zig

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const build_options = @import("build_options");
2323
const LibCInstallation = std.zig.LibCInstallation;
2424
const glibc = @import("libs/glibc.zig");
2525
const musl = @import("libs/musl.zig");
26+
const freebsd = @import("libs/freebsd.zig");
2627
const mingw = @import("libs/mingw.zig");
2728
const libunwind = @import("libs/libunwind.zig");
2829
const libcxx = @import("libs/libcxx.zig");
@@ -248,6 +249,7 @@ compiler_rt_obj: ?CrtFile = null,
248249
fuzzer_lib: ?CrtFile = null,
249250

250251
glibc_so_files: ?glibc.BuiltSharedObjects = null,
252+
freebsd_so_files: ?freebsd.BuiltSharedObjects = null,
251253
wasi_emulated_libs: []const wasi_libc.CrtFile,
252254

253255
/// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source,
@@ -294,12 +296,14 @@ const QueuedJobs = struct {
294296
update_builtin_zig: bool,
295297
musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false),
296298
glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false),
299+
freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false),
297300
/// one of WASI libc static objects
298301
wasi_libc_crt_file: [@typeInfo(wasi_libc.CrtFile).@"enum".fields.len]bool = @splat(false),
299302
/// one of the mingw-w64 static objects
300303
mingw_crt_file: [@typeInfo(mingw.CrtFile).@"enum".fields.len]bool = @splat(false),
301304
/// all of the glibc shared objects
302305
glibc_shared_objects: bool = false,
306+
freebsd_shared_objects: bool = false,
303307
/// libunwind.a, usually needed when linking libc
304308
libunwind: bool = false,
305309
libcxx: bool = false,
@@ -789,6 +793,8 @@ pub const MiscTask = enum {
789793
glibc_crt_file,
790794
glibc_shared_objects,
791795
musl_crt_file,
796+
freebsd_crt_file,
797+
freebsd_shared_objects,
792798
mingw_crt_file,
793799
windows_import_lib,
794800
libunwind,
@@ -823,6 +829,9 @@ pub const MiscTask = enum {
823829
@"glibc libc_nonshared.a",
824830
@"glibc shared object",
825831

832+
@"freebsd libc Scrt1.o",
833+
@"freebsd libc shared object",
834+
826835
@"mingw-w64 crt2.o",
827836
@"mingw-w64 dllcrt2.o",
828837
@"mingw-w64 libmingw32.lib",
@@ -1874,6 +1883,16 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18741883

18751884
comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;
18761885
comp.remaining_prelink_tasks += 1;
1886+
} else if (target.isFreeBSDLibC()) {
1887+
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1888+
1889+
if (freebsd.needsCrt0(comp.config.output_mode)) |f| {
1890+
comp.queued_jobs.freebsd_crt_file[@intFromEnum(f)] = true;
1891+
comp.remaining_prelink_tasks += 1;
1892+
}
1893+
1894+
comp.queued_jobs.freebsd_shared_objects = true;
1895+
comp.remaining_prelink_tasks += freebsd.sharedObjectsCount();
18771896
} else if (target.isWasiLibC()) {
18781897
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18791898

@@ -2028,6 +2047,10 @@ pub fn destroy(comp: *Compilation) void {
20282047
glibc_file.deinit(gpa);
20292048
}
20302049

2050+
if (comp.freebsd_so_files) |*freebsd_file| {
2051+
freebsd_file.deinit(gpa);
2052+
}
2053+
20312054
for (comp.c_object_table.keys()) |key| {
20322055
key.destroy(gpa);
20332056
}
@@ -3839,6 +3862,10 @@ fn performAllTheWorkInner(
38393862
comp.link_task_wait_group.spawnManager(buildGlibcSharedObjects, .{ comp, main_progress_node });
38403863
}
38413864

3865+
if (comp.queued_jobs.freebsd_shared_objects) {
3866+
comp.link_task_wait_group.spawnManager(buildFreeBSDSharedObjects, .{ comp, main_progress_node });
3867+
}
3868+
38423869
if (comp.queued_jobs.libunwind) {
38433870
comp.link_task_wait_group.spawnManager(buildLibUnwind, .{ comp, main_progress_node });
38443871
}
@@ -3873,6 +3900,13 @@ fn performAllTheWorkInner(
38733900
}
38743901
}
38753902

3903+
for (0..@typeInfo(freebsd.CrtFile).@"enum".fields.len) |i| {
3904+
if (comp.queued_jobs.freebsd_crt_file[i]) {
3905+
const tag: freebsd.CrtFile = @enumFromInt(i);
3906+
comp.link_task_wait_group.spawnManager(buildFreeBSDCrtFile, .{ comp, tag, main_progress_node });
3907+
}
3908+
}
3909+
38763910
for (0..@typeInfo(wasi_libc.CrtFile).@"enum".fields.len) |i| {
38773911
if (comp.queued_jobs.wasi_libc_crt_file[i]) {
38783912
const tag: wasi_libc.CrtFile = @enumFromInt(i);
@@ -4876,6 +4910,29 @@ fn buildGlibcSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) voi
48764910
}
48774911
}
48784912

4913+
fn buildFreeBSDCrtFile(comp: *Compilation, crt_file: freebsd.CrtFile, prog_node: std.Progress.Node) void {
4914+
if (freebsd.buildCrtFile(comp, crt_file, prog_node)) |_| {
4915+
comp.queued_jobs.freebsd_crt_file[@intFromEnum(crt_file)] = false;
4916+
} else |err| switch (err) {
4917+
error.SubCompilationFailed => return, // error reported already
4918+
else => comp.lockAndSetMiscFailure(.freebsd_crt_file, "unable to build FreeBSD {s}: {s}", .{
4919+
@tagName(crt_file), @errorName(err),
4920+
}),
4921+
}
4922+
}
4923+
4924+
fn buildFreeBSDSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) void {
4925+
if (freebsd.buildSharedObjects(comp, prog_node)) |_| {
4926+
// The job should no longer be queued up since it succeeded.
4927+
comp.queued_jobs.freebsd_shared_objects = false;
4928+
} else |err| switch (err) {
4929+
error.SubCompilationFailed => return, // error reported already
4930+
else => comp.lockAndSetMiscFailure(.freebsd_shared_objects, "unable to build FreeBSD libc shared objects: {s}", .{
4931+
@errorName(err),
4932+
}),
4933+
}
4934+
}
4935+
48794936
fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std.Progress.Node) void {
48804937
if (mingw.buildCrtFile(comp, crt_file, prog_node)) |_| {
48814938
comp.queued_jobs.mingw_crt_file[@intFromEnum(crt_file)] = false;

0 commit comments

Comments
 (0)