diff --git a/build.sh b/build.sh index 49475dc..036208d 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -odin run ./builder -sanitize:address -- $@ +odin run ./builder -- $@ diff --git a/builder/builder.odin b/builder/builder.odin index f1e3732..8e0f9cc 100644 --- a/builder/builder.odin +++ b/builder/builder.odin @@ -3,10 +3,12 @@ package builder import "core:flags" import "core:fmt" import "core:log" +import "core:io" import os "core:os/os2" import "core:path/filepath" import "core:slice" import "core:strings" +import "core:thread" Build_Variant :: enum { Hot_Reload, @@ -15,21 +17,22 @@ Build_Variant :: enum { } Options :: struct { - variant: Build_Variant `usage:"Variant of the build"`, - optimize: bool `args:"name=opt",usage:"Enable compiler optimizations"`, - debug: bool `usage:"Enable debug symbols"`, - rebuild_deps: bool `usage:"When enabled dependencies will be cleaned and rebuilt"`, - tracy: bool `usage:"Enable tracy profiler"`, + variant: Build_Variant `usage:"Variant of the build"`, + optimize: bool `args:"name=opt",usage:"Enable compiler optimizations"`, + debug: bool `usage:"Enable debug symbols"`, + force: bool `usage:"When enabled dependencies will be cleaned and rebuilt"`, + tracy: bool `usage:"Enable tracy profiler"`, + run: bool, } -temp_concat :: proc(left, right: []string) -> []string { - result := slice.concatenate([][]string{left, right}, context.temp_allocator) +temp_concat :: proc(strs: ..[]string) -> []string { + result := slice.concatenate(strs, context.temp_allocator) return result } build_deps :: proc(opts: Options) { log.infof("build_deps") - force := opts.rebuild_deps + force := opts.force shared := opts.variant == .Hot_Reload // Raylib { @@ -59,7 +62,7 @@ build_deps :: proc(opts: Options) { { cwd := "./libs/physfs" file_name := shared ? "libphysfs.so" : "libphysfs.a" - is_built := os.is_file(fmt.tprintf("./libs/physfs/%s", file_name)) + is_built := os.is_dir("./libs/physfs/build") if force { remove_all("./libs/physfs/build") } @@ -72,12 +75,14 @@ build_deps :: proc(opts: Options) { "./physfs", } build_cmd := []string{"cmake", "--build", "build", "--config", "MinSizeRel"} - if opts.variant == .Web { - run_cmd(temp_concat({"emcmake.bat"}, prepare_cmd), cwd) - run_cmd(temp_concat({"emmake.bat"}, build_cmd), cwd) - } else { - run_cmd(prepare_cmd, cwd) - run_cmd(build_cmd, cwd) + if !is_built || force { + if opts.variant == .Web { + run_cmd(temp_concat({"emcmake.bat"}, prepare_cmd), cwd) + run_cmd(temp_concat({"emmake.bat"}, build_cmd), cwd) + } else { + run_cmd(prepare_cmd, cwd) + run_cmd(build_cmd, cwd) + } } } @@ -117,7 +122,7 @@ build_deps :: proc(opts: Options) { "-O2", "vendor/tracy/public/TracyClient.cpp", "-lws2_32", - "-ldbghelp" + "-ldbghelp", }, shared ? {"-shared", "-o", TRACY_NAME_SHARED} : {"-c", "-o", "tracy.o"}, }, @@ -148,7 +153,11 @@ setup_emsdk_env :: proc() { PATH_ENV_DELIMITER :: ":" } - PATHS :: [3]string{"./libs/emsdk/upstream/bin", "./libs/emsdk/upstream/emscripten", "./libs/emsdk/ninja/git-release_64bit/bin"} + PATHS :: [3]string { + "./libs/emsdk/upstream/bin", + "./libs/emsdk/upstream/emscripten", + "./libs/emsdk/ninja/git-release_64bit/bin", + } paths: [len(PATHS)]string for path, i in PATHS { @@ -167,14 +176,12 @@ setup_emsdk_env :: proc() { set_env("EMSDK", absolute_path("./libs/emsdk")) } -archive_assets :: proc() { -} - main :: proc() { context.logger = log.create_console_logger() opts := Options { tracy = true, debug = true, + run = true, } flags.parse_or_exit(&opts, os.args, .Unix, context.temp_allocator) if opts.variant == .Web { @@ -194,26 +201,79 @@ main :: proc() { case .Hot_Reload: remove_all("./build/hotreload") mkdir_all("./build/hotreload") - cmd := slice.concatenate( - [][]string { - []string { - "odin", - "build", - "game", - "-define:RAYLIB_SHARED=true", - "-define:PHYSFS_SHARED=true", - "-build-mode:dll", - "-out:./build/hotreload/game_tmp.so", - }, - tracy_flag, - debug_flag, - optimize_flag, - COMMON_FLAGS, + + is_main_built := os.is_file("./build/hotreload/game.bin") + if !is_main_built || opts.force { + run_cmd( + temp_concat( + []string { + "odin", + "build", + "main_hot_reload", + "-out:./build/hotreload/game.bin", + }, + debug_flag, + tracy_flag, + optimize_flag, + COMMON_FLAGS, + ), + "", + ) + } + build_game_cmd := temp_concat( + []string { + "odin", + "build", + "game", + "-define:RAYLIB_SHARED=true", + "-define:PHYSFS_SHARED=true", + "-build-mode:dll", + "-out:./build/hotreload/game_tmp.so", }, - context.temp_allocator, + tracy_flag, + debug_flag, + optimize_flag, + COMMON_FLAGS, ) - run_cmd(cmd, "") - rename("./build/hotreload/game_tmp.so", "./build/hotreload/game.so") + build_game_lib :: proc(build_cmd: []string) { + run_cmd( + build_cmd, + "", + ) + rename("./build/hotreload/game_tmp.so", "./build/hotreload/game.so") + } + build_game_lib(build_game_cmd) + + if opts.run { + thread_ctx := context + thread_ctx.user_ptr = &build_game_cmd + thrd := thread.create_and_start(proc() { + build_game_cmd := (cast(^[]string)context.user_ptr)^ + input := os.to_reader(os.stdin) + + buf: [1024]u8 + for { + n, err := io.read(input, buf[:]) + + for cmd in buf[0:n] { + switch cmd { + case 'r', 'R': + build_game_lib(build_game_cmd) + case: + } + } + + if err == .EOF { + break + } + + handle_error(err) + } + }, thread_ctx) + + run_cmd({"./build/hotreload/game.bin"}, "") + thread.join(thrd) + } case .Desktop: remove_all("./build/desktop") mkdir_all("./build/desktop") @@ -283,3 +343,4 @@ main :: proc() { ) } } + diff --git a/libs/physfs/physfs.odin b/libs/physfs/physfs.odin index 0c31960..0e40e02 100644 --- a/libs/physfs/physfs.odin +++ b/libs/physfs/physfs.odin @@ -12,9 +12,9 @@ when ODIN_OS == .Windows { } } else when ODIN_OS == .Linux || ODIN_OS == .Darwin { when PHYSFS_SHARED { - foreign import lib "libphysfs.so" + foreign import lib "build/libphysfs.so" } else { - foreign import lib "libphysfs.a" + foreign import lib "build/libphysfs.a" } } else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 { foreign import lib "env.o"