diff --git a/CMakeLists.txt b/CMakeLists.txt index e65a14e..708b224 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,3 +50,4 @@ target_link_libraries(bb PUBLIC llvm_bindings) add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Werror -Wno-c99-extensions -Wno-unused-function -Wno-missing-designated-field-initializers -funsigned-char -fwrapv -fno-strict-aliasing) add_compile_definitions(CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}") +add_compile_definitions(BB_CI=${BB_CI}) diff --git a/generate.sh b/generate.sh index 2ab0b3f..890ae49 100755 --- a/generate.sh +++ b/generate.sh @@ -4,6 +4,7 @@ set -eu if [[ -z "${BB_CI:-}" ]]; then CMAKE_BUILD_TYPE=Debug LLVM_CMAKE_BUILD_TYPE=Release + BB_CI=0 else LLVM_CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE fi @@ -47,5 +48,5 @@ if [[ -n "${BB_CI+x}" ]]; then echo $LLVM_PREFIX_PATH fi -cmake .. -G Ninja -DCMAKE_C_COMPILER=$CLANG_PATH -DCMAKE_CXX_COMPILER=$CLANGXX_PATH -DCMAKE_LINKER_TYPE=$LINKER_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_PREFIX_PATH=$LLVM_PREFIX_PATH -DCMAKE_COLOR_DIAGNOSTICS=ON +cmake .. -G Ninja -DCMAKE_C_COMPILER=$CLANG_PATH -DCMAKE_CXX_COMPILER=$CLANGXX_PATH -DCMAKE_LINKER_TYPE=$LINKER_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_PREFIX_PATH=$LLVM_PREFIX_PATH -DCMAKE_COLOR_DIAGNOSTICS=ON -DBB_CI=$BB_CI cd .. diff --git a/src/compiler.bbb b/src/compiler.bbb index 2aa9a77..1a608c1 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -832,6 +832,42 @@ LLVMIntrinsicIndex = enum va_copy, } +[extern] LLVMInitializeX86TargetInfo = fn [cc(c)] () void; +[extern] LLVMInitializeX86Target = fn [cc(c)] () void; +[extern] LLVMInitializeX86TargetMC = fn [cc(c)] () void; +[extern] LLVMInitializeX86AsmPrinter = fn [cc(c)] () void; +[extern] LLVMInitializeX86AsmParser = fn [cc(c)] () void; +[extern] LLVMInitializeX86Disassembler = fn [cc(c)] () void; + +[extern] llvm_default_target_triple = fn [cc(c)] () []u8; +[extern] llvm_host_cpu_name = fn [cc(c)] () []u8; +[extern] llvm_host_cpu_features = fn [cc(c)] () []u8; + +host_triple: []u8 = zero; +host_cpu_model: []u8 = zero; +host_cpu_features: []u8 = zero; + +llvm_targets_initialized: u1 = 0; + +llvm_initialize_targets = fn () void +{ + if (!llvm_targets_initialized) + { + LLVMInitializeX86TargetInfo(); + LLVMInitializeX86Target(); + LLVMInitializeX86TargetMC(); + LLVMInitializeX86AsmPrinter(); + LLVMInitializeX86AsmParser(); + LLVMInitializeX86Disassembler(); + + host_triple = llvm_default_target_triple(); + host_cpu_model = llvm_host_cpu_name(); + host_cpu_features = llvm_host_cpu_features(); + + llvm_targets_initialized = 1; + } +} + [extern] LLVMContextCreate = fn [cc(c)] () &LLVMContext; ModuleLLVM = struct @@ -2614,6 +2650,7 @@ parse = fn (module: &Module) void emit = fn (module: &Module) void { + llvm_initialize_targets(); >context = LLVMContextCreate(); } diff --git a/src/compiler.cpp b/src/compiler.cpp index 241d9d9..88080c0 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -179,9 +179,8 @@ fn String compile_file(Arena* arena, Compile options) }; Slice object_slice = array_to_slice(objects); - String c_abi_libraries[] = { - string_literal("build/libc_abi.a"), - }; + String c_abi_library = string_literal("build/libc_abi.a"); + String llvm_bindings_library = string_literal("build/libllvm_bindings.a"); Slice library_names = {}; Slice library_paths = {}; String library_buffer[256]; @@ -199,6 +198,7 @@ fn String compile_file(Arena* arena, Compile options) builder.add(arena, arena_join_string(arena, array_to_slice(llvm_config_parts))); builder.add("--libdir"); builder.add("--libs"); + builder.add("--system-libs"); auto arguments = builder.flush(); auto llvm_config = os_execute(arena, arguments, environment, { .policies = { ExecuteStandardStreamPolicy::pipe, ExecuteStandardStreamPolicy::ignore }, @@ -226,43 +226,73 @@ fn String compile_file(Arena* arena, Compile options) { report_error(); } - if (line != stream.length - 1) - { - report_error(); - } - auto library_list = stream(0, line); + auto llvm_library_stream = stream(0, line); + + stream = stream(line + 1); + u64 library_count = 0; while (1) { - auto space = string_first_character(library_list, ' '); + auto space = string_first_character(llvm_library_stream, ' '); if (space == string_no_match) { - auto library_argument = library_list(2); + auto library_argument = llvm_library_stream; + library_buffer[library_count] = library_argument(2); + library_count += 1; + break; + } + + // Omit the first two characters: "-l" + auto 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); + auto system_library_stream = stream(0, line); + + while (1) + { + auto space = string_first_character(system_library_stream, ' '); + if (space == string_no_match) + { + auto library_argument = system_library_stream(2); library_buffer[library_count] = library_argument; library_count += 1; break; } + // Omit the first two characters: "-l" - auto library_argument = library_list(2, space); + auto library_argument = system_library_stream(2, space); library_buffer[library_count] = library_argument; library_count += 1; - library_list = library_list(space + 1); + system_library_stream = system_library_stream(space + 1); } library_buffer[library_count] = string_literal("gcc"); library_count += 1; library_buffer[library_count] = string_literal("gcc_s"); library_count += 1; - library_buffer[library_count] = string_literal("m"); + + library_buffer[library_count] = string_literal("lldCommon"); + library_count += 1; + library_buffer[library_count] = string_literal("lldELF"); library_count += 1; library_names = { library_buffer, library_count }; + library_paths = { &llvm_bindings_library, 1 }; } else if (base_name.equal(string_literal("c_abi"))) { - library_paths = array_to_slice(c_abi_libraries); + library_paths = { &c_abi_library, 1 }; } compile(arena, { @@ -564,6 +594,7 @@ void entry_point(Slice arguments, Slice envp) .silent = true, }); +#if BB_DEBUG == 0 || BB_CI == 0 for (auto name: names) { BuildMode build_mode = BuildMode::debug_none; @@ -592,6 +623,7 @@ void entry_point(Slice arguments, Slice envp) } break; } +#endif } } } break;