Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft for core:build. #2874

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
6bd4115
Drafting core:build. First commit
DragosPopse Oct 9, 2023
f81d529
Working on core:build. Added base algorithms and types
DragosPopse Oct 9, 2023
af3b5d6
Merge branch 'odin-lang:master' into master
DragosPopse Oct 11, 2023
f099e01
Removed ols.json
DragosPopse Oct 11, 2023
928b20e
More work towards core:build
DragosPopse Oct 11, 2023
782272f
First working version of core:build. Implemented ols.json generation
DragosPopse Oct 12, 2023
b7a8f52
Added more experimental flags in core:build. Needs implementing
DragosPopse Oct 12, 2023
cabbfba
Working draft. vscode integration still errors
DragosPopse Oct 16, 2023
88c819c
First working draft of core:build
DragosPopse Oct 17, 2023
ab40787
removed the dependencies demo for now.
DragosPopse Oct 17, 2023
e00879d
Fixed a typo for core:build vscode generation
DragosPopse Oct 17, 2023
d2e285f
Merge branch 'odin-lang:master' into master
DragosPopse Oct 17, 2023
18b43d5
Converted space indentation to tabs for core:build
DragosPopse Oct 17, 2023
db02159
renamed build.syscall to build.shell_exec. It's a better name.
DragosPopse Oct 17, 2023
2a1d161
Renamed Build_Options to Settings. Added settings_init_from_args, rem…
DragosPopse Oct 20, 2023
ad5ed51
core:build - concentrated the use of libc.system into a single place …
DragosPopse Oct 20, 2023
ca2e5de
Renamed Dev_Setup to Dev (easier to write)
DragosPopse Oct 20, 2023
398f43f
core:build - Added specifiable custom flags in build.settings_init_fr…
DragosPopse Oct 20, 2023
b1a8630
core:build - Working on dependencies feature. Mockup of the API. Need…
DragosPopse Oct 20, 2023
88d079f
core:build - cached the configs once generated. Working towards the d…
DragosPopse Oct 20, 2023
9963383
core:build - Dependencies work like a charm. Just need to allow calli…
DragosPopse Oct 20, 2023
d2b1a82
core:build. Simplified the interface. Config.name removed in favor of…
DragosPopse Oct 21, 2023
0adb0d9
Merge branch 'odin-lang:master' into master
DragosPopse Nov 4, 2023
404a650
Merge branch 'odin-lang:master' into master
DragosPopse Nov 5, 2023
936cbc8
core:build - Added abi as part of build.Platform
DragosPopse Nov 5, 2023
36e2f5a
Merge branch 'master' of https://github.com/DragosPopse/Odin
DragosPopse Nov 5, 2023
80d2974
core:build - added Compiler_Flag.No_RTTI
DragosPopse Nov 5, 2023
c636a07
core:build - Renamed Pic to PIC
DragosPopse Nov 5, 2023
4d52c31
core:build - fixed file permisions on linux. Tested on Ubuntu 64-bit VM
DragosPopse Nov 5, 2023
d2793f8
core:build - removed some whitespaces
DragosPopse Nov 5, 2023
5a4ef31
core:build - fixed error on windows caused by new linux permissions fix.
DragosPopse Nov 6, 2023
eac207f
core:build - started removing odin dependency and refactoring Config
DragosPopse Nov 7, 2023
1bc1081
core:build - removing libc dependence soon
DragosPopse Nov 7, 2023
7134115
core:build - trying out some of flysand's ideas
DragosPopse Nov 7, 2023
dff035f
Merge branch 'odin-lang:master' into master
DragosPopse Nov 7, 2023
92e7ae0
core:build - refactoring a bunch
DragosPopse Nov 9, 2023
3eaa8d7
core:build - target.root_dir no longer uses any allocations. More wor…
DragosPopse Nov 10, 2023
8b3fcb2
core:build - finishing touches on the refactoring
DragosPopse Nov 10, 2023
7e08a29
core:build - Changed the example. Needs work for dependency example. …
DragosPopse Nov 10, 2023
38275e2
core:build - build mode runs well. dev mode requires more work
DragosPopse Nov 11, 2023
0b00621
Merge branch 'odin-lang:master' into master
DragosPopse Nov 11, 2023
da659b1
core:build - basic dev settings work
DragosPopse Nov 11, 2023
86bd1e1
core:build - removed the abi from the Platform, moved it to Odin_Config
DragosPopse Nov 11, 2023
5c22fa1
core:build - file reorganization
DragosPopse Nov 11, 2023
9b40449
core:build - added build.relpath and build.abspath utilities. Removed…
DragosPopse Nov 11, 2023
09581ce
core:build - help flag now prints the executable rather than the full…
DragosPopse Nov 11, 2023
27737ee
core:build - removed dependency demo for now until a more fleshed out…
DragosPopse Nov 11, 2023
8ba2f83
core:build - Improved help display
DragosPopse Nov 11, 2023
403c329
core:build - Preparing final steps for review
DragosPopse Nov 11, 2023
70fe133
Merge branch 'odin-lang:master' into master
DragosPopse Nov 13, 2023
eb9c313
Fixed spaces. Removed Target.depends. Dependencies are handled by exe…
DragosPopse Nov 15, 2023
762b585
Merge branch 'odin-lang:master' into master
DragosPopse Nov 15, 2023
42abbab
Merge branch 'odin-lang:master' into master
DragosPopse Nov 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,5 @@ shared/
examples/bug/
build.sh
!core/debug/

*ols.json*
182 changes: 182 additions & 0 deletions core/build/cli.odin
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package build

import "core:strings"
import "core:os"
import "core:path/filepath"
import "core:sync"
import "core:encoding/json"
import "core:runtime"
import "core:fmt"
import "core:slice"
import "core:unicode/utf8"
import "core:unicode"
import "core:strconv"
import "core:intrinsics"


Flag_Arg :: struct { // -flag:key=val
flag: string,
key: string,
val: string,
}

Arg :: union {
Flag_Arg,
string,
}

Args_Error :: enum {
None,
Invalid_Format,
}

// Todo(Dragos): add option to handle ints, floats, bools as strings
parse_args :: proc(os_args: []string, allocator := context.allocator) -> (args: []Arg, err: Args_Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = allocator == context.temp_allocator)
context.allocator = allocator
args = make([]Arg, len(os_args) - 1)
for os_arg, i in os_args[1:] {
if os_arg[0] == '-' {
flag_arg: Flag_Arg
colon_slice := strings.split(os_arg, ":", context.temp_allocator)
switch len(colon_slice) {
case 1: // only the flag found, no key-val
flag_arg.flag = colon_slice[0]

case 2: // key and/or value found
flag_arg.flag = colon_slice[0]
equal_slice := strings.split(colon_slice[1], "=", context.temp_allocator)
switch len(equal_slice) {
case 1: // only key, no value
flag_arg.key = equal_slice[0]
case 2: /// key and value
flag_arg.key = equal_slice[0]
flag_arg.val = equal_slice[1]
}

case: // more than 1 colon found. Invalid syntax
err = .Invalid_Format
return
}
args[i] = flag_arg
} else {
args[i] = os_arg
}
}
return
}


Flag_Desc :: struct {
mode: Run_Mode,
flag: Flag_Arg,
help: string,
}

Cli_Info :: struct {
project: ^Project, // this can be projects: []^Project
default_target: ^Target,
}

Cli_Flags_Error :: enum {
Incompatible_Flags,
}

builtin_flags := [?]Flag_Desc {
{.Help, {"-help", "", ""}, "Displays information about the build system or the target specified."},
{.Dev, {"-ols", "", ""}, "Generates an ols.json for the configuration."},
{.Dev, {"-vscode", "", ""}, "Generates .vscode folder for debugging."},
{.Dev, {"-build-pre-launch", "", ""}, "Runs the build system before debugging. (WIP)"},
{.Dev, {"-include-build-system", "<args>", ""}, "Include the build system as a debugging target. (WIP)"},
{.Dev, {"-cwd", "<dir>", ""}, "Sets the CWD to the specified directory."},
{.Dev, {"-cwd-workspace", "", ""}, "Sets the CWD to the root of the build system executable."},
{.Dev, {"-cwd-out", "", ""}, "Sets the CWD to the output directory specified in the -out odin flag"},
{.Dev, {"-launch-args", "<args>", ""}, "The arguments to be sent to the output executable when debugging."},
{.Dev, {"-dbg", "<debugger name>", ""}, "Debugger type used. Works with -vscode. Sets the ./vscode/launch.json \"type\" argument"},
}

print_general_help :: proc(info: Cli_Info) {
fmt.printf("Syntax: %s <flags> <target>\n", filepath.base(os.args[0]))
fmt.printf("Available Targets:\n")
for target in info.project.targets {
prefixed_name := strings.concatenate({info.project.target_prefix, target.name}, context.temp_allocator)
fmt.printf("\t%s\n", prefixed_name)
}
fmt.println()
fmt.printf("Builtin Flags - Only 1 [Type] group per call. Groups are incompatible\n")

for flag_desc in builtin_flags {
fmt.printf("\t%s", flag_desc.flag.flag)
if flag_desc.flag.key != "" {
fmt.printf(":\"%s\"", flag_desc.flag.key)
}
if flag_desc.flag.val != "" {
fmt.printf("=\"%s\"", flag_desc.flag.key)
}
fmt.println()
fmt.printf("\t\t%s %s\n", mode_strings[flag_desc.mode], flag_desc.help)
fmt.println()
}
}

run_cli :: proc(info: Cli_Info, cli_args: []string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
args, err := parse_args(cli_args, context.temp_allocator) // cli_args[0] should be the executable
target_names_from_args := make_dynamic_array_len_cap([dynamic]string, 0, len(info.project.targets), context.temp_allocator) // This is not fully correct right now
filtered_args_by_mode := make([dynamic]Arg, context.temp_allocator)
current_mode: Maybe(Run_Mode)
last_flag: Flag_Arg
for arg in args {
#partial switch v in arg {
case string:
append(&target_names_from_args, v)
case Flag_Arg:
flag_found := false
for flag_desc in builtin_flags do if flag_desc.flag == v {
flag_found = true
if current_mode == nil {
current_mode = flag_desc.mode
}
if current_mode != flag_desc.mode {
fmt.eprintf("Mode %s set by %s is incompatible with previous mode %s set by previous flag %s. Run `%s -help`` for more details.\n", mode_strings[flag_desc.mode], flag_desc.flag, current_mode.?, last_flag, cli_args[0])
return false
}
last_flag = v
append(&filtered_args_by_mode, v)
break
}
if !flag_found {
fmt.eprintf("Flag %s does not exist. Run `%s -help` for a list of available flags.\n", v, cli_args[0])
return false
}
}
}

if current_mode == nil do current_mode = .Build


if len(target_names_from_args) > 0 do for name in target_names_from_args {
for target in info.project.targets {
prefixed_name := strings.concatenate({info.project.target_prefix, target.name})
if _match(name, prefixed_name) {
ok := run_target(target, current_mode.?, args)
if !ok {
fmt.eprintf("Error running %s mode for target %s\n", current_mode.?, target.name)
return false
}
}
}
} else { // if no target is specified, use the default target
if current_mode.? == .Help {
print_general_help(info) // No target + -help is a special case. It doesn't print the help of the default target, only the general help.
} else {
ok := run_target(info.default_target, current_mode.?, args)
if !ok {
fmt.eprintf("Error running %s mode for target %s\n", current_mode.?, info.default_target.name)
return false
}
}
}

return true
}
Loading