From e8d52ac2bcbc0b618b079df1c04316c018cfb333 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 19 May 2025 07:15:36 -0400
Subject: Make `odin help` more precise about what it accepts
---
src/main.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 50 insertions(+), 15 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index b2cfbe018..d8b866e83 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2221,20 +2221,30 @@ gb_internal void remove_temp_files(lbGenerator *gen) {
}
-gb_internal void print_show_help(String const arg0, String command, String optional_flag = {}) {
+gb_internal int print_show_help(String const arg0, String command, String optional_flag = {}) {
+ bool help_resolved = false;
+ bool printed_usage_header = false;
+ bool printed_flags_header = false;
+
if (command == "help" && optional_flag.len != 0 && optional_flag[0] != '-') {
command = optional_flag;
optional_flag = {};
}
- print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(arg0));
- print_usage_line(0, "Usage:");
- print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
- print_usage_line(0, "");
- defer (print_usage_line(0, ""));
-
+ auto const print_usage_header_once = [&help_resolved, &printed_usage_header, arg0, command]() {
+ if (printed_usage_header) {
+ return;
+ }
+ print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(arg0));
+ print_usage_line(0, "Usage:");
+ print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
+ print_usage_line(0, "");
+ help_resolved = true;
+ printed_usage_header = true;
+ };
if (command == "build") {
+ print_usage_header_once();
print_usage_line(1, "build Compiles directory of .odin files as an executable.");
print_usage_line(2, "One must contain the program's entry point, all must be in the same package.");
print_usage_line(2, "Use `-file` to build a single file instead.");
@@ -2243,6 +2253,7 @@ gb_internal void print_show_help(String const arg0, String command, String optio
print_usage_line(3, "odin build
Builds package in .");
print_usage_line(3, "odin build filename.odin -file Builds single-file package, must contain entry point.");
} else if (command == "run") {
+ print_usage_header_once();
print_usage_line(1, "run Same as 'build', but also then runs the newly compiled executable.");
print_usage_line(2, "Append an empty flag and then the args, '-- ', to specify args for the output.");
print_usage_line(2, "Examples:");
@@ -2250,25 +2261,31 @@ gb_internal void print_show_help(String const arg0, String command, String optio
print_usage_line(3, "odin run Builds and runs package in .");
print_usage_line(3, "odin run filename.odin -file Builds and runs single-file package, must contain entry point.");
} else if (command == "check") {
+ print_usage_header_once();
print_usage_line(1, "check Parses and type checks directory of .odin files.");
print_usage_line(2, "Examples:");
print_usage_line(3, "odin check . Type checks package in current directory.");
print_usage_line(3, "odin check Type checks package in .");
print_usage_line(3, "odin check filename.odin -file Type checks single-file package, must contain entry point.");
} else if (command == "test") {
+ print_usage_header_once();
print_usage_line(1, "test Builds and runs procedures with the attribute @(test) in the initial package.");
} else if (command == "doc") {
+ print_usage_header_once();
print_usage_line(1, "doc Generates documentation from a directory of .odin files.");
print_usage_line(2, "Examples:");
print_usage_line(3, "odin doc . Generates documentation on package in current directory.");
print_usage_line(3, "odin doc Generates documentation on package in .");
print_usage_line(3, "odin doc filename.odin -file Generates documentation on single-file package.");
} else if (command == "version") {
+ print_usage_header_once();
print_usage_line(1, "version Prints version.");
} else if (command == "strip-semicolon") {
+ print_usage_header_once();
print_usage_line(1, "strip-semicolon");
print_usage_line(2, "Parses and type checks .odin file(s) and then removes unneeded semicolons from the entire project.");
} else if (command == "bundle") {
+ print_usage_header_once();
print_usage_line(1, "bundle Bundles a directory in a specific layout for that platform");
print_usage_line(2, "Supported platforms:");
print_usage_line(3, "android");
@@ -2293,13 +2310,10 @@ gb_internal void print_show_help(String const arg0, String command, String optio
check = true;
}
- print_usage_line(0, "");
- print_usage_line(1, "Flags");
- print_usage_line(0, "");
- auto const print_flag = [&optional_flag](char const *flag) -> bool {
+ auto const print_flag = [&optional_flag, &help_resolved, &printed_flags_header, print_usage_header_once](char const *flag) -> bool {
if (optional_flag.len != 0) {
String f = make_string_c(flag);
isize i = string_index_byte(f, ':');
@@ -2310,6 +2324,14 @@ gb_internal void print_show_help(String const arg0, String command, String optio
return false;
}
}
+ print_usage_header_once();
+ if (!printed_flags_header) {
+ print_usage_line(0, "");
+ print_usage_line(1, "Flags");
+ print_usage_line(0, "");
+ printed_flags_header = true;
+ }
+ help_resolved = true;
print_usage_line(0, "");
print_usage_line(1, flag);
return true;
@@ -2867,6 +2889,21 @@ gb_internal void print_show_help(String const arg0, String command, String optio
print_usage_line(2, "If this is omitted, the terminal will prompt you to provide it.");
}
}
+
+ if (!help_resolved) {
+ usage(arg0);
+ print_usage_line(0, "");
+ if (command == "help") {
+ print_usage_line(0, "'%.*s' is not a recognized flag.", LIT(optional_flag));
+ } else {
+ print_usage_line(0, "'%.*s' is not a recognized command.", LIT(command));
+ }
+ return 1;
+ }
+
+ print_usage_line(0, "");
+
+ return 0;
}
gb_internal void print_show_unused(Checker *c) {
@@ -3354,8 +3391,7 @@ int main(int arg_count, char const **arg_ptr) {
usage(args[0]);
return 1;
} else {
- print_show_help(args[0], args[1], args[2]);
- return 0;
+ return print_show_help(args[0], args[1], args[2]);
}
} else if (command == "bundle") {
if (args.count < 4) {
@@ -3441,8 +3477,7 @@ int main(int arg_count, char const **arg_ptr) {
}
if (build_context.show_help) {
- print_show_help(args[0], command);
- return 0;
+ return print_show_help(args[0], command);
}
if (command == "bundle") {
--
cgit v1.2.3
From fa63d351acea69ecb6a1cb1b127a12e17538124d Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 19 May 2025 07:19:28 -0400
Subject: Add missing commands to `odin help`
---
src/main.cpp | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index d8b866e83..818e5b60e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2289,6 +2289,12 @@ gb_internal int print_show_help(String const arg0, String command, String option
print_usage_line(1, "bundle Bundles a directory in a specific layout for that platform");
print_usage_line(2, "Supported platforms:");
print_usage_line(3, "android");
+ } else if (command == "report") {
+ print_usage_header_once();
+ print_usage_line(1, "report Prints information useful to reporting a bug.");
+ } else if (command == "root") {
+ print_usage_header_once();
+ print_usage_line(1, "root Prints the root path where Odin looks for the builtin collections.");
}
bool doc = command == "doc";
--
cgit v1.2.3
From a5926532a2316340e6ceed7d8a7fee2b02fde7b7 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 19 May 2025 07:22:47 -0400
Subject: Sync command descriptions between `odin help` and usage
---
src/main.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index 818e5b60e..f64575cac 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -278,10 +278,10 @@ gb_internal void usage(String argv0, String argv1 = {}) {
print_usage_line(1, " One must contain the program's entry point, all must be in the same package.");
print_usage_line(1, "run Same as 'build', but also then runs the newly compiled executable.");
print_usage_line(1, "bundle Bundles a directory in a specific layout for that platform.");
- print_usage_line(1, "check Parses, and type checks a directory of .odin files.");
+ print_usage_line(1, "check Parses and type checks a directory of .odin files.");
print_usage_line(1, "strip-semicolon Parses, type checks, and removes unneeded semicolons from the entire program.");
print_usage_line(1, "test Builds and runs procedures with the attribute @(test) in the initial package.");
- print_usage_line(1, "doc Generates documentation on a directory of .odin files.");
+ print_usage_line(1, "doc Generates documentation from a directory of .odin files.");
print_usage_line(1, "version Prints version.");
print_usage_line(1, "report Prints information useful to reporting a bug.");
print_usage_line(1, "root Prints the root path where Odin looks for the builtin collections.");
--
cgit v1.2.3
From 4495a4c58ed73c7b6c4b552855537ead65cd93d3 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 19 May 2025 09:25:18 -0400
Subject: Check for `-help` sooner and show it immediately
---
src/main.cpp | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index f64575cac..d32ae9c28 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3282,6 +3282,16 @@ int main(int arg_count, char const **arg_ptr) {
String run_args_string = {};
isize last_non_run_arg = args.count;
+ for_array(i, args) {
+ if (args[i] == "--") {
+ break;
+ }
+ if (args[i] == "-help" || args[i] == "--help") {
+ build_context.show_help = true;
+ return print_show_help(args[0], command);
+ }
+ }
+
bool run_output = false;
if (command == "run" || command == "test") {
if (args.count < 3) {
@@ -3428,11 +3438,6 @@ int main(int arg_count, char const **arg_ptr) {
init_filename = copy_string(permanent_allocator(), init_filename);
- if (init_filename == "-help" ||
- init_filename == "--help") {
- build_context.show_help = true;
- }
-
if (init_filename.len > 0 && !build_context.show_help) {
// The command must be build, run, test, check, or another that takes a directory or filename.
if (!path_is_directory(init_filename)) {
--
cgit v1.2.3
From 2c25a72b45b9047862535aeb9b069292eba8a6e4 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 19 May 2025 09:26:57 -0400
Subject: Make certain commands fail if passed excess arguments
---
src/main.cpp | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index d32ae9c28..00032c1ff 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3385,6 +3385,10 @@ int main(int arg_count, char const **arg_ptr) {
return 1;
#endif
} else if (command == "version") {
+ if (args.count != 2) {
+ usage(args[0]);
+ return 1;
+ }
build_context.command_kind = Command_version;
gb_printf("%.*s version %.*s", LIT(args[0]), LIT(ODIN_VERSION));
@@ -3399,6 +3403,10 @@ int main(int arg_count, char const **arg_ptr) {
gb_printf("\n");
return 0;
} else if (command == "report") {
+ if (args.count != 2) {
+ usage(args[0]);
+ return 1;
+ }
build_context.command_kind = Command_bug_report;
print_bug_report_help();
return 0;
@@ -3423,6 +3431,10 @@ int main(int arg_count, char const **arg_ptr) {
}
init_filename = args[3];
} else if (command == "root") {
+ if (args.count != 2) {
+ usage(args[0]);
+ return 1;
+ }
gb_printf("%.*s", LIT(odin_root_dir()));
return 0;
} else if (command == "clear-cache") {
--
cgit v1.2.3
From ab9593250295137d0a654e942965feee7f506206 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Mon, 19 May 2025 20:44:27 +0200
Subject: -dynamic-literals
---
src/build_settings.cpp | 1 +
src/check_expr.cpp | 2 +-
src/llvm_backend_expr.cpp | 2 +-
src/main.cpp | 5 +++++
4 files changed, 8 insertions(+), 2 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 04101761c..8364bbfbe 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -459,6 +459,7 @@ struct BuildContext {
bool ignore_unknown_attributes;
bool no_bounds_check;
bool no_type_assert;
+ bool dynamic_literals; // Opt-in to `#+feature dynamic-literals` project-wide.
bool no_output_files;
bool no_crt;
bool no_rpath;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 7ccca1b57..167052772 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -9433,7 +9433,7 @@ gb_internal bool is_expr_inferred_fixed_array(Ast *type_expr) {
}
gb_internal bool check_for_dynamic_literals(CheckerContext *c, Ast *node, AstCompoundLit *cl) {
- if (cl->elems.count > 0 && (check_feature_flags(c, node) & OptInFeatureFlag_DynamicLiterals) == 0) {
+ if (cl->elems.count > 0 && (check_feature_flags(c, node) & OptInFeatureFlag_DynamicLiterals) == 0 && !build_context.dynamic_literals) {
ERROR_BLOCK();
error(node, "Compound literals of dynamic types are disabled by default");
error_line("\tSuggestion: If you want to enable them for this specific file, add '#+feature dynamic-literals' at the top of the file\n");
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 0909b189a..e17d958d7 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -4844,7 +4844,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
if (cl->elems.count == 0) {
break;
}
- GB_ASSERT(expr->file()->feature_flags & OptInFeatureFlag_DynamicLiterals);
+ GB_ASSERT(expr->file()->feature_flags & OptInFeatureFlag_DynamicLiterals || build_context.dynamic_literals);
lbValue err = lb_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos);
gb_unused(err);
diff --git a/src/main.cpp b/src/main.cpp
index 00032c1ff..3692e4f06 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -319,6 +319,7 @@ enum BuildFlagKind {
BuildFlag_NoBoundsCheck,
BuildFlag_NoTypeAssert,
BuildFlag_NoDynamicLiterals,
+ BuildFlag_DynamicLiterals,
BuildFlag_NoCRT,
BuildFlag_NoRPath,
BuildFlag_NoEntryPoint,
@@ -538,6 +539,7 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_NoTypeAssert, str_lit("no-type-assert"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_NoThreadLocal, str_lit("no-thread-local"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check);
+ add_flag(&build_flags, BuildFlag_DynamicLiterals, str_lit("dynamic-literals"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_NoRPath, str_lit("no-rpath"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test);
@@ -1207,6 +1209,9 @@ gb_internal bool parse_build_flags(Array args) {
case BuildFlag_NoDynamicLiterals:
gb_printf_err("Warning: Use of -no-dynamic-literals is now redundant\n");
break;
+ case BuildFlag_DynamicLiterals:
+ build_context.dynamic_literals = true;
+ break;
case BuildFlag_NoCRT:
build_context.no_crt = true;
break;
--
cgit v1.2.3
From c32b7ba593f78469d12a3ffdf333e7fb54116316 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Wed, 21 May 2025 20:24:27 +0200
Subject: List -subtarget in `odin help build`
---
src/main.cpp | 115 +++++++++++++++++++++++++++++++++--------------------------
1 file changed, 65 insertions(+), 50 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index 3692e4f06..bc57c677e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2364,20 +2364,20 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-build-mode:")) {
print_usage_line(2, "Sets the build mode.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-build-mode:exe Builds as an executable.");
- print_usage_line(3, "-build-mode:test Builds as an executable that executes tests.");
- print_usage_line(3, "-build-mode:dll Builds as a dynamically linked library.");
- print_usage_line(3, "-build-mode:shared Builds as a dynamically linked library.");
- print_usage_line(3, "-build-mode:dynamic Builds as a dynamically linked library.");
- print_usage_line(3, "-build-mode:lib Builds as a statically linked library.");
- print_usage_line(3, "-build-mode:static Builds as a statically linked library.");
- print_usage_line(3, "-build-mode:obj Builds as an object file.");
- print_usage_line(3, "-build-mode:object Builds as an object file.");
- print_usage_line(3, "-build-mode:assembly Builds as an assembly file.");
- print_usage_line(3, "-build-mode:assembler Builds as an assembly file.");
- print_usage_line(3, "-build-mode:asm Builds as an assembly file.");
- print_usage_line(3, "-build-mode:llvm-ir Builds as an LLVM IR file.");
- print_usage_line(3, "-build-mode:llvm Builds as an LLVM IR file.");
+ print_usage_line(3, "-build-mode:exe Builds as an executable.");
+ print_usage_line(3, "-build-mode:test Builds as an executable that executes tests.");
+ print_usage_line(3, "-build-mode:dll Builds as a dynamically linked library.");
+ print_usage_line(3, "-build-mode:shared Builds as a dynamically linked library.");
+ print_usage_line(3, "-build-mode:dynamic Builds as a dynamically linked library.");
+ print_usage_line(3, "-build-mode:lib Builds as a statically linked library.");
+ print_usage_line(3, "-build-mode:static Builds as a statically linked library.");
+ print_usage_line(3, "-build-mode:obj Builds as an object file.");
+ print_usage_line(3, "-build-mode:object Builds as an object file.");
+ print_usage_line(3, "-build-mode:assembly Builds as an assembly file.");
+ print_usage_line(3, "-build-mode:assembler Builds as an assembly file.");
+ print_usage_line(3, "-build-mode:asm Builds as an assembly file.");
+ print_usage_line(3, "-build-mode:llvm-ir Builds as an LLVM IR file.");
+ print_usage_line(3, "-build-mode:llvm Builds as an LLVM IR file.");
}
}
@@ -2386,16 +2386,16 @@ gb_internal int print_show_help(String const arg0, String command, String option
print_usage_line(2, "Defines a library collection used for imports.");
print_usage_line(2, "Example: -collection:shared=dir/to/shared");
print_usage_line(2, "Usage in Code:");
- print_usage_line(3, "import \"shared:foo\"");
+ print_usage_line(3, "import \"shared:foo\"");
}
if (print_flag("-custom-attribute:")) {
print_usage_line(2, "Add a custom attribute which will be ignored if it is unknown.");
print_usage_line(2, "This can be used with metaprogramming tools.");
print_usage_line(2, "Examples:");
- print_usage_line(3, "-custom-attribute:my_tag");
- print_usage_line(3, "-custom-attribute:my_tag,the_other_thing");
- print_usage_line(3, "-custom-attribute:my_tag -custom-attribute:the_other_thing");
+ print_usage_line(3, "-custom-attribute:my_tag");
+ print_usage_line(3, "-custom-attribute:my_tag,the_other_thing");
+ print_usage_line(3, "-custom-attribute:my_tag -custom-attribute:the_other_thing");
}
}
@@ -2418,7 +2418,7 @@ gb_internal int print_show_help(String const arg0, String command, String option
print_usage_line(2, "Defines a scalar boolean, integer or string as global constant.");
print_usage_line(2, "Example: -define:SPAM=123");
print_usage_line(2, "Usage in code:");
- print_usage_line(3, "#config(SPAM, default_value)");
+ print_usage_line(3, "#config(SPAM, default_value)");
}
}
@@ -2453,9 +2453,9 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (check) {
if (print_flag("-error-pos-style:")) {
print_usage_line(2, "Available options:");
- print_usage_line(3, "-error-pos-style:unix file/path:45:3:");
- print_usage_line(3, "-error-pos-style:odin file/path(45:3)");
- print_usage_line(3, "-error-pos-style:default (Defaults to 'odin'.)");
+ print_usage_line(3, "-error-pos-style:unix file/path:45:3:");
+ print_usage_line(3, "-error-pos-style:odin file/path(45:3)");
+ print_usage_line(3, "-error-pos-style:default (Defaults to 'odin'.)");
}
if (print_flag("-export-defineables:")) {
@@ -2466,8 +2466,8 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-export-dependencies:")) {
print_usage_line(2, "Exports dependencies to one of a few formats. Requires `-export-dependencies-file`.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-export-dependencies:make Exports in Makefile format");
- print_usage_line(3, "-export-dependencies:json Exports in JSON format");
+ print_usage_line(3, "-export-dependencies:make Exports in Makefile format");
+ print_usage_line(3, "-export-dependencies:json Exports in JSON format");
}
if (print_flag("-export-dependencies-file:")) {
@@ -2478,8 +2478,8 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-export-timings:")) {
print_usage_line(2, "Exports timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-export-timings:json Exports compile time stats to JSON.");
- print_usage_line(3, "-export-timings:csv Exports compile time stats to CSV.");
+ print_usage_line(3, "-export-timings:json Exports compile time stats to JSON.");
+ print_usage_line(3, "-export-timings:csv Exports compile time stats to CSV.");
}
if (print_flag("-export-timings-file:")) {
@@ -2569,9 +2569,9 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-microarch:")) {
print_usage_line(2, "Specifies the specific micro-architecture for the build in a string.");
print_usage_line(2, "Examples:");
- print_usage_line(3, "-microarch:sandybridge");
- print_usage_line(3, "-microarch:native");
- print_usage_line(3, "-microarch:\"?\" for a list");
+ print_usage_line(3, "-microarch:sandybridge");
+ print_usage_line(3, "-microarch:native");
+ print_usage_line(3, "-microarch:\"?\" for a list");
}
}
@@ -2628,10 +2628,10 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-o:")) {
print_usage_line(2, "Sets the optimization mode for compilation.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-o:none");
- print_usage_line(3, "-o:minimal");
- print_usage_line(3, "-o:size");
- print_usage_line(3, "-o:speed");
+ print_usage_line(3, "-o:none");
+ print_usage_line(3, "-o:minimal");
+ print_usage_line(3, "-o:size");
+ print_usage_line(3, "-o:speed");
if (LB_USE_NEW_PASS_SYSTEM) {
print_usage_line(3, "-o:aggressive (use this with caution)");
}
@@ -2682,10 +2682,10 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-reloc-mode:")) {
print_usage_line(2, "Specifies the reloc mode.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-reloc-mode:default");
- print_usage_line(3, "-reloc-mode:static");
- print_usage_line(3, "-reloc-mode:pic");
- print_usage_line(3, "-reloc-mode:dynamic-no-pic");
+ print_usage_line(3, "-reloc-mode:default");
+ print_usage_line(3, "-reloc-mode:static");
+ print_usage_line(3, "-reloc-mode:pic");
+ print_usage_line(3, "-reloc-mode:dynamic-no-pic");
}
#if defined(GB_SYSTEM_WINDOWS)
@@ -2700,9 +2700,9 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-sanitize:")) {
print_usage_line(2, "Enables sanitization analysis.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-sanitize:address");
- print_usage_line(3, "-sanitize:memory");
- print_usage_line(3, "-sanitize:thread");
+ print_usage_line(3, "-sanitize:address");
+ print_usage_line(3, "-sanitize:memory");
+ print_usage_line(3, "-sanitize:thread");
print_usage_line(2, "NOTE: This flag can be used multiple times.");
}
}
@@ -2763,17 +2763,32 @@ gb_internal int print_show_help(String const arg0, String command, String option
print_usage_line(2, "[Windows only]");
print_usage_line(2, "Defines the subsystem for the application.");
print_usage_line(2, "Available options:");
- print_usage_line(3, "-subsystem:console");
- print_usage_line(3, "-subsystem:windows");
+ print_usage_line(3, "-subsystem:console");
+ print_usage_line(3, "-subsystem:windows");
}
#endif
+ }
+ if (build) {
+ if (print_flag("-subtarget")) {
+ print_usage_line(2, "[Darwin and Linux only]");
+ print_usage_line(2, "Available subtargets:");
+ String prefix = str_lit("-subtarget:");
+ for (u32 i = 1; i < Subtarget_COUNT; i++) {
+ String name = subtarget_strings[i];
+ String help_string = concatenate_strings(temporary_allocator(), prefix, name);
+ print_usage_line(3, (const char *)help_string.text);
+ }
+ }
+ }
+
+ if (run_or_build) {
if (print_flag("-target-features:")) {
print_usage_line(2, "Specifies CPU features to enable on top of the enabled features implied by -microarch.");
print_usage_line(2, "Examples:");
- print_usage_line(3, "-target-features:atomics");
- print_usage_line(3, "-target-features:\"sse2,aes\"");
- print_usage_line(3, "-target-features:\"?\" for a list");
+ print_usage_line(3, "-target-features:atomics");
+ print_usage_line(3, "-target-features:\"sse2,aes\"");
+ print_usage_line(3, "-target-features:\"?\" for a list");
}
}
@@ -2810,11 +2825,11 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (print_flag("-vet")) {
print_usage_line(2, "Does extra checks on the code.");
print_usage_line(2, "Extra checks include:");
- print_usage_line(3, "-vet-unused");
- print_usage_line(3, "-vet-unused-variables");
- print_usage_line(3, "-vet-unused-imports");
- print_usage_line(3, "-vet-shadowing");
- print_usage_line(3, "-vet-using-stmt");
+ print_usage_line(3, "-vet-unused");
+ print_usage_line(3, "-vet-unused-variables");
+ print_usage_line(3, "-vet-unused-imports");
+ print_usage_line(3, "-vet-shadowing");
+ print_usage_line(3, "-vet-using-stmt");
}
if (print_flag("-vet-cast")) {
--
cgit v1.2.3
From f8bbeb54d4a6ce1e2c17cec68bd6fbeb5e628121 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Wed, 21 May 2025 20:28:21 +0200
Subject: Slight tweak.
---
src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index bc57c677e..90f2aad7a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2770,7 +2770,7 @@ gb_internal int print_show_help(String const arg0, String command, String option
}
if (build) {
- if (print_flag("-subtarget")) {
+ if (print_flag("-subtarget:")) {
print_usage_line(2, "[Darwin and Linux only]");
print_usage_line(2, "Available subtargets:");
String prefix = str_lit("-subtarget:");
--
cgit v1.2.3
From 0536f8626833e6b2938cbedf84b2cf06c95c0ae0 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Thu, 22 May 2025 17:33:24 -0400
Subject: Add `-build-only` for `odin test` command
This allows test executables to be only built, not run too.
---
src/build_settings.cpp | 1 +
src/main.cpp | 13 ++++++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index b3bbf726b..ae6fa3463 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -441,6 +441,7 @@ struct BuildContext {
String extra_assembler_flags;
String microarch;
BuildModeKind build_mode;
+ bool build_only;
bool generate_docs;
bool custom_optimization_level;
i32 optimization_level;
diff --git a/src/main.cpp b/src/main.cpp
index 90f2aad7a..5aaadc0d2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -312,6 +312,7 @@ enum BuildFlagKind {
BuildFlag_Collection,
BuildFlag_Define,
BuildFlag_BuildMode,
+ BuildFlag_BuildOnly,
BuildFlag_Target,
BuildFlag_Subtarget,
BuildFlag_Debug,
@@ -531,6 +532,7 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true);
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message
+ add_flag(&build_flags, BuildFlag_BuildOnly, str_lit("build-only"), BuildFlagParam_None, Command_test);
add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Subtarget, str_lit("subtarget"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check);
@@ -1193,6 +1195,9 @@ gb_internal bool parse_build_flags(Array args) {
break;
}
+ case BuildFlag_BuildOnly:
+ build_context.build_only = true;
+ break;
case BuildFlag_Debug:
build_context.ODIN_DEBUG = true;
@@ -2381,6 +2386,12 @@ gb_internal int print_show_help(String const arg0, String command, String option
}
}
+ if (test_only) {
+ if (print_flag("-build-only")) {
+ print_usage_line(2, "Only builds the test executable; does not automatically run it afterwards.");
+ }
+ }
+
if (check) {
if (print_flag("-collection:=")) {
print_usage_line(2, "Defines a library collection used for imports.");
@@ -3861,7 +3872,7 @@ end_of_code_gen:;
show_timings(checker, &global_timings);
}
- if (run_output) {
+ if (!build_context.build_only && run_output) {
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
defer (gb_free(heap_allocator(), exe_name.text));
--
cgit v1.2.3
From 5b5822effce461e3ecfdc3b57009736208999959 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Thu, 22 May 2025 17:54:15 -0400
Subject: Delete test executable after running, add `-keep-test-executable`
---
src/build_settings.cpp | 1 +
src/main.cpp | 30 +++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index ae6fa3463..4f573a8ca 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -442,6 +442,7 @@ struct BuildContext {
String microarch;
BuildModeKind build_mode;
bool build_only;
+ bool keep_test_executable;
bool generate_docs;
bool custom_optimization_level;
i32 optimization_level;
diff --git a/src/main.cpp b/src/main.cpp
index 5aaadc0d2..faedb9074 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -313,6 +313,7 @@ enum BuildFlagKind {
BuildFlag_Define,
BuildFlag_BuildMode,
BuildFlag_BuildOnly,
+ BuildFlag_KeepTestExecutable,
BuildFlag_Target,
BuildFlag_Subtarget,
BuildFlag_Debug,
@@ -533,6 +534,7 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true);
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message
add_flag(&build_flags, BuildFlag_BuildOnly, str_lit("build-only"), BuildFlagParam_None, Command_test);
+ add_flag(&build_flags, BuildFlag_KeepTestExecutable, str_lit("keep-test-executable"), BuildFlagParam_None, Command_test);
add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Subtarget, str_lit("subtarget"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check);
@@ -1196,7 +1198,22 @@ gb_internal bool parse_build_flags(Array args) {
break;
}
case BuildFlag_BuildOnly:
- build_context.build_only = true;
+ if (build_context.keep_test_executable) {
+ gb_printf_err("`-keep-test-executable` is mutually exclusive with `-build-only`.\n");
+ gb_printf_err("We either only build or run the test and optionally keep the executable.\n");
+ bad_flags = true;
+ } else {
+ build_context.build_only = true;
+ }
+ break;
+ case BuildFlag_KeepTestExecutable:
+ if (build_context.build_only) {
+ gb_printf_err("`-build-only` is mutually exclusive with `-keep-test-executable`.\n");
+ gb_printf_err("We either only build or run the test and optionally keep the executable.\n");
+ bad_flags = true;
+ } else {
+ build_context.keep_test_executable = true;
+ }
break;
case BuildFlag_Debug:
@@ -2554,6 +2571,12 @@ gb_internal int print_show_help(String const arg0, String command, String option
}
}
+ if (test_only) {
+ if (print_flag("-keep-test-executable")) {
+ print_usage_line(2, "Keep the test executable after running it instead of deleting it normally.");
+ }
+ }
+
if (run_or_build) {
if (print_flag("-linker:")) {
print_usage_line(2, "Specify the linker to use.");
@@ -3877,6 +3900,11 @@ end_of_code_gen:;
defer (gb_free(heap_allocator(), exe_name.text));
system_must_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string));
+
+ if (build_context.command_kind == Command_test && !build_context.keep_test_executable) {
+ char const *filename = cast(char const *)exe_name.text;
+ gb_file_remove(filename);
+ }
}
return 0;
}
--
cgit v1.2.3
From 12167bace05915abda62c93881d711e993e062cd Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Fri, 23 May 2025 08:28:27 +0200
Subject: Tweak #5202
Back out the new `-build-only` for tests in favor of the more established `-build-mode:test`, but retain the new `-keep-test-executable` option and default cleanup of test executables.
---
src/build_settings.cpp | 1 -
src/main.cpp | 25 +++++--------------------
2 files changed, 5 insertions(+), 21 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 9c530df19..ecbe0a45a 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -441,7 +441,6 @@ struct BuildContext {
String extra_assembler_flags;
String microarch;
BuildModeKind build_mode;
- bool build_only;
bool keep_test_executable;
bool generate_docs;
bool custom_optimization_level;
diff --git a/src/main.cpp b/src/main.cpp
index faedb9074..e905d291d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -312,7 +312,6 @@ enum BuildFlagKind {
BuildFlag_Collection,
BuildFlag_Define,
BuildFlag_BuildMode,
- BuildFlag_BuildOnly,
BuildFlag_KeepTestExecutable,
BuildFlag_Target,
BuildFlag_Subtarget,
@@ -533,7 +532,6 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true);
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message
- add_flag(&build_flags, BuildFlag_BuildOnly, str_lit("build-only"), BuildFlagParam_None, Command_test);
add_flag(&build_flags, BuildFlag_KeepTestExecutable, str_lit("keep-test-executable"), BuildFlagParam_None, Command_test);
add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Subtarget, str_lit("subtarget"), BuildFlagParam_String, Command__does_check);
@@ -1197,23 +1195,8 @@ gb_internal bool parse_build_flags(Array args) {
break;
}
- case BuildFlag_BuildOnly:
- if (build_context.keep_test_executable) {
- gb_printf_err("`-keep-test-executable` is mutually exclusive with `-build-only`.\n");
- gb_printf_err("We either only build or run the test and optionally keep the executable.\n");
- bad_flags = true;
- } else {
- build_context.build_only = true;
- }
- break;
case BuildFlag_KeepTestExecutable:
- if (build_context.build_only) {
- gb_printf_err("`-build-only` is mutually exclusive with `-keep-test-executable`.\n");
- gb_printf_err("We either only build or run the test and optionally keep the executable.\n");
- bad_flags = true;
- } else {
- build_context.keep_test_executable = true;
- }
+ build_context.keep_test_executable = true;
break;
case BuildFlag_Debug:
@@ -2573,7 +2556,9 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (test_only) {
if (print_flag("-keep-test-executable")) {
- print_usage_line(2, "Keep the test executable after running it instead of deleting it normally.");
+ print_usage_line(2, "Keep the test executable after running it with `odin test`, instead of deleting it after the test completes.");
+ print_usage_line(2, "If you build your your tests using `odin build -build-mode:test`, the compiler does not execute");
+ print_usage_line(2, "the resulting test program, and this option is not applicable.");
}
}
@@ -3895,7 +3880,7 @@ end_of_code_gen:;
show_timings(checker, &global_timings);
}
- if (!build_context.build_only && run_output) {
+ if (run_output) {
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
defer (gb_free(heap_allocator(), exe_name.text));
--
cgit v1.2.3
From f716d4c88fcb1c073cb1a1d9d32f35cc2bcc4a77 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Fri, 23 May 2025 08:32:16 +0200
Subject: your your
---
src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index e905d291d..d28faf77c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2557,7 +2557,7 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (test_only) {
if (print_flag("-keep-test-executable")) {
print_usage_line(2, "Keep the test executable after running it with `odin test`, instead of deleting it after the test completes.");
- print_usage_line(2, "If you build your your tests using `odin build -build-mode:test`, the compiler does not execute");
+ print_usage_line(2, "If you build your tests using `odin build -build-mode:test`, the compiler does not execute");
print_usage_line(2, "the resulting test program, and this option is not applicable.");
}
}
--
cgit v1.2.3
From 84b140f963126391faba0a5e873f119803d80c3c Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Fri, 23 May 2025 08:47:48 +0200
Subject: Rename -keep-test-executable to -keep-executable
---
src/build_settings.cpp | 2 +-
src/main.cpp | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index ecbe0a45a..00594c1b4 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -441,7 +441,7 @@ struct BuildContext {
String extra_assembler_flags;
String microarch;
BuildModeKind build_mode;
- bool keep_test_executable;
+ bool keep_executable;
bool generate_docs;
bool custom_optimization_level;
i32 optimization_level;
diff --git a/src/main.cpp b/src/main.cpp
index d28faf77c..1ffdd0dba 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -312,7 +312,7 @@ enum BuildFlagKind {
BuildFlag_Collection,
BuildFlag_Define,
BuildFlag_BuildMode,
- BuildFlag_KeepTestExecutable,
+ BuildFlag_KeepExecutable,
BuildFlag_Target,
BuildFlag_Subtarget,
BuildFlag_Debug,
@@ -532,7 +532,7 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true);
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message
- add_flag(&build_flags, BuildFlag_KeepTestExecutable, str_lit("keep-test-executable"), BuildFlagParam_None, Command_test);
+ add_flag(&build_flags, BuildFlag_KeepExecutable, str_lit("keep-executable"), BuildFlagParam_None, Command__does_build | Command_test);
add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Subtarget, str_lit("subtarget"), BuildFlagParam_String, Command__does_check);
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check);
@@ -1195,8 +1195,8 @@ gb_internal bool parse_build_flags(Array args) {
break;
}
- case BuildFlag_KeepTestExecutable:
- build_context.keep_test_executable = true;
+ case BuildFlag_KeepExecutable:
+ build_context.keep_executable = true;
break;
case BuildFlag_Debug:
@@ -2554,11 +2554,11 @@ gb_internal int print_show_help(String const arg0, String command, String option
}
}
- if (test_only) {
- if (print_flag("-keep-test-executable")) {
- print_usage_line(2, "Keep the test executable after running it with `odin test`, instead of deleting it after the test completes.");
- print_usage_line(2, "If you build your tests using `odin build -build-mode:test`, the compiler does not execute");
- print_usage_line(2, "the resulting test program, and this option is not applicable.");
+ if (test_only || run_or_build) {
+ if (print_flag("-keep-executable")) {
+ print_usage_line(2, "Keep the executable generated by `odin test` or `odin run` after running it. We clean it up by default.");
+ print_usage_line(2, "If you build your program or test using `odin build`, the compiler does not automatically execute");
+ print_usage_line(2, "the resulting program, and this option is not applicable.");
}
}
@@ -3886,7 +3886,7 @@ end_of_code_gen:;
system_must_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string));
- if (build_context.command_kind == Command_test && !build_context.keep_test_executable) {
+ if (!build_context.keep_executable) {
char const *filename = cast(char const *)exe_name.text;
gb_file_remove(filename);
}
--
cgit v1.2.3
From 229c734820f4cfa3deb84386e1613a982d92eede Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Mon, 26 May 2025 18:58:59 +0200
Subject: Add comments to `builtin.odin`, documenting ODIN_* constants. (#5218)
And document constants not previously listed.
---
base/builtin/builtin.odin | 230 ++++++++++++++++++++++++++++++++++++++++++++--
src/build_settings.cpp | 135 +++++++++++++--------------
src/checker.cpp | 31 +++++--
src/linker.cpp | 6 +-
src/main.cpp | 10 +-
5 files changed, 324 insertions(+), 88 deletions(-)
(limited to 'src/main.cpp')
diff --git a/base/builtin/builtin.odin b/base/builtin/builtin.odin
index 14da9603d..019fd93ff 100644
--- a/base/builtin/builtin.odin
+++ b/base/builtin/builtin.odin
@@ -7,13 +7,226 @@ nil :: nil
false :: 0!=0
true :: 0==0
-ODIN_OS :: ODIN_OS
-ODIN_ARCH :: ODIN_ARCH
-ODIN_ENDIAN :: ODIN_ENDIAN
-ODIN_VENDOR :: ODIN_VENDOR
-ODIN_VERSION :: ODIN_VERSION
-ODIN_ROOT :: ODIN_ROOT
-ODIN_DEBUG :: ODIN_DEBUG
+// The following constants are added in `checker.cpp`'s `init_universal` procedure.
+
+/*
+ An `enum` value indicating what the CPU architecture of the target is.
+ Possible values are: `.amd64`, `.i386`, `.arm32`, `.arm64`, `.wasm32`, `.wasm64p32`, and `.riscv64`.
+*/
+ODIN_ARCH :: ODIN_ARCH
+
+/*
+ A `string` indicating what the CPU architecture of the target is.
+ Possible values are: "amd64", "i386", "arm32", "arm64", "wasm32", "wasm64p32", "riscv64".
+*/
+ODIN_ARCH_STRING :: ODIN_ARCH_STRING
+
+/*
+ An `enum` value indicating the type of compiled output, chosen using `-build-mode`.
+ Possible values are: `.Executable`, `.Dynamic`, `.Static`, `.Object`, `.Assembly`, and `.LLVM_IR`.
+*/
+ODIN_BUILD_MODE :: ODIN_BUILD_MODE
+
+/*
+ A `string` containing the name of the folder that contains the entry point,
+ e.g. for `%ODIN_ROOT%/examples/demo`, this would contain `demo`.
+*/
+ODIN_BUILD_PROJECT_NAME :: ODIN_BUILD_PROJECT_NAME
+
+/*
+ An `i64` containing the time at which the executable was compiled, in nanoseconds.
+ This is compatible with the `time.Time` type, i.e. `time.Time{_nsec=ODIN_COMPILE_TIMESTAMP}`
+*/
+ODIN_COMPILE_TIMESTAMP :: ODIN_COMPILE_TIMESTAMP
+
+/*
+ `true` if the `-debug` command line switch is passed, which enables debug info generation.
+*/
+ODIN_DEBUG :: ODIN_DEBUG
+
+/*
+ `true` if the `-default-to-nil-allocator` command line switch is passed,
+ which sets the initial `context.allocator` to an allocator that does nothing.
+*/
+ODIN_DEFAULT_TO_NIL_ALLOCATOR :: ODIN_DEFAULT_TO_NIL_ALLOCATOR
+
+/*
+ `true` if the `-default-to-panic-allocator` command line switch is passed,
+ which sets the initial `context.allocator` to an allocator that panics if allocated from.
+*/
+ODIN_DEFAULT_TO_PANIC_ALLOCATOR :: ODIN_DEFAULT_TO_PANIC_ALLOCATOR
+
+/*
+ `true` if the `-disable-assert` command line switch is passed,
+ which removes all calls to `assert` from the program.
+*/
+ODIN_DISABLE_ASSERT :: ODIN_DISABLE_ASSERT
+
+/*
+ An `enum` value indicating the endianness of the target.
+ Possible values are: `.Little` and `.Big`.
+*/
+ODIN_ENDIAN :: ODIN_ENDIAN
+
+/*
+ An `enum` value indicating the endianness of the target.
+ Possible values are: "little" and "big".
+*/
+ODIN_ENDIAN_STRING :: ODIN_ENDIAN_STRING
+
+/*
+ An `enum` value set using the `-error-pos-style` switch, indicating the source location style used for compile errors and warnings.
+ Possible values are: `.Default` (Odin-style) and `.Unix`.
+*/
+ODIN_ERROR_POS_STYLE :: ODIN_ERROR_POS_STYLE
+
+/*
+ `true` if the `-foreign-error-procedures` command line switch is passed,
+ which inhibits generation of runtime error procedures, so that they can be in a separate compilation unit.
+*/
+ODIN_FOREIGN_ERROR_PROCEDURES :: ODIN_FOREIGN_ERROR_PROCEDURES
+
+/*
+ A `string` describing the microarchitecture used for code generation.
+ If not set using the `-microarch` command line switch, the compiler will pick a default.
+ Possible values include, but are not limited to: "sandybridge", "x86-64-v2".
+*/
+ODIN_MICROARCH_STRING :: ODIN_MICROARCH_STRING
+
+/*
+ An `int` value representing the minimum OS version given to the linker, calculated as `major * 10_000 + minor * 100 + revision`.
+ If not set using the `-minimum-os-version` command line switch, it defaults to `0`.
+*/
+ODIN_MINIMUM_OS_VERSION :: ODIN_MINIMUM_OS_VERSION
+
+/*
+ `true` if the `-no-bounds-check` command line switch is passed, which disables bounds checking at runtime.
+*/
+ODIN_NO_BOUNDS_CHECK :: ODIN_NO_BOUNDS_CHECK
+
+/*
+ `true` if the `-no-crt` command line switch is passed, which inhibits linking with the C Runtime Library, a.k.a. LibC.
+*/
+ODIN_NO_CRT :: ODIN_NO_CRT
+
+/*
+ `true` if the `-no-entry-point` command line switch is passed, which makes the declaration of a `main` procedure optional.
+*/
+ODIN_NO_ENTRY_POINT :: ODIN_NO_ENTRY_POINT
+
+/*
+ `true` if the `-no-rtti` command line switch is passed, which inhibits generation of full Runtime Type Information.
+*/
+ODIN_NO_RTTI :: ODIN_NO_RTTI
+
+/*
+ `true` if the `-no-type-assert` command line switch is passed, which disables type assertion checking program wide.
+*/
+ODIN_NO_TYPE_ASSERT :: ODIN_NO_TYPE_ASSERT
+
+/*
+ An `enum` value indicating the optimization level selected using the `-o` command line switch.
+ Possible values are: `.None`, `.Minimal`, `.Size`, `.Speed`, and `.Aggressive`.
+*/
+ODIN_OPTIMIZATION_MODE :: ODIN_OPTIMIZATION_MODE
+
+/*
+ An `enum` value indicating what the target operating system is.
+*/
+ODIN_OS :: ODIN_OS
+
+/*
+ A `string` indicating what the target operating system is.
+*/
+ODIN_OS_STRING :: ODIN_OS_STRING
+
+/*
+ An `enum` value indicating the platform subtarget, chosen using the `-subtarget` switch.
+ Possible values are: `.Default` `.iOS`, and `.Android`.
+*/
+ODIN_PLATFORM_SUBTARGET :: ODIN_PLATFORM_SUBTARGET
+
+/*
+ A `string` representing the path of the folder containing the Odin compiler,
+ relative to which we expect to find the `base` and `core` package collections.
+*/
+ODIN_ROOT :: ODIN_ROOT
+
+/*
+ A `bit_set` indicating the sanitizer flags set using the `-sanitize` command line switch.
+ Supported flags are `.Address`, `.Memory`, and `.Thread`.
+*/
+ODIN_SANITIZER_FLAGS :: ODIN_SANITIZER_FLAGS
+
+/*
+ `true` if the code is being compiled via an invocation of `odin test`.
+*/
+ODIN_TEST :: ODIN_TEST
+
+/*
+ `true` if built using the experimental Tilde backend.
+*/
+ODIN_TILDE :: ODIN_TILDE
+
+/*
+ `true` if the `-use-separate-modules` command line switch is passed,
+ which builds each package into its own object file, and then links them together, instead of performing a unity build.
+*/
+ODIN_USE_SEPARATE_MODULES :: ODIN_USE_SEPARATE_MODULES
+
+/*
+ `true` if Valgrind integration is supported on the target.
+*/
+ODIN_VALGRIND_SUPPORT :: ODIN_VALGRIND_SUPPORT
+
+/*
+ A `string` which identifies the compiler being used. The official compiler sets this to `"odin"`.
+*/
+ODIN_VENDOR :: ODIN_VENDOR
+
+/*
+ A `string` containing the version of the Odin compiler, typically in the format `dev-YYYY-MM`.
+*/
+ODIN_VERSION :: ODIN_VERSION
+
+/*
+ A `string` containing the Git hash part of the Odin version.
+ Empty if `.git` could not be detected at the time the compiler was built.
+*/
+ODIN_VERSION_HASH :: ODIN_VERSION_HASH
+
+/*
+ An `enum` set by the `-subsystem` flag, specifying which Windows subsystem the PE file was created for.
+ Possible values are:
+ `.Unknown` - Default and only value on non-Windows platforms
+ `.Console` - Default on Windows
+ `.Windows` - Can be used by graphical applications so Windows doesn't open an empty console
+
+ There are some other possible values for e.g. EFI applications, but only Console and Windows are supported.
+
+ See also: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header64
+*/
+ODIN_WINDOWS_SUBSYSTEM :: ODIN_WINDOWS_SUBSYSTEM
+
+/*
+ An `string` set by the `-subsystem` flag, specifying which Windows subsystem the PE file was created for.
+ Possible values are:
+ "UNKNOWN" - Default and only value on non-Windows platforms
+ "CONSOLE" - Default on Windows
+ "WINDOWS" - Can be used by graphical applications so Windows doesn't open an empty console
+
+ There are some other possible values for e.g. EFI applications, but only Console and Windows are supported.
+
+ See also: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header64
+*/
+ODIN_WINDOWS_SUBSYSTEM_STRING :: ODIN_WINDOWS_SUBSYSTEM_STRING
+
+/*
+ `true` if LLVM supports the f16 type.
+*/
+__ODIN_LLVM_F16_SUPPORTED :: __ODIN_LLVM_F16_SUPPORTED
+
+
byte :: u8 // alias
@@ -131,3 +344,6 @@ soa_zip :: proc(slices: ...) -> #soa[]Struct ---
soa_unzip :: proc(value: $S/#soa[]$E) -> (slices: ...) ---
unreachable :: proc() -> ! ---
+
+// Where T is a string, slice, dynamic array, or pointer to an array type
+raw_data :: proc(t: $T) -> rawptr
\ No newline at end of file
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 00594c1b4..9d1685cd7 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -31,6 +31,24 @@ enum TargetOsKind : u16 {
TargetOs_COUNT,
};
+gb_global String target_os_names[TargetOs_COUNT] = {
+ str_lit(""),
+ str_lit("windows"),
+ str_lit("darwin"),
+ str_lit("linux"),
+ str_lit("essence"),
+ str_lit("freebsd"),
+ str_lit("openbsd"),
+ str_lit("netbsd"),
+ str_lit("haiku"),
+
+ str_lit("wasi"),
+ str_lit("js"),
+ str_lit("orca"),
+
+ str_lit("freestanding"),
+};
+
enum TargetArchKind : u16 {
TargetArch_Invalid,
@@ -45,6 +63,17 @@ enum TargetArchKind : u16 {
TargetArch_COUNT,
};
+gb_global String target_arch_names[TargetArch_COUNT] = {
+ str_lit(""),
+ str_lit("amd64"),
+ str_lit("i386"),
+ str_lit("arm32"),
+ str_lit("arm64"),
+ str_lit("wasm32"),
+ str_lit("wasm64p32"),
+ str_lit("riscv64"),
+};
+
enum TargetEndianKind : u8 {
TargetEndian_Little,
TargetEndian_Big,
@@ -52,6 +81,11 @@ enum TargetEndianKind : u8 {
TargetEndian_COUNT,
};
+gb_global String target_endian_names[TargetEndian_COUNT] = {
+ str_lit("little"),
+ str_lit("big"),
+};
+
enum TargetABIKind : u16 {
TargetABI_Default,
@@ -61,7 +95,14 @@ enum TargetABIKind : u16 {
TargetABI_COUNT,
};
+gb_global String target_abi_names[TargetABI_COUNT] = {
+ str_lit(""),
+ str_lit("win64"),
+ str_lit("sysv"),
+};
+
enum Windows_Subsystem : u8 {
+ Windows_Subsystem_UNKNOWN,
Windows_Subsystem_BOOT_APPLICATION,
Windows_Subsystem_CONSOLE, // Default,
Windows_Subsystem_EFI_APPLICATION,
@@ -75,38 +116,23 @@ enum Windows_Subsystem : u8 {
Windows_Subsystem_COUNT,
};
-struct MicroarchFeatureList {
- String microarch;
- String features;
-};
-
-gb_global String target_os_names[TargetOs_COUNT] = {
+gb_global String windows_subsystem_names[Windows_Subsystem_COUNT] = {
str_lit(""),
- str_lit("windows"),
- str_lit("darwin"),
- str_lit("linux"),
- str_lit("essence"),
- str_lit("freebsd"),
- str_lit("openbsd"),
- str_lit("netbsd"),
- str_lit("haiku"),
-
- str_lit("wasi"),
- str_lit("js"),
- str_lit("orca"),
-
- str_lit("freestanding"),
+ str_lit("BOOT_APPLICATION"),
+ str_lit("CONSOLE"), // Default
+ str_lit("EFI_APPLICATION"),
+ str_lit("EFI_BOOT_SERVICE_DRIVER"),
+ str_lit("EFI_ROM"),
+ str_lit("EFI_RUNTIME_DRIVER"),
+ str_lit("NATIVE"),
+ str_lit("POSIX"),
+ str_lit("WINDOWS"),
+ str_lit("WINDOWSCE"),
};
-gb_global String target_arch_names[TargetArch_COUNT] = {
- str_lit(""),
- str_lit("amd64"),
- str_lit("i386"),
- str_lit("arm32"),
- str_lit("arm64"),
- str_lit("wasm32"),
- str_lit("wasm64p32"),
- str_lit("riscv64"),
+struct MicroarchFeatureList {
+ String microarch;
+ String features;
};
#if defined(GB_SYSTEM_WINDOWS)
@@ -114,20 +140,8 @@ gb_global String target_arch_names[TargetArch_COUNT] = {
#else
#include
#endif
-
#include "build_settings_microarch.cpp"
-gb_global String target_endian_names[TargetEndian_COUNT] = {
- str_lit("little"),
- str_lit("big"),
-};
-
-gb_global String target_abi_names[TargetABI_COUNT] = {
- str_lit(""),
- str_lit("win64"),
- str_lit("sysv"),
-};
-
gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
TargetEndian_Little,
TargetEndian_Little,
@@ -138,19 +152,6 @@ gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
TargetEndian_Little,
};
-gb_global String windows_subsystem_names[Windows_Subsystem_COUNT] = {
- str_lit("BOOT_APPLICATION"),
- str_lit("CONSOLE"), // Default
- str_lit("EFI_APPLICATION"),
- str_lit("EFI_BOOT_SERVICE_DRIVER"),
- str_lit("EFI_ROM"),
- str_lit("EFI_RUNTIME_DRIVER"),
- str_lit("NATIVE"),
- str_lit("POSIX"),
- str_lit("WINDOWS"),
- str_lit("WINDOWSCE"),
-};
-
#ifndef ODIN_VERSION_RAW
#define ODIN_VERSION_RAW "dev-unknown-unknown"
#endif
@@ -393,17 +394,17 @@ String linker_choices[Linker_COUNT] = {
// This stores the information for the specify architecture of this build
struct BuildContext {
// Constants
- String ODIN_OS; // Target operating system
- String ODIN_ARCH; // Target architecture
- String ODIN_VENDOR; // Compiler vendor
- String ODIN_VERSION; // Compiler version
- String ODIN_ROOT; // Odin ROOT
- String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name
- String ODIN_WINDOWS_SUBSYSTEM; // Empty string for non-Windows targets
- bool ODIN_DEBUG; // Odin in debug mode
- bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
- bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
- bool ODIN_DEFAULT_TO_PANIC_ALLOCATOR; // Whether the default allocator is a "panic" allocator or not (i.e. panics on any call to it)
+ String ODIN_OS; // Target operating system
+ String ODIN_ARCH; // Target architecture
+ String ODIN_VENDOR; // Compiler vendor
+ String ODIN_VERSION; // Compiler version
+ String ODIN_ROOT; // Odin ROOT
+ String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name
+ Windows_Subsystem ODIN_WINDOWS_SUBSYSTEM; // .Console, .Windows
+ bool ODIN_DEBUG; // Odin in debug mode
+ bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
+ bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
+ bool ODIN_DEFAULT_TO_PANIC_ALLOCATOR; // Whether the default allocator is a "panic" allocator or not (i.e. panics on any call to it)
bool ODIN_FOREIGN_ERROR_PROCEDURES;
bool ODIN_VALGRIND_SUPPORT;
@@ -1788,8 +1789,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
}
// Default to subsystem:CONSOLE on Windows targets
- if (bc->ODIN_WINDOWS_SUBSYSTEM == "" && bc->metrics.os == TargetOs_windows) {
- bc->ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_CONSOLE];
+ if (bc->ODIN_WINDOWS_SUBSYSTEM == Windows_Subsystem_UNKNOWN && bc->metrics.os == TargetOs_windows) {
+ bc->ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem_CONSOLE;
}
if (subtarget == Subtarget_Android) {
diff --git a/src/checker.cpp b/src/checker.cpp
index aaa815365..9bc02cd87 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1078,11 +1078,30 @@ gb_internal void init_universal(void) {
add_global_bool_constant("true", true);
add_global_bool_constant("false", false);
- add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR);
- add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
- add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
- add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME);
- add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM);
+ add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR);
+ add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
+ add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
+ add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME);
+
+ {
+ GlobalEnumValue values[Windows_Subsystem_COUNT] = {
+ {"Unknown", Windows_Subsystem_UNKNOWN},
+ {"Boot_Application", Windows_Subsystem_BOOT_APPLICATION},
+ {"Console", Windows_Subsystem_CONSOLE},
+ {"EFI_Application", Windows_Subsystem_EFI_APPLICATION},
+ {"EFI_Boot_Service_Driver", Windows_Subsystem_EFI_BOOT_SERVICE_DRIVER},
+ {"EFI_Rom", Windows_Subsystem_EFI_ROM},
+ {"EFI_Runtime_Driver", Windows_Subsystem_EFI_RUNTIME_DRIVER},
+ {"Native", Windows_Subsystem_NATIVE},
+ {"Posix", Windows_Subsystem_POSIX},
+ {"Windows", Windows_Subsystem_WINDOWS},
+ {"Windows_CE", Windows_Subsystem_WINDOWSCE},
+ };
+
+ auto fields = add_global_enum_type(str_lit("Odin_Windows_Subsystem_Type"), values, gb_count_of(values));
+ add_global_enum_constant(fields, "ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM);
+ add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM_STRING", windows_subsystem_names[bc->ODIN_WINDOWS_SUBSYSTEM]);
+ }
{
GlobalEnumValue values[TargetOs_COUNT] = {
@@ -1102,7 +1121,7 @@ gb_internal void init_universal(void) {
};
auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values));
- add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os);
+ add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os);
add_global_string_constant("ODIN_OS_STRING", target_os_names[bc->metrics.os]);
}
diff --git a/src/linker.cpp b/src/linker.cpp
index 447d66d0a..71aee3a3b 100644
--- a/src/linker.cpp
+++ b/src/linker.cpp
@@ -321,7 +321,7 @@ try_cross_linking:;
"",
LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename),
link_settings,
- LIT(build_context.ODIN_WINDOWS_SUBSYSTEM),
+ LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
LIT(build_context.link_flags),
LIT(build_context.extra_linker_flags),
lib_str
@@ -341,7 +341,7 @@ try_cross_linking:;
"",
LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename),
link_settings,
- LIT(build_context.ODIN_WINDOWS_SUBSYSTEM),
+ LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
LIT(build_context.link_flags),
LIT(build_context.extra_linker_flags),
lib_str
@@ -404,7 +404,7 @@ try_cross_linking:;
"",
LIT(vs_exe_path), LIT(linker_name), object_files, LIT(res_path), LIT(output_filename),
link_settings,
- LIT(build_context.ODIN_WINDOWS_SUBSYSTEM),
+ LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
LIT(build_context.link_flags),
LIT(build_context.extra_linker_flags),
lib_str
diff --git a/src/main.cpp b/src/main.cpp
index 1ffdd0dba..dfc2f3213 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1627,9 +1627,9 @@ gb_internal bool parse_build_flags(Array args) {
GB_ASSERT(value.kind == ExactValue_String);
String subsystem = value.value_string;
bool subsystem_found = false;
- for (int i = 0; i < Windows_Subsystem_COUNT; i++) {
+ for (int i = 1; i < Windows_Subsystem_COUNT; i++) {
if (str_eq_ignore_case(subsystem, windows_subsystem_names[i])) {
- build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[i];
+ build_context.ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem(i);
subsystem_found = true;
break;
}
@@ -1638,7 +1638,7 @@ gb_internal bool parse_build_flags(Array args) {
// WINDOW is a hidden alias for WINDOWS. Check it.
String subsystem_windows_alias = str_lit("WINDOW");
if (!subsystem_found && str_eq_ignore_case(subsystem, subsystem_windows_alias)) {
- build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_WINDOWS];
+ build_context.ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem_WINDOWS;
subsystem_found = true;
break;
}
@@ -1646,8 +1646,8 @@ gb_internal bool parse_build_flags(Array args) {
if (!subsystem_found) {
gb_printf_err("Invalid -subsystem string, got %.*s. Expected one of:\n", LIT(subsystem));
gb_printf_err("\t");
- for (int i = 0; i < Windows_Subsystem_COUNT; i++) {
- if (i > 0) {
+ for (int i = 1; i < Windows_Subsystem_COUNT; i++) {
+ if (i > 1) {
gb_printf_err(", ");
}
gb_printf_err("%.*s", LIT(windows_subsystem_names[i]));
--
cgit v1.2.3
From 349a34cb1ae1e37f791aaf44dc0a298aff4e1e78 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Sun, 1 Jun 2025 13:37:26 +0200
Subject: Also delete .pdb unless -keep-executable is supplied
---
src/main.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index dfc2f3213..b0f839509 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3889,6 +3889,14 @@ end_of_code_gen:;
if (!build_context.keep_executable) {
char const *filename = cast(char const *)exe_name.text;
gb_file_remove(filename);
+
+ if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) {
+ String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]);
+ defer (gb_free(heap_allocator(), pdb_path.text));
+
+ filename = cast(char const *)pdb_path.text;
+ gb_file_remove(filename);
+ }
}
}
return 0;
--
cgit v1.2.3
From 405bf7cd5549edd1f718fce2b53f845dde6fe690 Mon Sep 17 00:00:00 2001
From: Jeroen van Rijn
Date: Sun, 1 Jun 2025 15:59:38 +0200
Subject: Also clean up .dSym on Darwin
---
src/build_settings.cpp | 28 ++++++++++++++++++----------
src/linker.cpp | 6 +++---
src/main.cpp | 12 +++++++-----
3 files changed, 28 insertions(+), 18 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index e0ca03a61..2c444f4eb 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -288,7 +288,7 @@ enum BuildPath : u8 {
BuildPath_VS_LIB, // vs_library_path
BuildPath_Output, // Output Path for .exe, .dll, .so, etc. Can be overridden with `-out:`.
- BuildPath_PDB, // Output Path for .pdb file, can be overridden with `-pdb-name:`.
+ BuildPath_Symbols, // Output Path for .pdb or .dSym file, can be overridden with `-pdb-name:`.
BuildPathCOUNT,
};
@@ -2292,15 +2292,23 @@ gb_internal bool init_build_paths(String init_filename) {
bc->build_paths[BuildPath_Output] = output_path;
}
- if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) {
- if (bc->pdb_filepath.len > 0) {
- bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath);
- } else {
- Path pdb_path;
- pdb_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename);
- pdb_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name);
- pdb_path.ext = copy_string(ha, STR_LIT("pdb"));
- bc->build_paths[BuildPath_PDB] = pdb_path;
+ if (build_context.ODIN_DEBUG) {
+ if (build_context.metrics.os == TargetOs_windows) {
+ if (bc->pdb_filepath.len > 0) {
+ bc->build_paths[BuildPath_Symbols] = path_from_string(ha, bc->pdb_filepath);
+ } else {
+ Path symbol_path;
+ symbol_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename);
+ symbol_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name);
+ symbol_path.ext = copy_string(ha, STR_LIT("pdb"));
+ bc->build_paths[BuildPath_Symbols] = symbol_path;
+ }
+ } else if (build_context.metrics.os == TargetOs_darwin) {
+ Path symbol_path;
+ symbol_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename);
+ symbol_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name);
+ symbol_path.ext = copy_string(ha, STR_LIT("dSym"));
+ bc->build_paths[BuildPath_Symbols] = symbol_path;
}
}
diff --git a/src/linker.cpp b/src/linker.cpp
index f10e47ec3..2210c1306 100644
--- a/src/linker.cpp
+++ b/src/linker.cpp
@@ -281,9 +281,9 @@ try_cross_linking:;
link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup");
}
- if (build_context.build_paths[BuildPath_PDB].name != "") {
- String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]);
- link_settings = gb_string_append_fmt(link_settings, " /PDB:\"%.*s\"", LIT(pdb_path));
+ if (build_context.build_paths[BuildPath_Symbols].name != "") {
+ String symbol_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Symbols]);
+ link_settings = gb_string_append_fmt(link_settings, " /PDB:\"%.*s\"", LIT(symbol_path));
}
if (build_context.build_mode != BuildMode_StaticLibrary) {
diff --git a/src/main.cpp b/src/main.cpp
index b0f839509..af321258c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3890,12 +3890,14 @@ end_of_code_gen:;
char const *filename = cast(char const *)exe_name.text;
gb_file_remove(filename);
- if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) {
- String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]);
- defer (gb_free(heap_allocator(), pdb_path.text));
+ if (build_context.ODIN_DEBUG) {
+ if (build_context.metrics.os == TargetOs_windows || build_context.metrics.os == TargetOs_darwin) {
+ String symbol_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Symbols]);
+ defer (gb_free(heap_allocator(), symbol_path.text));
- filename = cast(char const *)pdb_path.text;
- gb_file_remove(filename);
+ filename = cast(char const *)symbol_path.text;
+ gb_file_remove(filename);
+ }
}
}
}
--
cgit v1.2.3
From 16b8da6a79dcfeb02c3e7b3ff47df0d56bf88f1d Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Mon, 2 Jun 2025 07:47:19 -0400
Subject: Let `-test-all-packages` work with `-build-mode:test`
Fixes #3930
---
src/main.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index af321258c..3ca84b870 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -596,7 +596,7 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_ObfuscateSourceCodeLocations, str_lit("obfuscate-source-code-locations"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc);
- add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc | Command_test);
+ add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc | Command_test | Command_build);
add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc);
add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all);
@@ -1733,6 +1733,12 @@ gb_internal bool parse_build_flags(Array args) {
bad_flags = true;
}
+
+ if ((build_context.command_kind & (Command_doc | Command_test)) == 0 && build_context.test_all_packages) {
+ gb_printf_err("`-test-all-packages` can only be used with `odin build -build-mode:test`, `odin test`, or `odin doc`.\n");
+ bad_flags = true;
+ }
+
return !bad_flags;
}
--
cgit v1.2.3
From 9ba68f20245bce78a21f237615d9c393b49c8e35 Mon Sep 17 00:00:00 2001
From: Bambo-Borris
Date: Mon, 2 Jun 2025 12:48:45 +0100
Subject: Correct spelling in `odin doc -help` output
---
src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index af321258c..b7c3e5abc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2671,7 +2671,7 @@ gb_internal int print_show_help(String const arg0, String command, String option
if (doc) {
if (print_flag("-out:")) {
- print_usage_line(2, "Sets the base name of the resultig .odin-doc file.");
+ print_usage_line(2, "Sets the base name of the resulting .odin-doc file.");
print_usage_line(2, "The extension can be optionally included; the resulting file will always have an extension of '.odin-doc'.");
print_usage_line(2, "Example: -out:foo");
}
--
cgit v1.2.3
From 68ed6315829fabc182a8d2e6e73d2b4e6485022b Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Tue, 3 Jun 2025 21:20:53 -0400
Subject: Forbid multiple uses of `-sanitize`
`clang` does not allow this.
Fixes #4354
---
src/main.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index 531bbe98e..ad07c9a12 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1555,6 +1555,11 @@ gb_internal bool parse_build_flags(Array args) {
case BuildFlag_Sanitize:
GB_ASSERT(value.kind == ExactValue_String);
+ if (build_context.sanitizer_flags != 0) {
+ gb_printf_err("-sanitize: may only be used once\n");
+ bad_flags = true;
+ }
+
if (str_eq_ignore_case(value.value_string, str_lit("address"))) {
build_context.sanitizer_flags |= SanitizerFlag_Address;
} else if (str_eq_ignore_case(value.value_string, str_lit("memory"))) {
@@ -2728,7 +2733,6 @@ gb_internal int print_show_help(String const arg0, String command, String option
print_usage_line(3, "-sanitize:address");
print_usage_line(3, "-sanitize:memory");
print_usage_line(3, "-sanitize:thread");
- print_usage_line(2, "NOTE: This flag can be used multiple times.");
}
}
--
cgit v1.2.3
From b0d050dd90561c466a800dd4b7e5bb6d6bcaa499 Mon Sep 17 00:00:00 2001
From: Feoramund <161657516+Feoramund@users.noreply.github.com>
Date: Wed, 4 Jun 2025 13:59:31 -0400
Subject: Print timings to stderr instead of stdout
This is in line with other diagnostic messages.
Fixes #4642
---
src/main.cpp | 104 ++++++++++++++++++++++++++++----------------------------
src/timings.cpp | 4 +--
2 files changed, 54 insertions(+), 54 deletions(-)
(limited to 'src/main.cpp')
diff --git a/src/main.cpp b/src/main.cpp
index ad07c9a12..d7fb66f99 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1996,39 +1996,39 @@ gb_internal void show_timings(Checker *c, Timings *t) {
if (build_context.show_debug_messages && build_context.show_more_timings) {
{
- gb_printf("\n");
- gb_printf("Total Lines - %td\n", lines);
- gb_printf("Total Tokens - %td\n", tokens);
- gb_printf("Total Files - %td\n", files);
- gb_printf("Total Packages - %td\n", packages);
- gb_printf("Total File Size - %td\n", total_file_size);
- gb_printf("\n");
+ gb_printf_err("\n");
+ gb_printf_err("Total Lines - %td\n", lines);
+ gb_printf_err("Total Tokens - %td\n", tokens);
+ gb_printf_err("Total Files - %td\n", files);
+ gb_printf_err("Total Packages - %td\n", packages);
+ gb_printf_err("Total File Size - %td\n", total_file_size);
+ gb_printf_err("\n");
}
{
f64 time = total_tokenizing_time;
- gb_printf("Tokenization Only\n");
- gb_printf("LOC/s - %.3f\n", cast(f64)lines/time);
- gb_printf("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
- gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/time);
- gb_printf("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
- gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/time);
- gb_printf("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
- gb_printf("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
+ gb_printf_err("Tokenization Only\n");
+ gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/time);
+ gb_printf_err("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
+ gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/time);
+ gb_printf_err("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
+ gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/time);
+ gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
+ gb_printf_err("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
- gb_printf("\n");
+ gb_printf_err("\n");
}
{
f64 time = total_parsing_time;
- gb_printf("Parsing Only\n");
- gb_printf("LOC/s - %.3f\n", cast(f64)lines/time);
- gb_printf("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
- gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/time);
- gb_printf("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
- gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/time);
- gb_printf("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
- gb_printf("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
+ gb_printf_err("Parsing Only\n");
+ gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/time);
+ gb_printf_err("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
+ gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/time);
+ gb_printf_err("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
+ gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/time);
+ gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
+ gb_printf_err("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
- gb_printf("\n");
+ gb_printf_err("\n");
}
{
TimeStamp ts = {};
@@ -2041,16 +2041,16 @@ gb_internal void show_timings(Checker *c, Timings *t) {
GB_ASSERT(ts.label == "parse files");
f64 parse_time = time_stamp_as_s(ts, t->freq);
- gb_printf("Parse pass\n");
- gb_printf("LOC/s - %.3f\n", cast(f64)lines/parse_time);
- gb_printf("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
- gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/parse_time);
- gb_printf("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens);
- gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time);
- gb_printf("MiB/s - %.3f\n", cast(f64)(total_file_size/parse_time)/(1024*1024));
- gb_printf("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size);
+ gb_printf_err("Parse pass\n");
+ gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/parse_time);
+ gb_printf_err("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
+ gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/parse_time);
+ gb_printf_err("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens);
+ gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time);
+ gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/parse_time)/(1024*1024));
+ gb_printf_err("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size);
- gb_printf("\n");
+ gb_printf_err("\n");
}
{
TimeStamp ts = {};
@@ -2071,27 +2071,27 @@ gb_internal void show_timings(Checker *c, Timings *t) {
ts.finish = ts_end.finish;
f64 parse_time = time_stamp_as_s(ts, t->freq);
- gb_printf("Checker pass\n");
- gb_printf("LOC/s - %.3f\n", cast(f64)lines/parse_time);
- gb_printf("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
- gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/parse_time);
- gb_printf("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens);
- gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time);
- gb_printf("MiB/s - %.3f\n", (cast(f64)total_file_size/parse_time)/(1024*1024));
- gb_printf("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size);
- gb_printf("\n");
+ gb_printf_err("Checker pass\n");
+ gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/parse_time);
+ gb_printf_err("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
+ gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/parse_time);
+ gb_printf_err("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens);
+ gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time);
+ gb_printf_err("MiB/s - %.3f\n", (cast(f64)total_file_size/parse_time)/(1024*1024));
+ gb_printf_err("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size);
+ gb_printf_err("\n");
}
{
f64 total_time = t->total_time_seconds;
- gb_printf("Total pass\n");
- gb_printf("LOC/s - %.3f\n", cast(f64)lines/total_time);
- gb_printf("us/LOC - %.3f\n", 1.0e6*total_time/cast(f64)lines);
- gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/total_time);
- gb_printf("us/Token - %.3f\n", 1.0e6*total_time/cast(f64)tokens);
- gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/total_time);
- gb_printf("MiB/s - %.3f\n", cast(f64)(total_file_size/total_time)/(1024*1024));
- gb_printf("us/bytes - %.3f\n", 1.0e6*total_time/cast(f64)total_file_size);
- gb_printf("\n");
+ gb_printf_err("Total pass\n");
+ gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/total_time);
+ gb_printf_err("us/LOC - %.3f\n", 1.0e6*total_time/cast(f64)lines);
+ gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/total_time);
+ gb_printf_err("us/Token - %.3f\n", 1.0e6*total_time/cast(f64)tokens);
+ gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/total_time);
+ gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/total_time)/(1024*1024));
+ gb_printf_err("us/bytes - %.3f\n", 1.0e6*total_time/cast(f64)total_file_size);
+ gb_printf_err("\n");
}
}
}
diff --git a/src/timings.cpp b/src/timings.cpp
index 3f8402b36..f6e86867f 100644
--- a/src/timings.cpp
+++ b/src/timings.cpp
@@ -197,7 +197,7 @@ gb_internal void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Mill
f64 total_time = time_stamp(t->total, t->freq, unit);
- gb_printf("%.*s%.*s - % 9.3f %s - %6.2f%%\n",
+ gb_printf_err("%.*s%.*s - % 9.3f %s - %6.2f%%\n",
LIT(t->total.label),
cast(int)(max_len-t->total.label.len), SPACES,
total_time,
@@ -207,7 +207,7 @@ gb_internal void timings_print_all(Timings *t, TimingUnit unit = TimingUnit_Mill
for_array(i, t->sections) {
TimeStamp ts = t->sections[i];
f64 section_time = time_stamp(ts, t->freq, unit);
- gb_printf("%.*s%.*s - % 9.3f %s - %6.2f%%\n",
+ gb_printf_err("%.*s%.*s - % 9.3f %s - %6.2f%%\n",
LIT(ts.label),
cast(int)(max_len-ts.label.len), SPACES,
section_time,
--
cgit v1.2.3