initial working version of the builder

This commit is contained in:
Stefan Stefanov 2024-01-18 17:40:11 +02:00
parent 51ec473ee6
commit b7e340b562
7 changed files with 124 additions and 10 deletions

View file

@ -5,6 +5,9 @@ build: clean
run:
./bin/odin_runner.exe
check:
odin check ./src/
clean:
rm -rf ./bin/odin_runner.*

View file

@ -2,6 +2,7 @@
"defaults": {
"collections": [],
"flags": [],
"source": "./src/",
"output_dir": "./bin/",
"binary_name": "binary_name.bin"
},
@ -17,6 +18,7 @@
"flags": [
"-o:speed",
],
"source": "./src/",
"output_dir": "./bin/release/",
"binary_name": "binary_name_release.bin"
}
@ -32,6 +34,7 @@
"flags": [
"-debug",
],
"source": "./src/",
"output_dir": "./bin/debug/",
"binary_name": "binary_name_debug.bin"
}

BIN
src.bin Executable file

Binary file not shown.

View file

@ -4,30 +4,51 @@ import "core:fmt"
import "core:log"
import "core:os"
ECommand :: enum {
Command :: enum {
TEST,
BUILD,
CHECK,
CLEAN,
}
TEST_CMD :: "test"
BUILD_CMD :: "build"
CHECK_CMD :: "check"
CLEAN_CMD :: "clean"
parse_commands :: proc() {
command : ECommand
parse_commands :: proc() -> (command: Command, target: TargetName) {
args := os.args
binary_name := args[0]
command_string := args[1]
command_string := len(args) > 1 ? args[1] : "build"
log.infof("args: %v", args)
if command_string == BUILD_CMD {
if command_string == TEST_CMD {
command = .TEST
} else if command_string == BUILD_CMD {
command = .BUILD
}
if command_string == CHECK_CMD {
} else if command_string == CHECK_CMD {
command = .CHECK
}
if command_string == CLEAN_CMD {
} else if command_string == CLEAN_CMD {
command = .CLEAN
} else {log.errorf("Unsupported command: %s", command_string);os.exit(1)}
if len(args) > 2 {
target = TargetName(args[2])
}
return
}
command_to_string :: proc(command: Command) -> string {
switch command {
case .TEST:
{return "test"}
case .BUILD:
{return "build"}
case .CLEAN:
{return "clean"}
case .CHECK:
{return "check"}
}
return ""
}

80
src/command_executor.odin Normal file
View file

@ -0,0 +1,80 @@
package main
import c "core:c/libc"
import "core:log"
import "core:os"
import "core:strings"
ExecutionError :: enum {
None,
ErrorDuringCommandExecution,
}
execute_command :: proc(
command: Command,
target_name: TargetName,
configuration: ConfigurationTargets,
) -> (
error: ExecutionError,
) {
target_config, found_target_in_config := configuration[target_name]
if !found_target_in_config && target_name != "" {
log.errorf("No such target in config: %s", target_name)
os.exit(1)
}
compile_flags: string
sb := strings.builder_make()
defer strings.builder_destroy(&sb)
// Append the command
strings.write_string(&sb, "odin ")
strings.write_string(&sb, command_to_string(command))
strings.write_byte(&sb, ' ')
if def_config, ok := configuration[DEFAULT_TARGET_NAME]; ok && !found_target_in_config {
strings.write_string(&sb, string(def_config.source))
} else if found_target_in_config {
strings.write_string(&sb, string(target_config.source))
}
// Add the collections to the compile flags
if def_config, ok := configuration[DEFAULT_TARGET_NAME]; ok {
for collectionName, collectionPath in def_config.collections {
strings.write_string(&sb, " -collection:")
strings.write_string(&sb, string(collectionName))
strings.write_string(&sb, "=")
strings.write_string(&sb, string(collectionPath))
}
}
if found_target_in_config {
for collectionName, collectionPath in target_config.collections {
strings.write_string(&sb, " -collection:")
strings.write_string(&sb, string(collectionName))
strings.write_string(&sb, "=")
strings.write_string(&sb, string(collectionPath))
}
}
// Add the other type of flags
if def_config, ok := configuration[DEFAULT_TARGET_NAME]; ok {
for flag in def_config.flags {
strings.write_byte(&sb, ' ')
strings.write_string(&sb, flag)
}
}
if found_target_in_config {
for flag in target_config.flags {
strings.write_byte(&sb, ' ')
strings.write_string(&sb, flag)
}
}
compile_flags = strings.to_string(sb)
log.infof("Calling command:\n\t'%s'", compile_flags)
ccommand, err := strings.clone_to_cstring(compile_flags)
c.system(ccommand)
return
}

View file

@ -13,6 +13,7 @@ TargetName :: distinct string
DEFAULT_TARGET_NAME :: "defaults"
CONFIGURATIONS_KEY :: "configurations"
FLAGS_KEY :: "flags"
SOURCE_KEY :: "source"
OUTPUT_DIR_KEY :: "output_dir"
BINARY_NAME_KEY :: "binary_name"
COLLECTION_NAME_KEY :: "name"
@ -26,6 +27,7 @@ Config :: struct {
output_dir: Path,
binary_name: string,
configuration_name: TargetName,
source: Path,
}
ConfigurationTargets :: distinct map[TargetName]Config
@ -104,6 +106,9 @@ parse_target_config :: proc(name: TargetName, target_obj: json.Object) -> (confi
}
}
source, s_ok := target_obj[SOURCE_KEY].(json.String)
if s_ok {config.source = Path(source)}
output_dir, o_ok := target_obj[OUTPUT_DIR_KEY].(json.String)
if o_ok {config.output_dir = Path(output_dir)}

View file

@ -1,11 +1,13 @@
package main
import "core:log"
import c "core:c/libc"
main :: proc() {
context.logger = log.create_console_logger()
parse_commands()
command, target := parse_commands()
targets := parse_config("./odin_runner.json")
log.debug(targets)
execute_command(command, target, targets)
}