Skip to content

Commit 7b0542d

Browse files
committed
build system: consolidate duplicate code and more
* add ability to add assembly files when building an exe, obj, or lib * add implicit cast from `[N]T` to `?[]const T` (closes #343) * remove link_exe and link_lib in favor of allowing build_exe and build_lib support no root zig source file
1 parent 09bc4d6 commit 7b0542d

13 files changed

+322
-693
lines changed

src/all_types.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ struct CodeGen {
12961296
LLVMBuilderRef builder;
12971297
ZigLLVMDIBuilder *dbuilder;
12981298
ZigLLVMDICompileUnit *compile_unit;
1299+
ZigLLVMDIFile *compile_unit_file;
12991300

13001301
ZigList<Buf *> link_libs; // non-libc link libs
13011302
// add -framework [name] args to linker
@@ -1468,6 +1469,7 @@ struct CodeGen {
14681469

14691470
Buf global_asm;
14701471
ZigList<Buf *> link_objects;
1472+
ZigList<Buf *> assembly_files;
14711473

14721474
ZigList<TypeTableEntry *> name_table_enums;
14731475

src/analyze.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,9 +2851,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
28512851
node->data.use.value = result;
28522852
}
28532853

2854-
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2855-
Buf *abs_full_path, Buf *src_dirname, Buf *src_basename, Buf *source_code)
2856-
{
2854+
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) {
28572855
if (g->verbose) {
28582856
fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path));
28592857
fprintf(stderr, "----------------\n");
@@ -2894,7 +2892,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
28942892
ast_print(stderr, import_entry->root, 0);
28952893
}
28962894

2897-
// TODO: assert that src_basename has no '/' in it
2895+
Buf *src_dirname = buf_alloc();
2896+
Buf *src_basename = buf_alloc();
2897+
os_path_split(abs_full_path, src_dirname, src_basename);
2898+
28982899
import_entry->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
28992900
g->import_table.put(abs_full_path, import_entry);
29002901
g->import_queue.append(import_entry);

src/analyze.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ void find_libc_lib_path(CodeGen *g);
4040
bool type_has_bits(TypeTableEntry *type_entry);
4141

4242

43-
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
44-
Buf *abs_full_path, Buf *src_dirname, Buf *src_basename, Buf *source_code);
43+
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
4544

4645

4746
// TODO move these over, these used to be static

src/codegen.cpp

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa
5555
return entry;
5656
}
5757

58-
CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
58+
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) {
5959
CodeGen *g = allocate<CodeGen>(1);
6060

6161
codegen_add_time_event(g, "Initialize");
@@ -81,9 +81,17 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
8181
// reserve index 0 to indicate no error
8282
g->error_decls.append(nullptr);
8383

84-
g->root_package = new_package(buf_ptr(root_source_dir), "");
85-
g->std_package = new_package(ZIG_STD_DIR, "index.zig");
86-
g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
84+
if (root_src_path) {
85+
Buf *src_basename = buf_alloc();
86+
Buf *src_dir = buf_alloc();
87+
os_path_split(root_src_path, src_dir, src_basename);
88+
89+
g->root_package = new_package(buf_ptr(src_dir), buf_ptr(src_basename));
90+
g->std_package = new_package(ZIG_STD_DIR, "index.zig");
91+
g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
92+
} else {
93+
g->root_package = new_package(".", "");
94+
}
8795
g->zig_std_dir = buf_create_from_str(ZIG_STD_DIR);
8896

8997
g->zig_std_special_dir = buf_alloc();
@@ -757,7 +765,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
757765

758766
static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
759767
LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
760-
LLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, "");
768+
ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, LLVMFastCallConv, false, "");
761769
LLVMBuildUnreachable(g->builder);
762770
}
763771

@@ -3655,6 +3663,10 @@ static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const c
36553663
}
36563664

36573665
static void do_code_gen(CodeGen *g) {
3666+
if (g->verbose) {
3667+
fprintf(stderr, "\nCode Generation:\n");
3668+
fprintf(stderr, "------------------\n");
3669+
}
36583670
assert(!g->errors.length);
36593671

36603672
codegen_add_time_event(g, "Code Generation");
@@ -4602,8 +4614,9 @@ static void define_builtin_compile_vars(CodeGen *g) {
46024614
add_compile_var(g, "panic_implementation_provided", create_const_bool(g, false));
46034615
}
46044616

4605-
static void init(CodeGen *g, Buf *source_path) {
4606-
g->module = LLVMModuleCreateWithName(buf_ptr(source_path));
4617+
static void init(CodeGen *g) {
4618+
assert(g->root_out_name);
4619+
g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
46074620

46084621
get_target_triple(&g->triple_str, &g->zig_target);
46094622

@@ -4674,23 +4687,25 @@ static void init(CodeGen *g, Buf *source_path) {
46744687
g->const_void_val.type = g->builtin_types.entry_void;
46754688
}
46764689

4677-
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {
4690+
void codegen_parseh(CodeGen *g, Buf *full_path) {
46784691
find_libc_include_path(g);
4679-
Buf *full_path = buf_alloc();
4680-
os_path_join(src_dirname, src_basename, full_path);
4692+
4693+
Buf *src_basename = buf_alloc();
4694+
Buf *src_dirname = buf_alloc();
4695+
os_path_split(full_path, src_dirname, src_basename);
46814696

46824697
ImportTableEntry *import = allocate<ImportTableEntry>(1);
4683-
import->source_code = source_code;
4698+
import->source_code = nullptr;
46844699
import->path = full_path;
46854700
g->root_import = import;
46864701
import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import);
46874702

4688-
init(g, full_path);
4703+
init(g);
46894704

46904705
import->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
46914706

46924707
ZigList<ErrorMsg *> errors = {0};
4693-
int err = parse_h_buf(import, &errors, source_code, g, nullptr);
4708+
int err = parse_h_file(import, &errors, buf_ptr(full_path), g, nullptr);
46944709
if (err) {
46954710
fprintf(stderr, "unable to parse .h file: %s\n", err_str(err));
46964711
exit(1);
@@ -4719,7 +4734,7 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package
47194734
zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err));
47204735
}
47214736

4722-
return add_source_file(g, package, abs_full_path, g->zig_std_special_dir, code_basename, import_code);
4737+
return add_source_file(g, package, abs_full_path, import_code);
47234738
}
47244739

47254740
static PackageTableEntry *create_bootstrap_pkg(CodeGen *g) {
@@ -4736,23 +4751,27 @@ static PackageTableEntry *create_zigrt_pkg(CodeGen *g) {
47364751
return package;
47374752
}
47384753

4739-
void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *source_code) {
4740-
codegen_add_time_event(g, "Semantic Analysis");
4741-
4742-
Buf source_path = BUF_INIT;
4743-
os_path_join(src_dir, src_basename, &source_path);
4754+
static void gen_root_source(CodeGen *g) {
4755+
if (buf_len(&g->root_package->root_src_path) == 0)
4756+
return;
47444757

4745-
buf_init_from_buf(&g->root_package->root_src_path, src_basename);
4758+
codegen_add_time_event(g, "Semantic Analysis");
47464759

4747-
init(g, &source_path);
4760+
Buf *rel_full_path = buf_alloc();
4761+
os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, rel_full_path);
47484762

47494763
Buf *abs_full_path = buf_alloc();
47504764
int err;
4751-
if ((err = os_path_real(&source_path, abs_full_path))) {
4752-
zig_panic("unable to open '%s': %s", buf_ptr(&source_path), err_str(err));
4765+
if ((err = os_path_real(rel_full_path, abs_full_path))) {
4766+
zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err));
4767+
}
4768+
4769+
Buf *source_code = buf_alloc();
4770+
if ((err = os_fetch_file_path(rel_full_path, source_code))) {
4771+
zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err));
47534772
}
47544773

4755-
g->root_import = add_source_file(g, g->root_package, abs_full_path, src_dir, src_basename, source_code);
4774+
g->root_import = add_source_file(g, g->root_package, abs_full_path, source_code);
47564775

47574776
assert(g->root_out_name);
47584777
assert(g->out_type != OutTypeUnknown);
@@ -4787,27 +4806,33 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
47874806
exit(1);
47884807
}
47894808

4790-
if (g->verbose) {
4791-
fprintf(stderr, "\nCode Generation:\n");
4792-
fprintf(stderr, "------------------\n");
4793-
4794-
}
4795-
4796-
do_code_gen(g);
47974809
}
47984810

4799-
void codegen_add_root_assembly(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *source_code) {
4800-
Buf source_path = BUF_INIT;
4801-
os_path_join(src_dir, src_basename, &source_path);
4811+
void codegen_add_assembly(CodeGen *g, Buf *path) {
4812+
g->assembly_files.append(path);
4813+
}
48024814

4803-
init(g, &source_path);
4815+
static void gen_global_asm(CodeGen *g) {
4816+
Buf contents = BUF_INIT;
4817+
int err;
4818+
for (size_t i = 0; i < g->assembly_files.length; i += 1) {
4819+
Buf *asm_file = g->assembly_files.at(i);
4820+
if ((err = os_fetch_file_path(asm_file, &contents))) {
4821+
zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err));
4822+
}
4823+
if (g->zig_target.arch.arch == ZigLLVM_x86 || g->zig_target.arch.arch == ZigLLVM_x86_64) {
4824+
buf_append_str(&g->global_asm, ".intel_syntax noprefix\n");
4825+
}
4826+
buf_append_buf(&g->global_asm, &contents);
4827+
}
4828+
}
48044829

4805-
assert(g->root_out_name);
4830+
void codegen_build(CodeGen *g) {
48064831
assert(g->out_type != OutTypeUnknown);
4832+
init(g);
48074833

4808-
buf_init_from_str(&g->global_asm, ".intel_syntax noprefix\n");
4809-
buf_append_buf(&g->global_asm, source_code);
4810-
4834+
gen_global_asm(g);
4835+
gen_root_source(g);
48114836
do_code_gen(g);
48124837
}
48134838

src/codegen.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#include <stdio.h>
1616

17-
CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target);
17+
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target);
1818

1919
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
2020
void codegen_set_is_release(CodeGen *codegen, bool is_release);
@@ -49,13 +49,13 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
4949
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
5050
void codegen_add_time_event(CodeGen *g, const char *name);
5151
void codegen_print_timing_report(CodeGen *g, FILE *f);
52+
void codegen_build(CodeGen *g);
5253

5354
PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
54-
void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
55-
void codegen_add_root_assembly(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
55+
void codegen_add_assembly(CodeGen *g, Buf *path);
5656
void codegen_add_object(CodeGen *g, Buf *object_path);
5757

58-
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);
58+
void codegen_parseh(CodeGen *g, Buf *path);
5959
void codegen_render_ast(CodeGen *g, FILE *f, int indent_size);
6060

6161
void codegen_generate_h_file(CodeGen *g);

src/ir.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6043,6 +6043,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
60436043
}
60446044
}
60456045

6046+
// implicit [N]T to ?[]const N
6047+
if (expected_type->id == TypeTableEntryIdMaybe &&
6048+
is_slice(expected_type->data.maybe.child_type) &&
6049+
actual_type->id == TypeTableEntryIdArray)
6050+
{
6051+
TypeTableEntry *ptr_type =
6052+
expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
6053+
assert(ptr_type->id == TypeTableEntryIdPointer);
6054+
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6055+
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6056+
{
6057+
return ImplicitCastMatchResultYes;
6058+
}
6059+
}
6060+
60466061
// implicit number literal to typed number
60476062
// implicit number literal to &const integer
60486063
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
@@ -7093,6 +7108,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
70937108
}
70947109
}
70957110

7111+
// explicit cast from [N]T to ?[]const N
7112+
if (wanted_type->id == TypeTableEntryIdMaybe &&
7113+
is_slice(wanted_type->data.maybe.child_type) &&
7114+
actual_type->id == TypeTableEntryIdArray)
7115+
{
7116+
TypeTableEntry *ptr_type =
7117+
wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
7118+
assert(ptr_type->id == TypeTableEntryIdPointer);
7119+
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
7120+
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
7121+
{
7122+
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
7123+
if (type_is_invalid(cast1->value.type))
7124+
return ira->codegen->invalid_instruction;
7125+
7126+
IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
7127+
if (type_is_invalid(cast2->value.type))
7128+
return ira->codegen->invalid_instruction;
7129+
7130+
return cast2;
7131+
}
7132+
}
7133+
70967134
// explicit cast from []T to []u8 or []u8 to []T
70977135
if (is_slice(wanted_type) && is_slice(actual_type) &&
70987136
(is_u8(wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type) ||
@@ -10880,8 +10918,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi
1088010918
return ira->codegen->builtin_types.entry_invalid;
1088110919
}
1088210920
}
10883-
ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,
10884-
abs_full_path, search_dir, import_target_path, import_code);
10921+
ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, abs_full_path, import_code);
1088510922

1088610923
scan_decls(ira->codegen, target_import->decls_scope, target_import->root);
1088710924

src/link.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {
3333

3434
static Buf *build_o(CodeGen *parent_gen, const char *oname) {
3535
Buf *source_basename = buf_sprintf("%s.zig", oname);
36+
Buf *full_path = buf_alloc();
37+
os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
3638

3739
ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
38-
CodeGen *child_gen = codegen_create(parent_gen->zig_std_special_dir, child_target);
40+
CodeGen *child_gen = codegen_create(full_path, child_target);
3941
child_gen->link_libc = parent_gen->link_libc;
4042

4143
child_gen->link_libs.resize(parent_gen->link_libs.length);
@@ -60,15 +62,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
6062
codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);
6163
codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min);
6264

63-
Buf *full_path = buf_alloc();
64-
os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
65-
66-
Buf source_code = BUF_INIT;
67-
if (os_fetch_file_path(full_path, &source_code)) {
68-
zig_panic("unable to fetch file: %s\n", buf_ptr(full_path));
69-
}
70-
71-
codegen_add_root_code(child_gen, parent_gen->zig_std_special_dir, source_basename, &source_code);
65+
codegen_build(child_gen);
7266
const char *o_ext = target_o_file_ext(&child_gen->zig_target);
7367
Buf *o_out = buf_sprintf("%s%s", oname, o_ext);
7468
codegen_link(child_gen, buf_ptr(o_out));

0 commit comments

Comments
 (0)