aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2021-05-20 12:15:14 +0200
committerDaniel Gavin <danielgavin5@hotmail.com>2021-05-20 12:15:14 +0200
commit44ee0f2cdc773fc3ba3261de076b8a8a7fb64f03 (patch)
treec408237d1bd2e6bfcb0c5526d9c0d8cdb97bbf69 /src/main.cpp
parent50035f257eb33769211ca49a30c51f9a20440a0e (diff)
parent92abddddc5ca4be622e93856c7246159b594e9e9 (diff)
Merge branch 'master' into prototype-fmt
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp213
1 files changed, 104 insertions, 109 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 251616b56..d16a110e3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -218,8 +218,19 @@ i32 linker_stage(lbGenerator *gen) {
add_path(find_result.vs_library_path);
}
- for_array(i, gen->module.foreign_library_paths) {
- String lib = gen->module.foreign_library_paths[i];
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ for_array(i, m->foreign_library_paths) {
+ String lib = m->foreign_library_paths[i];
+ GB_ASSERT(lib.len < gb_count_of(lib_str_buf)-1);
+ isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
+ " \"%.*s\"", LIT(lib));
+ lib_str = gb_string_appendc(lib_str, lib_str_buf);
+ }
+ }
+
+ for_array(i, gen->default_module.foreign_library_paths) {
+ String lib = gen->default_module.foreign_library_paths[i];
GB_ASSERT(lib.len < gb_count_of(lib_str_buf)-1);
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib));
@@ -265,22 +276,22 @@ i32 linker_stage(lbGenerator *gen) {
LIT(build_context.resource_filepath)
);
- if(result == 0) {
- result = system_exec_command_line_app("msvc-link",
- "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
- "/nologo /incremental:no /opt:ref /subsystem:%s "
- " %.*s "
- " %.*s "
- " %s "
- "",
- LIT(find_result.vs_exe_path), object_files, LIT(output_base), LIT(output_base), output_ext,
- link_settings,
- subsystem_str,
- LIT(build_context.link_flags),
- LIT(build_context.extra_linker_flags),
- lib_str
- );
- }
+ if (result == 0) {
+ result = system_exec_command_line_app("msvc-link",
+ "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
+ "/nologo /incremental:no /opt:ref /subsystem:%s "
+ " %.*s "
+ " %.*s "
+ " %s "
+ "",
+ LIT(find_result.vs_exe_path), object_files, LIT(output_base), LIT(output_base), output_ext,
+ link_settings,
+ subsystem_str,
+ LIT(build_context.link_flags),
+ LIT(build_context.extra_linker_flags),
+ lib_str
+ );
+ }
} else {
result = system_exec_command_line_app("msvc-link",
"\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s "
@@ -327,8 +338,8 @@ i32 linker_stage(lbGenerator *gen) {
gbString lib_str = gb_string_make(heap_allocator(), "-L/");
defer (gb_string_free(lib_str));
- for_array(i, gen->module.foreign_library_paths) {
- String lib = gen->module.foreign_library_paths[i];
+ for_array(i, gen->default_module.foreign_library_paths) {
+ String lib = gen->default_module.foreign_library_paths[i];
// NOTE(zangent): Sometimes, you have to use -framework on MacOS.
// This allows you to specify '-f' in a #foreign_system_library,
@@ -409,6 +420,11 @@ i32 linker_stage(lbGenerator *gen) {
#endif
}
+ if (build_context.metrics.os == TargetOs_linux) {
+ link_settings = gb_string_appendc(link_settings, "-no-pie ");
+ }
+
+
if (build_context.out_filepath.len > 0) {
//NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that
isize pos = string_extension_position(build_context.out_filepath);
@@ -580,6 +596,7 @@ enum BuildFlagKind {
BuildFlag_NoCRT,
BuildFlag_NoEntryPoint,
BuildFlag_UseLLD,
+ BuildFlag_UseSeparateModules,
BuildFlag_Vet,
BuildFlag_VetExtra,
BuildFlag_UseLLVMApi,
@@ -587,6 +604,8 @@ enum BuildFlagKind {
BuildFlag_ExtraLinkerFlags,
BuildFlag_Microarch,
+ BuildFlag_TestName,
+
BuildFlag_DisallowDo,
BuildFlag_DefaultToNilAllocator,
BuildFlag_InsertSemicolon,
@@ -602,6 +621,7 @@ enum BuildFlagKind {
BuildFlag_IgnoreWarnings,
BuildFlag_WarningsAsErrors,
+ BuildFlag_VerboseErrors,
#if defined(GB_SYSTEM_WINDOWS)
BuildFlag_IgnoreVsSearch,
@@ -698,6 +718,7 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test);
add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build);
+ add_flag(&build_flags, BuildFlag_UseSeparateModules,str_lit("use-separate-modules"),BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build);
@@ -705,6 +726,8 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build);
+ add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test);
+
add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_InsertSemicolon, str_lit("insert-semicolon"), BuildFlagParam_None, Command__does_check);
@@ -719,6 +742,7 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all);
+ add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all);
#if defined(GB_SYSTEM_WINDOWS)
add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build);
@@ -1175,6 +1199,10 @@ bool parse_build_flags(Array<String> args) {
build_context.use_lld = true;
break;
+ case BuildFlag_UseSeparateModules:
+ build_context.use_separate_modules = true;
+ break;
+
case BuildFlag_Vet:
build_context.vet = true;
break;
@@ -1203,6 +1231,21 @@ bool parse_build_flags(Array<String> args) {
string_to_lower(&build_context.microarch);
break;
+ case BuildFlag_TestName:
+ GB_ASSERT(value.kind == ExactValue_String);
+ {
+ String name = value.value_string;
+ if (!string_is_valid_identifier(name)) {
+ gb_printf_err("Test name '%.*s' must be a valid identifier\n", LIT(name));
+ bad_flags = true;
+ break;
+ }
+ string_set_add(&build_context.test_names, name);
+
+ // NOTE(bill): Allow for multiple -test-name
+ continue;
+ }
+
case BuildFlag_DisallowDo:
build_context.disallow_do = true;
break;
@@ -1279,6 +1322,10 @@ bool parse_build_flags(Array<String> args) {
}
break;
+ case BuildFlag_VerboseErrors:
+ build_context.show_error_line = true;
+ break;
+
#if defined(GB_SYSTEM_WINDOWS)
case BuildFlag_IgnoreVsSearch:
GB_ASSERT(value.kind == ExactValue_Invalid);
@@ -1507,96 +1554,22 @@ void show_timings(Checker *c, Timings *t) {
}
}
-void remove_temp_files(String output_base) {
+void remove_temp_files(lbGenerator *gen) {
if (build_context.keep_temp_files) return;
- auto data = array_make<u8>(heap_allocator(), output_base.len + 30);
- defer (array_free(&data));
-
- isize n = output_base.len;
- gb_memmove(data.data, output_base.text, n);
-#define EXT_REMOVE(s) do { \
- gb_memmove(data.data+n, s, gb_size_of(s)); \
- gb_file_remove(cast(char const *)data.data); \
- } while (0)
- EXT_REMOVE(".ll");
- EXT_REMOVE(".bc");
- EXT_REMOVE("_memcpy_pass.bc");
- if (build_context.build_mode != BuildMode_Object && !build_context.keep_object_files) {
- #if defined(GB_SYSTEM_WINDOWS)
- EXT_REMOVE(".obj");
- EXT_REMOVE(".res");
- #else
- EXT_REMOVE(".o");
- #endif
+ for_array(i, gen->output_temp_paths) {
+ String path = gen->output_temp_paths[i];
+ gb_file_remove(cast(char const *)path.text);
}
-#undef EXT_REMOVE
-}
-
-
-
-
-i32 exec_llvm_opt(String output_base) {
-#if defined(GB_SYSTEM_WINDOWS)
- // For more passes arguments: http://llvm.org/docs/Passes.html
-
- return system_exec_command_line_app("llvm-opt",
- "\"%.*sbin/opt\" \"%.*s.ll\" -o \"%.*s_memcpy_pass.bc\" -memcpyopt"
- "",
- LIT(build_context.ODIN_ROOT),
- LIT(output_base), LIT(output_base))
-
- || system_exec_command_line_app("llvm-opt",
- "\"%.*sbin/opt\" \"%.*s_memcpy_pass.bc\" -o \"%.*s.bc\" %.*s "
- "",
- LIT(build_context.ODIN_ROOT),
- LIT(output_base), LIT(output_base),
- LIT(build_context.opt_flags));
-#else
- // NOTE(zangent): This is separate because it seems that LLVM tools are packaged
- // with the Windows version, while they will be system-provided on MacOS and GNU/Linux
-
- return system_exec_command_line_app("llvm-opt",
- "opt \"%.*s.ll\" -o \"%.*s_memcpy_pass.bc\" -memcpyopt"
- "",
- LIT(output_base), LIT(output_base))
-
- || system_exec_command_line_app("llvm-opt",
- "opt \"%.*s_memcpy_pass.bc\" -o \"%.*s.bc\" %.*s "
- "",
- LIT(output_base), LIT(output_base),
- LIT(build_context.opt_flags));
-#endif
+ if (build_context.build_mode != BuildMode_Object && !build_context.keep_object_files) {
+ for_array(i, gen->output_object_paths) {
+ String path = gen->output_object_paths[i];
+ gb_file_remove(cast(char const *)path.text);
+ }
+ }
}
-i32 exec_llvm_llc(String output_base) {
- // For more arguments: http://llvm.org/docs/CommandGuide/llc.html
-#if defined(GB_SYSTEM_WINDOWS)
- return system_exec_command_line_app("llvm-llc",
- "\"%.*sbin\\llc\" \"%.*s.bc\" -filetype=obj -O%d "
- "-o \"%.*s.obj\" "
- "%.*s"
- "",
- LIT(build_context.ODIN_ROOT),
- LIT(output_base),
- build_context.optimization_level,
- LIT(output_base),
- LIT(build_context.llc_flags));
-#else
- // NOTE(zangent): Linux / Unix is unfinished and not tested very well.
- return system_exec_command_line_app("llc",
- "llc \"%.*s.bc\" -filetype=obj -relocation-model=pic -O%d "
- "%.*s "
- "%s%.*s",
- LIT(output_base),
- build_context.optimization_level,
- LIT(build_context.llc_flags),
- build_context.cross_compiling ? "-mtriple=" : "",
- cast(int)(build_context.cross_compiling ? build_context.metrics.target_triplet.len : 0),
- build_context.metrics.target_triplet.text);
-#endif
-}
void print_show_help(String const arg0, String const &command) {
print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
@@ -1612,7 +1585,7 @@ void print_show_help(String const arg0, String const &command) {
} else if (command == "check") {
print_usage_line(1, "check parse and type check .odin file");
} else if (command == "test") {
- print_usage_line(1, "test build ands runs 'test_*' procedures in the initial package");
+ print_usage_line(1, "test build ands runs procedures with the attribute @(test) in the initial package");
} else if (command == "query") {
print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program");
} else if (command == "doc") {
@@ -1627,6 +1600,7 @@ void print_show_help(String const arg0, String const &command) {
bool doc = command == "doc";
bool build = command == "build";
bool run_or_build = command == "run" || command == "build" || command == "test";
+ bool test_only = command == "test";
bool check_only = command == "check";
bool check = run_or_build || command == "check";
@@ -1720,6 +1694,11 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(3, "-build-mode:shared Build as a dynamically linked library");
print_usage_line(3, "-build-mode:obj Build as an object file");
print_usage_line(3, "-build-mode:object Build as an object file");
+ print_usage_line(3, "-build-mode:assembly Build as an object file");
+ print_usage_line(3, "-build-mode:assembler Build as an assembly file");
+ print_usage_line(3, "-build-mode:asm Build as an assembly file");
+ print_usage_line(3, "-build-mode:llvm-ir Build as an LLVM IR file");
+ print_usage_line(3, "-build-mode:llvm Build as an LLVM IR file");
print_usage_line(0, "");
}
@@ -1746,9 +1725,16 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(2, "Disables automatic linking with the C Run Time");
print_usage_line(0, "");
- print_usage_line(1, "-use-lld");
+ print_usage_line(1, "-lld");
print_usage_line(2, "Use the LLD linker rather than the default");
print_usage_line(0, "");
+
+ print_usage_line(1, "-use-separate-modules");
+ print_usage_line(1, "[EXPERIMENTAL]");
+ print_usage_line(2, "The backend generates multiple build units which are then linked together");
+ print_usage_line(2, "Normally, a single build unit is generated for a standard project");
+ print_usage_line(0, "");
+
}
if (check) {
@@ -1776,6 +1762,12 @@ void print_show_help(String const arg0, String const &command) {
}
}
+ if (test_only) {
+ print_usage_line(1, "-test-name:<string>");
+ print_usage_line(2, "Run specific test only by name");
+ print_usage_line(0, "");
+ }
+
if (run_or_build) {
print_usage_line(1, "-extra-linker-flags:<string>");
print_usage_line(2, "Adds extra linker specific flags in a string");
@@ -1943,7 +1935,7 @@ int main(int arg_count, char const **arg_ptr) {
Timings *timings = &global_timings;
- timings_init(timings, str_lit("Total Time"), 128);
+ timings_init(timings, str_lit("Total Time"), 2048);
defer (timings_destroy(timings));
arena_init(&permanent_arena, heap_allocator());
@@ -1967,7 +1959,7 @@ int main(int arg_count, char const **arg_ptr) {
map_init(&build_context.defined_values, heap_allocator());
build_context.extra_packages.allocator = heap_allocator();
-
+ string_set_init(&build_context.test_names, heap_allocator());
Array<String> args = setup_args(arg_count, arg_ptr);
@@ -2190,6 +2182,9 @@ int main(int arg_count, char const **arg_ptr) {
case BuildMode_DynamicLibrary:
i32 result = linker_stage(&gen);
if (result != 0) {
+ if (build_context.show_timings) {
+ show_timings(&checker, timings);
+ }
return 1;
}
break;
@@ -2199,7 +2194,7 @@ int main(int arg_count, char const **arg_ptr) {
show_timings(&checker, timings);
}
- remove_temp_files(gen.output_base);
+ remove_temp_files(&gen);
if (run_output) {
#if defined(GB_SYSTEM_WINDOWS)