diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 19e28bd4a..f070bb0dc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,7 +38,7 @@ jobs: - name: Build testproject run: | cd resources/testproject - ../../build/c3c build --debug-log + ../../build/c3c run --debug-log - name: run compiler tests run: | @@ -73,7 +73,7 @@ jobs: - name: Build testproject run: | cd resources/testproject - ../../build/c3c build --debug-log + ../../build/c3c run --debug-log - name: run compiler tests run: | @@ -118,7 +118,12 @@ jobs: - name: Build testproject run: | cd resources/testproject - ../../build/c3c build --debug-log + ../../build/c3c run --debug-log + + - name: Build testproject direct linker + run: | + cd resources/testproject + ../../build/c3c run --debug-log --forcelinker - name: run compiler tests run: | @@ -150,7 +155,12 @@ jobs: - name: Build testproject run: | cd resources/testproject - ../../build/c3c build --debug-log + ../../build/c3c run --debug-log + + - name: Build testproject direct linker + run: | + cd resources/testproject + ../../build/c3c run --debug-log --forcelinker - name: run compiler tests run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index fb878b4e2..754e17836 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,12 +84,18 @@ llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS}) file(COPY ${CMAKE_SOURCE_DIR}/lib DESTINATION ${CMAKE_BINARY_DIR}) # These don't seem to be reliable on windows. + if(UNIX) message(STATUS "using find_library") # find_library(TB_LIB NAMES tinybackend.a PATHS ${CMAKE_SOURCE_DIR}/resources/tblib) find_library(LLD_COFF NAMES lldCOFF.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS}) find_library(LLD_COMMON NAMES lldCommon.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS}) find_library(LLD_ELF NAMES lldELF.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS}) + if (${LLVM_PACKAGE_VERSION} VERSION_LESS 14) + find_library(LLD_MACHO NAMES lldMachO2.a liblldMachO2.a PATHS ${LLVM_LIBRARY_DIRS}) + else() + find_library(LLD_MACHO NAMES lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS}) + endif() find_library(LLD_MACHO NAMES lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS}) find_library(LLD_MINGW NAMES lldMinGW.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS}) find_library(LLD_WASM NAMES lldWasm.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS}) @@ -113,9 +119,18 @@ if(UNIX) ${LLD_YAML} ${LLD_CORE} ) - message(STATUS "linking to llvm libs ${llvm_libs} ${lld_libs}") -endif() + if(APPLE) + set(lld_libs ${lld_libs} xar) + endif() + message(STATUS "linking to llvm libs ${llvm_libs} ${lld_libs}") +else() + if(${LLVM_PACKAGE_VERSION} VERSION_LESS 14) + set(lld_libs lldCommon lldCore lldCOFF lldWASM lldMinGW lldELF lldDriver lldReaderWriter lldMachO2 lldYAML) + else() + set(lld_libs lldCommon lldCore lldCOFF lldWASM lldMinGW lldELF lldDriver lldReaderWriter lldMachO lldYAML) + endif() +endif() message(STATUS "Found LLD ${lld_libs}") add_library(c3c_wrappers STATIC wrapper/src/wrapper.cpp) @@ -138,6 +153,7 @@ add_executable(c3c src/compiler/float.c src/compiler/headers.c src/compiler/lexer.c + src/compiler/libraries.c src/compiler/linker.c src/compiler/llvm_codegen.c src/compiler/llvm_codegen_c_abi_aarch64.c @@ -196,11 +212,12 @@ add_executable(c3c src/utils/vmem.h src/utils/whereami.c src/compiler/decltable.c + src/compiler/mac_support.c src/compiler/tilde_codegen_storeload.c src/compiler/llvm_codegen_storeload.c src/compiler/tilde_codegen_expr.c src/compiler/tilde_codegen_stmt.c - src/compiler/tilde_codegen_type.c) + src/compiler/tilde_codegen_type.c src/compiler/windows_support.c) if(NOT CMAKE_C_COMPILER_ID STREQUAL "MSVC") message(STATUS "using gcc/clang warning switches") @@ -231,8 +248,8 @@ else() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -LIBPATH:C:\\llvm\\llvm\\build\\Release\\lib") # needed for lldCommon.lib #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -LIBPATH:${LLVM_LIBPATH}") # This doesn't seem to work for some reason message(STATUS "${LLVM_LIBPATH}") - target_link_libraries(c3c debug ${llvm_libs} c3c_wrappers lldCommon lldCore lldCOFF lldWASM lldMinGW lldELF lldDriver lldReaderWriter lldMachO lldYAML Advapi32) - target_link_libraries(c3c optimized ${llvm_libs} c3c_wrappers lldCommon lldCore lldCOFF lldWASM lldMinGW lldELF lldDriver lldReaderWriter lldMachO lldYAML Advapi32) + target_link_libraries(c3c debug ${llvm_libs} c3c_wrappers ${lld_libs} Advapi32) + target_link_libraries(c3c optimized ${llvm_libs} c3c_wrappers ${lld_libs} Advapi32) endif() if (WIN32) diff --git a/resources/testfragments/raylibtest.c3 b/resources/testfragments/raylibtest.c3 new file mode 100644 index 000000000..d6b21dd53 --- /dev/null +++ b/resources/testfragments/raylibtest.c3 @@ -0,0 +1,167 @@ +module foo; +extern fn void printf(char*, ...); + +enum Foo : int (int offset, char* extra_name, double x) +{ + BAZ(12, "hello", 3.0), + BOO(33, "oekfe", 4.0) = 3, +} + +fn void main() +{ + int screenWidth = 800; + int screenHeight = 450; + + raylib::init_window(screenWidth, screenHeight, "raylib [core] example - keyboard input"); + + Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 }; + + raylib::set_target_fps(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + foo2::tester(screenHeight); + // Main game loop + while (!raylib::window_should_close()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (raylib::is_key_down(KeyboardKey.RIGHT)) ballPosition.x += 2.0f; + if (raylib::is_key_down(KeyboardKey.LEFT)) ballPosition.x -= 2.0f; + if (raylib::is_key_down(KeyboardKey.UP)) ballPosition.y -= 2.0f; + if (raylib::is_key_down(KeyboardKey.DOWN)) ballPosition.y += 2.0f; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + raylib::begin_drawing(); + + raylib::clear_background(raylib::RAYWHITE); + + raylib::draw_text("move the ball with arrow keys", 10, 10, 20, raylib::DARKGRAY); + + raylib::draw_circle_v(ballPosition, 50, raylib::MAROON); + + raylib::end_drawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + raylib::close_window(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +} +/* +struct Game +{ + int answer; + bool done; + int guesses; + int high; +} + +int err_count = 0; + + +import "core:bufio" +import "core:fmt" +import "core:io" +import "core:mem" +import "core:os" +import "core:strconv" +import "core:time" +import "core:math/rand" + +Game :: struct { + answer: int, + done: bool, + guesses: int, + high: int, +} + +int err_count = 0; +*/ +/* +fn int ask_guess(int high) +{ + libc::printf("Guess a number between 1 and %d: ", high); + +} +ask_guess :: proc(high: int) -> (result: int, ok: bool) { + fmt.printf("Guess a number between 1 and %d: ", high) + if text, ok := read_line(); ok { + defer mem.delete(text) + return strconv.parse_int(s = text, base = 10) + } + return +} + +ask_guess_multi :: proc(high: int) -> int { + for { + if result, ok := ask_guess(high); ok { + return result + } + fmt.println("I didn't understand") + err_count += 1 + } +} + +pick_answer :: proc(high: int, r: ^rand.Rand) -> int { + return rand.int_max(high, r) + 1 +} + +play :: proc(game: ^Game) { + for !game.done { + guess := ask_guess_multi(game.high) + report(game^, guess) + game^ = update(game^, guess) + } +} + +read_line :: proc() -> (result: string, ok: bool) { + // See also: + // - https://github.com/odin-lang/Odin/issues/1214 + // - https://p.teknik.io/Raw/IT996 + s := os.stream_from_handle(os.stdin) + r: bufio.Reader + bufio.reader_init(&r, io.Reader{s}) + defer bufio.reader_destroy(&r) + if line, err := bufio.reader_read_string(&r, '\n'); err == .None { + return line[:len(line) - 1], true + } + return +} + +report :: proc(game: Game, guess: int) { + // game.done = true + // fmt.println(&game) + description := ( + "too low" if guess < game.answer else + "too high" if guess > game.answer else + "the answer!" + ) + fmt.println(guess, "is", description) +} + +update :: proc(game: Game, guess: int) -> (next: Game) { + next = game + next.done = guess == game.answer + next.guesses += 1 + return +} + +main :: proc() { + high :: 100 + r := rand.create(transmute(u64)time.now()) + // Or use nil for default random. + answer := pick_answer(high, &r) + game := Game {answer = answer, done = false, guesses = 0, high = high} + play(&game) + fmt.println("Finished in", game.guesses, "guesses"); + fmt.println("Total input errors:", err_count) +} +*/ + +module foo2; +fn void tester(int x) +{ + assert(x > 1000, "Shit!"); +} diff --git a/resources/testproject/hello_world.c3 b/resources/testproject/hello_world.c3 index 9e3b61836..0f3e2b635 100644 --- a/resources/testproject/hello_world.c3 +++ b/resources/testproject/hello_world.c3 @@ -9,5 +9,5 @@ fn int main() printf("Hello World!\n"); bar::test(); printf("Hello double: %d\n", test_doubler(11)); - return 1; + return 17; } \ No newline at end of file diff --git a/src/build/build_options.c b/src/build/build_options.c index 9396e4d72..fd19355ce 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -14,6 +14,7 @@ #include #include "../utils/whereami.h" +extern int llvm_version_major; static int arg_index; static int arg_count; @@ -23,30 +24,30 @@ extern const char* llvm_version; extern const char* llvm_target; char *arch_os_target[ARCH_OS_TARGET_LAST + 1] = { - [X86_FREEBSD] = "x86-freebsd", - [X86_OPENBSD] = "x86-openbsd", - [X86_NETBSD] = "x86-netbsd", - [X86_MCU] = "x86-mcu", - [X86_ELF] = "x86-elf", - [X86_WINDOWS] = "x86-windows", - [X86_LINUX] = "x86-linux", - [X64_DARWIN] = "x64-darwin", - [X64_LINUX] = "x64-linux", - [X64_WINDOWS] = "x64-windows", - [X64_WINDOWS_GNU] = "x64-mingw", - [X64_FREEBSD] = "x64-freebsd", - [X64_OPENBSD] = "x64-openbsd", - [X64_NETBSD] = "x64-netbsd", - [X64_ELF] = "x64-elf", - [AARCH64_LINUX] = "aarch64-linux", - [AARCH64_DARWIN] = "aarch64-darwin", - [AARCH64_ELF] = "aarch64-elf", - [RISCV32_LINUX] = "riscv32-linux", - [RISCV32_ELF] = "riscv32-elf", - [RISCV64_LINUX] = "riscv64-linux", - [RISCV64_ELF] = "riscv64-elf", + [WINDOWS_X86] = "windows-x86", + [WINDOWS_X64] = "windows-x64", + [MINGW_X64] = "mingw-x64", + [MACOS_X64] = "macos-x64", + [MACOS_AARCH64] = "macos-aarch64", + [LINUX_X86] = "linux-x86", + [LINUX_X64] = "linux-x64", + [LINUX_AARCH64] = "linux-aarch64", + [LINUX_RISCV32] = "linux-riscv32", + [LINUX_RISCV64] = "linux-riscv64", [WASM32] = "wasm32", [WASM64] = "wasm64", + [ELF_X86] = "elf-x86", + [ELF_X64] = "elf-x64", + [ELF_AARCH64] = "elf-aarch64", + [ELF_RISCV32] = "elf-riscv32", + [ELF_RISCV64] = "elf-riscv64", + [FREEBSD_X86] = "freebsd-x86", + [FREEBSD_X64] = "freebsd-x64", + [OPENBSD_X86] = "openbsd-x86", + [OPENBSD_X64] = "openbsd-x64", + [NETBSD_X86] = "netbsd-x86", + [NETBSD_X64] = "netbsd-x64", + [MCU_X86] = "mcu-x86", }; #define EOUTPUT(string, ...) fprintf(stderr, string "\n", ##__VA_ARGS__) @@ -74,7 +75,8 @@ static void usage(void) OUTPUT("Options:"); OUTPUT(" --tinybackend - Use the TinyBackend for compilation."); OUTPUT(" --stdlib - Use this directory as the C3 standard library path."); - OUTPUT(" --lib - Use this directory as the C3 library path."); + OUTPUT(" --libdir - Add this directory to the C3 library search paths."); + OUTPUT(" --lib - Add this library to the compilation."); OUTPUT(" --path - Use this as the base directory for the current command."); OUTPUT(" --template