Skip to content

Commit c400cb4

Browse files
committed
zig build system: add setLinkerScript and setTarget
* See #204 - zig build system * allow builtin types Os, Environ, Arch to be used at runtime. they have zero_bits=false and debug info now. * Eradicate use of `@alloca` in std for syscalls. See #225 * add `std.io.writeFile` * `std.debug.panic` adds a newline to format
1 parent a1363b5 commit c400cb4

File tree

10 files changed

+374
-148
lines changed

10 files changed

+374
-148
lines changed

src/all_types.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ struct TypeTableEntryEnum {
944944
AstNode *decl_node;
945945
ContainerLayout layout;
946946
uint32_t src_field_count;
947+
// number of fields in the union. 0 if enum with no payload
947948
uint32_t gen_field_count;
948949
TypeEnumField *fields;
949950
bool is_invalid; // true if any fields are invalid

src/codegen.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,35 @@ static const GlobalLinkageValue global_linkage_values[] = {
38023802
{GlobalLinkageIdLinkOnce, "LinkOnce"},
38033803
};
38043804

3805+
static void init_enum_debug_info(CodeGen *g, TypeTableEntry *enum_type) {
3806+
uint32_t field_count = enum_type->data.enumeration.src_field_count;
3807+
3808+
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3809+
enum_type->data.enumeration.tag_type = tag_type_entry;
3810+
3811+
ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
3812+
for (uint32_t i = 0; i < field_count; i += 1) {
3813+
TypeEnumField *field = &enum_type->data.enumeration.fields[i];
3814+
di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field->name), i);
3815+
}
3816+
3817+
// create debug type for tag
3818+
uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
3819+
uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref);
3820+
enum_type->di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
3821+
nullptr, buf_ptr(&enum_type->name),
3822+
nullptr, 0,
3823+
tag_debug_size_in_bits,
3824+
tag_debug_align_in_bits,
3825+
di_enumerators, field_count,
3826+
tag_type_entry->di_type, "");
3827+
3828+
enum_type->type_ref = tag_type_entry->type_ref;
3829+
3830+
enum_type->data.enumeration.complete = true;
3831+
enum_type->data.enumeration.zero_bits_known = true;
3832+
}
3833+
38053834
static void define_builtin_types(CodeGen *g) {
38063835
{
38073836
// if this type is anywhere in the AST, we should never hit codegen.
@@ -4022,7 +4051,6 @@ static void define_builtin_types(CodeGen *g) {
40224051

40234052
{
40244053
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4025-
entry->zero_bits = true; // only allowed at compile time
40264054
buf_init_from_str(&entry->name, "Os");
40274055
uint32_t field_count = target_os_count();
40284056
entry->data.enumeration.src_field_count = field_count;
@@ -4038,19 +4066,15 @@ static void define_builtin_types(CodeGen *g) {
40384066
g->target_os_index = i;
40394067
}
40404068
}
4041-
entry->data.enumeration.complete = true;
4042-
entry->data.enumeration.zero_bits_known = true;
40434069

4044-
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
4045-
entry->data.enumeration.tag_type = tag_type_entry;
4070+
init_enum_debug_info(g, entry);
40464071

40474072
g->builtin_types.entry_os_enum = entry;
40484073
g->primitive_type_table.put(&entry->name, entry);
40494074
}
40504075

40514076
{
40524077
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4053-
entry->zero_bits = true; // only allowed at compile time
40544078
buf_init_from_str(&entry->name, "Arch");
40554079
uint32_t field_count = target_arch_count();
40564080
entry->data.enumeration.src_field_count = field_count;
@@ -4072,19 +4096,15 @@ static void define_builtin_types(CodeGen *g) {
40724096
g->target_arch_index = i;
40734097
}
40744098
}
4075-
entry->data.enumeration.complete = true;
4076-
entry->data.enumeration.zero_bits_known = true;
40774099

4078-
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
4079-
entry->data.enumeration.tag_type = tag_type_entry;
4100+
init_enum_debug_info(g, entry);
40804101

40814102
g->builtin_types.entry_arch_enum = entry;
40824103
g->primitive_type_table.put(&entry->name, entry);
40834104
}
40844105

40854106
{
40864107
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4087-
entry->zero_bits = true; // only allowed at compile time
40884108
buf_init_from_str(&entry->name, "Environ");
40894109
uint32_t field_count = target_environ_count();
40904110
entry->data.enumeration.src_field_count = field_count;
@@ -4100,19 +4120,15 @@ static void define_builtin_types(CodeGen *g) {
41004120
g->target_environ_index = i;
41014121
}
41024122
}
4103-
entry->data.enumeration.complete = true;
4104-
entry->data.enumeration.zero_bits_known = true;
41054123

4106-
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
4107-
entry->data.enumeration.tag_type = tag_type_entry;
4124+
init_enum_debug_info(g, entry);
41084125

41094126
g->builtin_types.entry_environ_enum = entry;
41104127
g->primitive_type_table.put(&entry->name, entry);
41114128
}
41124129

41134130
{
41144131
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4115-
entry->zero_bits = true; // only allowed at compile time
41164132
buf_init_from_str(&entry->name, "ObjectFormat");
41174133
uint32_t field_count = target_oformat_count();
41184134
entry->data.enumeration.src_field_count = field_count;
@@ -4128,11 +4144,8 @@ static void define_builtin_types(CodeGen *g) {
41284144
g->target_oformat_index = i;
41294145
}
41304146
}
4131-
entry->data.enumeration.complete = true;
4132-
entry->data.enumeration.zero_bits_known = true;
41334147

4134-
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
4135-
entry->data.enumeration.tag_type = tag_type_entry;
4148+
init_enum_debug_info(g, entry);
41364149

41374150
g->builtin_types.entry_oformat_enum = entry;
41384151
g->primitive_type_table.put(&entry->name, entry);

std/build.zig

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub const Builder = struct {
3232
*exe = Exe {
3333
.root_src = root_src,
3434
.name = name,
35+
.target = Target.Native,
36+
.linker_script = LinkerScript.None,
3537
};
3638
%return self.exe_list.append(exe);
3739
return exe;
@@ -53,9 +55,43 @@ pub const Builder = struct {
5355

5456
%return zig_args.append("build_exe"[0...]); // TODO issue #296
5557
%return zig_args.append(exe.root_src);
58+
59+
if (verbose) {
60+
%return zig_args.append("--verbose"[0...]); // TODO issue #296
61+
}
62+
5663
%return zig_args.append("--name"[0...]); // TODO issue #296
5764
%return zig_args.append(exe.name);
5865

66+
switch (exe.target) {
67+
Target.Native => {},
68+
Target.Cross => |cross_target| {
69+
%return zig_args.append("--target-arch"[0...]); // TODO issue #296
70+
%return zig_args.append(targetArchName(cross_target.arch));
71+
72+
%return zig_args.append("--target-os"[0...]); // TODO issue #296
73+
%return zig_args.append(targetOsName(cross_target.os));
74+
75+
%return zig_args.append("--target-environ"[0...]); // TODO issue #296
76+
%return zig_args.append(targetEnvironName(cross_target.environ));
77+
},
78+
}
79+
80+
switch (exe.linker_script) {
81+
LinkerScript.None => {},
82+
LinkerScript.Embed => |script| {
83+
const tmp_file_name = "linker.ld.tmp"; // TODO issue #298
84+
io.writeFile(tmp_file_name, script, self.allocator)
85+
%% |err| debug.panic("unable to write linker script: {}\n", @errorName(err));
86+
%return zig_args.append("--linker-script"[0...]); // TODO issue #296
87+
%return zig_args.append(tmp_file_name[0...]); // TODO issue #296
88+
},
89+
LinkerScript.Path => |path| {
90+
%return zig_args.append("--linker-script"[0...]); // TODO issue #296
91+
%return zig_args.append(path);
92+
},
93+
}
94+
5995
printInvocation(self.zig_exe, zig_args);
6096
var child = %return os.ChildProcess.spawn(self.zig_exe, zig_args.toSliceConst(), os.environ,
6197
StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator);
@@ -72,9 +108,48 @@ pub const Builder = struct {
72108
}
73109
};
74110

111+
const CrossTarget = struct {
112+
arch: Arch,
113+
os: Os,
114+
environ: Environ,
115+
};
116+
117+
const Target = enum {
118+
Native,
119+
Cross: CrossTarget,
120+
};
121+
122+
const LinkerScript = enum {
123+
None,
124+
Embed: []const u8,
125+
Path: []const u8,
126+
};
127+
75128
const Exe = struct {
76129
root_src: []const u8,
77130
name: []const u8,
131+
target: Target,
132+
linker_script: LinkerScript,
133+
134+
fn setTarget(self: &Exe, target_arch: Arch, target_os: Os, target_environ: Environ) {
135+
self.target = Target.Cross {
136+
CrossTarget {
137+
.arch = target_arch,
138+
.os = target_os,
139+
.environ = target_environ,
140+
}
141+
};
142+
}
143+
144+
/// Exe keeps a reference to script for its lifetime or until this function
145+
/// is called again.
146+
fn setLinkerScriptContents(self: &Exe, script: []const u8) {
147+
self.linker_script = LinkerScript.Embed { script };
148+
}
149+
150+
fn setLinkerScriptPath(self: &Exe, path: []const u8) {
151+
self.linker_script = LinkerScript.Path { path };
152+
}
78153
};
79154

80155
fn handleErr(err: error) -> noreturn {
@@ -88,3 +163,130 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) {
88163
}
89164
%%io.stderr.printf("\n");
90165
}
166+
167+
// TODO issue #299
168+
fn targetOsName(target_os: Os) -> []const u8 {
169+
return switch (target_os) {
170+
Os.freestanding => ([]const u8)("freestanding"),
171+
Os.cloudabi => ([]const u8)("cloudabi"),
172+
Os.darwin => ([]const u8)("darwin"),
173+
Os.dragonfly => ([]const u8)("dragonfly"),
174+
Os.freebsd => ([]const u8)("freebsd"),
175+
Os.ios => ([]const u8)("ios"),
176+
Os.kfreebsd => ([]const u8)("kfreebsd"),
177+
Os.linux => ([]const u8)("linux"),
178+
Os.lv2 => ([]const u8)("lv2"),
179+
Os.macosx => ([]const u8)("macosx"),
180+
Os.netbsd => ([]const u8)("netbsd"),
181+
Os.openbsd => ([]const u8)("openbsd"),
182+
Os.solaris => ([]const u8)("solaris"),
183+
Os.windows => ([]const u8)("windows"),
184+
Os.haiku => ([]const u8)("haiku"),
185+
Os.minix => ([]const u8)("minix"),
186+
Os.rtems => ([]const u8)("rtems"),
187+
Os.nacl => ([]const u8)("nacl"),
188+
Os.cnk => ([]const u8)("cnk"),
189+
Os.bitrig => ([]const u8)("bitrig"),
190+
Os.aix => ([]const u8)("aix"),
191+
Os.cuda => ([]const u8)("cuda"),
192+
Os.nvcl => ([]const u8)("nvcl"),
193+
Os.amdhsa => ([]const u8)("amdhsa"),
194+
Os.ps4 => ([]const u8)("ps4"),
195+
Os.elfiamcu => ([]const u8)("elfiamcu"),
196+
Os.tvos => ([]const u8)("tvos"),
197+
Os.watchos => ([]const u8)("watchos"),
198+
Os.mesa3d => ([]const u8)("mesa3d"),
199+
};
200+
}
201+
202+
// TODO issue #299
203+
fn targetArchName(target_arch: Arch) -> []const u8 {
204+
return switch (target_arch) {
205+
Arch.armv8_2a => ([]const u8)("armv8_2a"),
206+
Arch.armv8_1a => ([]const u8)("armv8_1a"),
207+
Arch.armv8 => ([]const u8)("armv8"),
208+
Arch.armv8m_baseline => ([]const u8)("armv8m_baseline"),
209+
Arch.armv8m_mainline => ([]const u8)("armv8m_mainline"),
210+
Arch.armv7 => ([]const u8)("armv7"),
211+
Arch.armv7em => ([]const u8)("armv7em"),
212+
Arch.armv7m => ([]const u8)("armv7m"),
213+
Arch.armv7s => ([]const u8)("armv7s"),
214+
Arch.armv7k => ([]const u8)("armv7k"),
215+
Arch.armv6 => ([]const u8)("armv6"),
216+
Arch.armv6m => ([]const u8)("armv6m"),
217+
Arch.armv6k => ([]const u8)("armv6k"),
218+
Arch.armv6t2 => ([]const u8)("armv6t2"),
219+
Arch.armv5 => ([]const u8)("armv5"),
220+
Arch.armv5te => ([]const u8)("armv5te"),
221+
Arch.armv4t => ([]const u8)("armv4t"),
222+
Arch.armeb => ([]const u8)("armeb"),
223+
Arch.aarch64 => ([]const u8)("aarch64"),
224+
Arch.aarch64_be => ([]const u8)("aarch64_be"),
225+
Arch.avr => ([]const u8)("avr"),
226+
Arch.bpfel => ([]const u8)("bpfel"),
227+
Arch.bpfeb => ([]const u8)("bpfeb"),
228+
Arch.hexagon => ([]const u8)("hexagon"),
229+
Arch.mips => ([]const u8)("mips"),
230+
Arch.mipsel => ([]const u8)("mipsel"),
231+
Arch.mips64 => ([]const u8)("mips64"),
232+
Arch.mips64el => ([]const u8)("mips64el"),
233+
Arch.msp430 => ([]const u8)("msp430"),
234+
Arch.powerpc => ([]const u8)("powerpc"),
235+
Arch.powerpc64 => ([]const u8)("powerpc64"),
236+
Arch.powerpc64le => ([]const u8)("powerpc64le"),
237+
Arch.r600 => ([]const u8)("r600"),
238+
Arch.amdgcn => ([]const u8)("amdgcn"),
239+
Arch.sparc => ([]const u8)("sparc"),
240+
Arch.sparcv9 => ([]const u8)("sparcv9"),
241+
Arch.sparcel => ([]const u8)("sparcel"),
242+
Arch.s390x => ([]const u8)("s390x"),
243+
Arch.tce => ([]const u8)("tce"),
244+
Arch.thumb => ([]const u8)("thumb"),
245+
Arch.thumbeb => ([]const u8)("thumbeb"),
246+
Arch.i386 => ([]const u8)("i386"),
247+
Arch.x86_64 => ([]const u8)("x86_64"),
248+
Arch.xcore => ([]const u8)("xcore"),
249+
Arch.nvptx => ([]const u8)("nvptx"),
250+
Arch.nvptx64 => ([]const u8)("nvptx64"),
251+
Arch.le32 => ([]const u8)("le32"),
252+
Arch.le64 => ([]const u8)("le64"),
253+
Arch.amdil => ([]const u8)("amdil"),
254+
Arch.amdil64 => ([]const u8)("amdil64"),
255+
Arch.hsail => ([]const u8)("hsail"),
256+
Arch.hsail64 => ([]const u8)("hsail64"),
257+
Arch.spir => ([]const u8)("spir"),
258+
Arch.spir64 => ([]const u8)("spir64"),
259+
Arch.kalimbav3 => ([]const u8)("kalimbav3"),
260+
Arch.kalimbav4 => ([]const u8)("kalimbav4"),
261+
Arch.kalimbav5 => ([]const u8)("kalimbav5"),
262+
Arch.shave => ([]const u8)("shave"),
263+
Arch.lanai => ([]const u8)("lanai"),
264+
Arch.wasm32 => ([]const u8)("wasm32"),
265+
Arch.wasm64 => ([]const u8)("wasm64"),
266+
Arch.renderscript32 => ([]const u8)("renderscript32"),
267+
Arch.renderscript64 => ([]const u8)("renderscript64"),
268+
};
269+
}
270+
271+
// TODO issue #299
272+
fn targetEnvironName(target_environ: Environ) -> []const u8 {
273+
return switch (target_environ) {
274+
Environ.gnu => ([]const u8)("gnu"),
275+
Environ.gnuabi64 => ([]const u8)("gnuabi64"),
276+
Environ.gnueabi => ([]const u8)("gnueabi"),
277+
Environ.gnueabihf => ([]const u8)("gnueabihf"),
278+
Environ.gnux32 => ([]const u8)("gnux32"),
279+
Environ.code16 => ([]const u8)("code16"),
280+
Environ.eabi => ([]const u8)("eabi"),
281+
Environ.eabihf => ([]const u8)("eabihf"),
282+
Environ.android => ([]const u8)("android"),
283+
Environ.musl => ([]const u8)("musl"),
284+
Environ.musleabi => ([]const u8)("musleabi"),
285+
Environ.musleabihf => ([]const u8)("musleabihf"),
286+
Environ.msvc => ([]const u8)("msvc"),
287+
Environ.itanium => ([]const u8)("itanium"),
288+
Environ.cygnus => ([]const u8)("cygnus"),
289+
Environ.amdopencl => ([]const u8)("amdopencl"),
290+
Environ.coreclr => ([]const u8)("coreclr"),
291+
};
292+
}

std/debug.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub coldcc fn panic(comptime format: []const u8, args: ...) -> noreturn {
2828
panicking = true;
2929
}
3030

31-
%%io.stderr.printf(format, args);
31+
%%io.stderr.printf(format ++ "\n", args);
3232
%%printStackTrace();
3333

3434
os.abort();
@@ -52,8 +52,8 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
5252
.compile_unit_list = List(CompileUnit).init(&global_allocator),
5353
};
5454
const st = &stack_trace;
55-
%return io.openSelfExe(&st.self_exe_stream);
56-
defer st.self_exe_stream.close() %% {};
55+
st.self_exe_stream = %return io.openSelfExe();
56+
defer st.self_exe_stream.close();
5757

5858
%return st.elf.openStream(&global_allocator, &st.self_exe_stream);
5959
defer st.elf.close();

0 commit comments

Comments
 (0)