diff --git a/src/compiler.bbb b/src/compiler.bbb index ace2f3d..1ed4075 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -101,6 +101,29 @@ assert = macro (ok: u1) void } } +ArgumentBuilder = struct +{ + buffer: [128]&u8, + count: u64, +} + +add_argument = fn (builder: &ArgumentBuilder, argument: []u8) void +{ + assert(argument.pointer[argument.length] == 0); + >index = builder.count; + assert(index < builder.buffer.length); + builder.buffer[index] = argument.pointer; + builder.count = index + 1; +} + +flush_arguments = fn (builder: &ArgumentBuilder) []&u8 +{ + >argument_count = builder.count; + assert(argument_count < builder.buffer.length); + builder.buffer[argument_count] = zero; + return builder.buffer[..argument_count]; +} + align_forward = fn (value: u64, alignment: u64) u64 { assert(alignment != 0); @@ -154,6 +177,22 @@ string_equal = fn(a: []u8, b: []u8) u1 return result; } +string_first_character = fn (string: []u8, character: u8) u64 +{ + >result = string_no_match; + + for (i: 0..string.length) + { + if (character == string[i]) + { + result = i; + break; + } + } + + return result; +} + string_last_character = fn(string: []u8, character: u8) u64 { >i = string.length; @@ -1727,6 +1766,11 @@ get_byte_size = fn (type: &Type) u64 >result = element_size * element_count; return result; }, + .alias => + { + >result = get_byte_size(type.content.alias.type); + return result; + }, else => { #trap(); @@ -16627,29 +16671,6 @@ generate_object = fn (module: &LLVMModule, target_machine: &LLVMTargetMachine, o return result; } -ArgumentBuilder = struct -{ - buffer: [128]&u8, - count: u64, -} - -add_argument = fn (builder: &ArgumentBuilder, argument: []u8) void -{ - assert(argument.pointer[argument.length] == 0); - >index = builder.count; - assert(index < builder.buffer.length); - builder.buffer[index] = argument.pointer; - builder.count = index + 1; -} - -flush_arguments = fn (builder: &ArgumentBuilder) []&u8 -{ - >argument_count = builder.count; - assert(argument_count < builder.buffer.length); - builder.buffer[argument_count] = zero; - return builder.buffer[..argument_count]; -} - link = fn (module: &Module) void { >arena = module.arena; @@ -17824,7 +17845,7 @@ compile = fn (arena: &Arena, options: CompileOptions) void emit(&module); } -compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8 +compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8 { >relative_file_path = compile_options.relative_file_path; if (relative_file_path.length < 5) @@ -17901,7 +17922,113 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8 if (is_compiler) { - #trap(); + >builder: ArgumentBuilder = zero; + + add_argument(&builder, "/home/david/dev/llvm/install/llvm_20.1.3_x86_64-linux-Release/bin/llvm-config"); + add_argument(&builder, "--libdir"); + add_argument(&builder, "--libs"); + add_argument(&builder, "--system-libs"); + + >arguments = flush_arguments(&builder); + + >llvm_config = os_execute(arena, arguments, envp, { + .policies = [ .pipe, .ignore ], + zero, + }); + + >success = llvm_config.termination_kind == .exit and llvm_config.termination_code == 0; + + if (!success) + { + report_error(); + } + + >stream = llvm_config.streams[0]; + + >line = string_first_character(stream, '\n'); + + if (line == string_no_match) + { + report_error(); + } + + library_directory = stream[..line]; + library_directories = { .pointer = &library_directory, .length = 1 }; + + stream = stream[line + 1..]; + + line = string_first_character(stream, '\n'); + if (line == string_no_match) + { + report_error(); + } + + >llvm_library_stream = stream[..line]; + + stream = stream[line + 1..]; + + >library_count: u64 = 0; + + while (1) + { + >space = string_first_character(llvm_library_stream, ' '); + if (space == string_no_match) + { + >library_argument = llvm_library_stream; + library_buffer[library_count] = library_argument[2..]; + library_count += 1; + break; + } + + // Omit the first two characters: "-l" + >library_argument = llvm_library_stream[2..space]; + library_buffer[library_count] = library_argument; + library_count += 1; + llvm_library_stream = llvm_library_stream[space + 1..]; + } + + line = string_first_character(stream, '\n'); + if (line == string_no_match) + { + report_error(); + } + + assert(line == stream.length - 1); + + >system_library_stream = stream[..line]; + + while (1) + { + >space = string_first_character(system_library_stream, ' '); + if (space == string_no_match) + { + >library_argument = llvm_library_stream; + library_buffer[library_count] = library_argument[2..]; + library_count += 1; + break; + } + + // Omit the first two characters: "-l" + >library_argument = system_library_stream[2..space]; + library_buffer[library_count] = library_argument; + library_count += 1; + system_library_stream = system_library_stream[space + 1..]; + } + + library_buffer[library_count] = "gcc"; + library_count += 1; + + library_buffer[library_count] = "gcc_s"; + library_count += 1; + + library_buffer[library_count] = "lldCommon"; + library_count += 1; + + library_buffer[library_count] = "lldELF"; + library_count += 1; + + library_names = library_buffer[..library_count]; + library_paths = { .pointer = &llvm_bindings_library, .length = 1 }; } else if (string_equal(base_name, "c_abi")) { @@ -18125,7 +18252,7 @@ names: [_][]u8 = .build_mode = build_mode, .has_debug_info = has_debug_info, .silent = 0, - }); + }, envp); }, .test => { @@ -18149,7 +18276,7 @@ names: [_][]u8 = .build_mode = build_mode, .has_debug_info = has_debug_info, .silent = 1, - }); + }, envp); >arguments: [_]&u8 = [ executable_path.pointer,