diff --git a/build.c b/build.c index 3061469a..a94a01ef 100644 --- a/build.c +++ b/build.c @@ -71,6 +71,7 @@ typedef struct CompileCommandListNode CompileCommandListNode; struct CompileCommandListNode { String comp_command; String link_file_path; + Bool silent_if_success; CompileCommandListNode *next; CompileCommandListNode *prev; }; @@ -82,11 +83,12 @@ struct CompileCommandList { Size count; }; -void CompileCommandListAppend(Arena *arena, CompileCommandList *l, String comp_command, String link_file_path) +void CompileCommandListAppend(Arena *arena, CompileCommandList *l, String comp_command, String link_file_path, Bool silent_if_success) { CompileCommandListNode *n = ArenaPush(arena, CompileCommandListNode); n->comp_command = comp_command; n->link_file_path = link_file_path; + n->silent_if_success = silent_if_success; DllPushBack(l->first, l->last, n); ++l->count; } @@ -127,15 +129,6 @@ void OnBuild(StringList args_list) { Arena arena = ArenaAlloc(Gigabyte(64)); - CompileCommandList compile_command_list = { 0 }; - - String obj_file_extension = PlatformWindows ? Lit("obj") : Lit("o"); - D_Tag executable = D_FileTagFromPath(&arena, Lit("build/bin/PowerPlay.exe")); - - D_Tag pch_input = D_FileTagFromPath(&arena, Lit("src/common.h")); - D_Tag pch_c_output = D_FileTagFromPath(&arena, Lit("build/common_c.pch")); - D_Tag pch_cpp_output = D_FileTagFromPath(&arena, Lit("build/common_cpp.pch")); - /* ========================== * * Unpack command line args * ========================== */ @@ -160,6 +153,73 @@ void OnBuild(StringList args_list) if (MSVC) CLANG = 0; if (CLANG) MSVC = 0; + /* ========================== * + * Determine output dir + * ========================== */ + + String out_obj_dir_path = { 0 }; + String out_inc_dir_path = { 0 }; + String out_bin_dir_path = { 0 }; + { + StringList out_dir_path_parts = { 0 }; + if (CLANG) { + StringListAppend(&arena, &out_dir_path_parts, Lit("clang")); + } else if (MSVC) { + StringListAppend(&arena, &out_dir_path_parts, Lit("msvc")); + }a + if (DEVELOPER) { + StringListAppend(&arena, &out_dir_path_parts, Lit("developer")); + } else if (MSVC) { + StringListAppend(&arena, &out_dir_path_parts, Lit("user")); + } + if (RTC) { + StringListAppend(&arena, &out_dir_path_parts, Lit("rtc")); + } + if (ASAN) { + StringListAppend(&arena, &out_dir_path_parts, Lit("asan")); + } + if (CRTLIB) { + StringListAppend(&arena, &out_dir_path_parts, Lit("crtlib")); + } + if (DEBINFO) { + StringListAppend(&arena, &out_dir_path_parts, Lit("debinfo")); + } + if (PROFILING) { + StringListAppend(&arena, &out_dir_path_parts, Lit("profiling")); + } + if (UNOPTIMIZED) { + StringListAppend(&arena, &out_dir_path_parts, Lit("unoptimized")); + } + + String out_dir_name = StringFromStringList(&arena, Lit("-"), out_dir_path_parts); + out_obj_dir_path = OS_GetAbsPath(&arena, StringF(&arena, Lit("build/%F/obj/"), FmtStr(out_dir_name))); + out_inc_dir_path = OS_GetAbsPath(&arena, StringF(&arena, Lit("build/%F/inc/"), FmtStr(out_dir_name))); + out_bin_dir_path = OS_GetAbsPath(&arena, StringF(&arena, Lit("build/%F/bin/"), FmtStr(out_dir_name))); + } + + if (!OS_DirExists(out_obj_dir_path)) { + OS_CreateDirAtAbsPath(out_obj_dir_path); + } + if (!OS_DirExists(out_inc_dir_path)) { + OS_CreateDirAtAbsPath(out_inc_dir_path); + } + if (!OS_DirExists(out_bin_dir_path)) { + OS_CreateDirAtAbsPath(out_bin_dir_path); + } + + /* ========================== * + * Constants + * ========================== */ + + CompileCommandList compile_command_list = { 0 }; + + String obj_file_extension = PlatformWindows ? Lit("obj") : Lit("o"); + D_Tag executable = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/PowerPlay.exe"), FmtStr(out_bin_dir_path))); + + D_Tag pch_input = D_FileTagFromPath(&arena, Lit("src/common.h")); + D_Tag pch_c_output = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/common_c.pch"), FmtStr(out_obj_dir_path))); + D_Tag pch_cpp_output = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/common_cpp.pch"), FmtStr(out_obj_dir_path))); + /* ========================== * * Determine compiler args * ========================== */ @@ -182,50 +242,14 @@ void OnBuild(StringList args_list) StringList link_args = { 0 }; -#if 0 -#if Rtc - /* ========================== * - * Verify environment - * ========================== */ - { - I32 error = SH_RunCommand(Lit("where clang-cl.exe"), true); - if (error) { - StringListAppend(&arena, &compile_args, Lit("msdev &&")); - StringListAppend(&arena, &link_args, Lit("msdev &&")); - } - } - -#if 0 - { - /* TODO: Check for MSVC cl & rc */ - if (SH_RunCommand(Lit("where clang-cl.exe"), true)) { - Error(Lit("Could not locate clang-cl.exe")); - OS_Exit(1); - } - if (SH_RunCommand(Lit("where llvm-rc.exe"), true)) { - Error(Lit("Could not locate llvm-rc.exe")); - OS_Exit(1); - } - } -#endif -#endif -#endif - if (CLANG) { #if 1 - //StringListAppend(&arena, &compile_args, Lit("clang -c")); - //StringListAppend(&arena, &link_args, Lit("lld-link")); + StringListAppend(&arena, &c_compile_args, Lit("clang -xc -std=c99 -c %F -o %F")); + StringListAppend(&arena, &pch_c_compile_args, Lit("clang -xc-header -std=c99 -c %F -o %F")); + StringListAppend(&arena, &cpp_compile_args, Lit("clang -xc++ -std=c++20 -c %F -o %F")); + StringListAppend(&arena, &pch_cpp_compile_args, Lit("clang -xc++-header -std=c++20 -c %F -o %F")); - //StringListAppend(&arena, &c_compile_args, Lit("msdev && clang -c -o %F %F -std=c99")); - //StringListAppend(&arena, &pch_c_compile_args, Lit("msdev && clang -c -o %F %F -x c-header -std=c99")); - //StringListAppend(&arena, &cpp_compile_args, Lit("msdev && clang -c -o %F %F -std=c++20")); - //StringListAppend(&arena, &pch_cpp_compile_args, Lit("msdev && clang -c -o %F %F -x c++-header -std=c++20")); - StringListAppend(&arena, &c_compile_args, Lit("msdev && clang -xc -std=c99 -c %F -o %F")); - StringListAppend(&arena, &pch_c_compile_args, Lit("msdev && clang -xc-header -std=c99 -c %F -o %F")); - StringListAppend(&arena, &cpp_compile_args, Lit("msdev && clang -xc++ -std=c++20 -c %F -o %F")); - StringListAppend(&arena, &pch_cpp_compile_args, Lit("msdev && clang -xc++-header -std=c++20 -c %F -o %F")); - - StringListAppend(&arena, &link_args, Lit("msdev && clang %F -o %F")); + StringListAppend(&arena, &link_args, Lit("clang %F -o %F")); #else StringListAppend(&arena, &compile_args, Lit("clang -c")); StringListAppend(&arena, &link_args, Lit("lld-link")); @@ -372,10 +396,11 @@ void OnBuild(StringList args_list) warnings = (StringList) { 0 }; } + String incbin_dir = StringReplace(&arena, out_inc_dir_path, Lit("\\"), Lit("/")); + StringListAppend(&arena, &compile_and_link_args, StringF(&arena, Lit("-DINCBIN_DIR=\"%F\""), FmtStr(incbin_dir))); + final_c_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), c_compile_args, compile_args, compile_and_link_args, warnings); final_cpp_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), cpp_compile_args, compile_args, compile_and_link_args, warnings); - //final_pch_c_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), pch_c_compile_args, compile_args, compile_and_link_args, warnings); - //final_pch_cpp_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), pch_cpp_compile_args, compile_args, compile_and_link_args, warnings); final_pch_c_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), pch_c_compile_args, compile_args, compile_and_link_args); final_pch_cpp_compile_args_fmt = StringFromStringLists(&arena, Lit(" "), pch_cpp_compile_args, compile_args, compile_and_link_args); final_link_args_fmt = StringFromStringLists(&arena, Lit(" "), link_args, compile_and_link_args, warnings); @@ -394,7 +419,7 @@ void OnBuild(StringList args_list) RcIncludeList rc_includes = { 0 }; /* Generate shaders tar */ - D_Tag shaders_tar = D_FileTagFromPath(&arena, Lit("build/shaders.tar")); + D_Tag shaders_tar = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/shaders.tar"), FmtStr(out_inc_dir_path))); D_AddDependency(shaders_tar, shaders_dir); if (embed_in_rc) { RcIncludeListAppend(&arena, &rc_includes, shaders_tar, Lit("RCDATA")); @@ -403,13 +428,12 @@ void OnBuild(StringList args_list) } if (D_IsDirty(shaders_tar)) { String tar_cmd = StringF(&arena, Lit("cd %F && tar cvf %F ."), FmtStr(shaders_dir.full_path), FmtStr(shaders_tar.full_path)); - SH_PrintF(Lit("Running command \"%F\"\n"), FmtStr(tar_cmd)); - I32 error = SH_RunCommand(tar_cmd, false); + CompileCommandListAppend(&arena, &compile_command_list, tar_cmd, (String) { 0 }, true); } /* Generate res tar */ if (!DEVELOPER) { - D_Tag res_tar = D_FileTagFromPath(&arena, Lit("build/res.tar")); + D_Tag res_tar = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/res.tar"), FmtStr(out_inc_dir_path))); D_AddDependency(res_tar, res_dir); if (embed_in_rc) { RcIncludeListAppend(&arena, &rc_includes, res_tar, Lit("RCDATA")); @@ -418,8 +442,7 @@ void OnBuild(StringList args_list) } if (D_IsDirty(res_tar)) { String tar_cmd = StringF(&arena, Lit("cd %F && tar cvf %F ."), FmtStr(res_dir.full_path), FmtStr(res_tar.full_path)); - SH_PrintF(Lit("Running command \"%F\"\n"), FmtStr(tar_cmd)); - I32 error = SH_RunCommand(tar_cmd, false); + CompileCommandListAppend(&arena, &compile_command_list, tar_cmd, (String) { 0 }, true); } } @@ -428,7 +451,7 @@ void OnBuild(StringList args_list) * ========================== */ if (PlatformWindows) { - D_Tag rc_file = D_FileTagFromPath(&arena, Lit("build/rc.rc")); + D_Tag rc_file = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/rc.rc"), FmtStr(out_obj_dir_path)));; /* Add icon file to rc list */ { @@ -451,14 +474,14 @@ void OnBuild(StringList args_list) } /* Append rc -> res compile command */ - D_Tag rc_res_file = D_FileTagFromPath(&arena, Lit("build/rc.res")); + D_Tag rc_res_file = D_FileTagFromPath(&arena, StringF(&arena, Lit("%F/rc.res"), FmtStr(out_obj_dir_path)));; String rc_compile_cmd = { 0 }; if (MSVC) { - rc_compile_cmd = StringF(&arena, Lit("msdev && rc %F"), FmtStr(rc_file.full_path)); + rc_compile_cmd = StringF(&arena, Lit("rc %F"), FmtStr(rc_file.full_path)); } else { - rc_compile_cmd = StringF(&arena, Lit("msdev && llvm-rc %F"), FmtStr(rc_file.full_path)); + rc_compile_cmd = StringF(&arena, Lit("llvm-rc %F"), FmtStr(rc_file.full_path)); } - CompileCommandListAppend(&arena, &compile_command_list, rc_compile_cmd, rc_res_file.full_path); + CompileCommandListAppend(&arena, &compile_command_list, rc_compile_cmd, rc_res_file.full_path, true); } } @@ -470,12 +493,12 @@ void OnBuild(StringList args_list) /* C */ { String comp_cmd = StringF(&arena, final_pch_c_compile_args_fmt, FmtStr(pch_input.full_path), FmtStr(pch_c_output.full_path)); - CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, (String) { 0 }); + CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, (String) { 0 }, true); } /* Cpp */ { String comp_cmd = StringF(&arena, final_pch_cpp_compile_args_fmt, FmtStr(pch_input.full_path), FmtStr(pch_cpp_output.full_path)); - CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, (String) { 0 }); + CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, (String) { 0 }, true); } } @@ -526,14 +549,14 @@ void OnBuild(StringList args_list) if ((extension.len + 1) <= name.len) { name_no_extension.len -= extension.len + 1; } - obj_file_path = StringF(&arena, Lit("build/%F.%F"), FmtStr(name_no_extension), FmtStr(obj_file_extension)); + obj_file_path = StringF(&arena, Lit("%F/%F.%F"), FmtStr(out_obj_dir_path), FmtStr(name_no_extension), FmtStr(obj_file_extension)); obj_file_path = OS_GetAbsPath(&arena, obj_file_path); } String comp_cmd_fmt = is_c ? final_c_compile_args_fmt : final_cpp_compile_args_fmt; String comp_cmd = StringF(&arena, comp_cmd_fmt, FmtStr(file.full_path), FmtStr(obj_file_path)); - CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, obj_file_path); + CompileCommandListAppend(&arena, &compile_command_list, comp_cmd, obj_file_path, true); } /* ========================== * @@ -552,7 +575,10 @@ void OnBuild(StringList args_list) if (comp_cmd.len > 0 ) { //SH_PrintF(Lit("[Comp %F/%F] %F\n"), FmtI64(comp_i), FmtI64(comp_count), FmtStr(comp_cmd)); SH_PrintF(Lit("[Comp %F/%F]\n"), FmtI64(comp_i), FmtI64(comp_count)); - SH_CommandResult result = SH_RunCommandCaptureOutput(&arena, comp_cmd, false); + SH_CommandResult result = SH_RunCommandCaptureOutput(&arena, comp_cmd, true); + if (!n->silent_if_success || result.error != 0) { + SH_PrintF(Lit("%F\n"), result.output); + } if (result.error != 0) { Error(Lit("Compilation failed")); OS_Exit(1); diff --git a/src/common.h b/src/common.h index 3066b4e8..bb6a5e22 100644 --- a/src/common.h +++ b/src/common.h @@ -68,6 +68,10 @@ extern "C" { # define RUN_TESTS 0 #endif +#ifndef INCBIN_DIR +# define INCBIN_DIR "" +#endif + /* ========================== * * Machine context * ========================== */ diff --git a/src/inc.c b/src/inc.c index 10dd4c62..f1e71f2d 100644 --- a/src/inc.c +++ b/src/inc.c @@ -7,14 +7,14 @@ * an embedded file. */ #if RESOURCES_EMBEDDED -INCBIN_INCLUDE(res_tar, "build/res.tar"); +INCBIN_INCLUDE(res_tar, INCBINSTR(INCBIN_DIR) "/res.tar"); struct buffer inc_res_tar(void) { return INCBIN_GET(res_tar); } #endif -INCBIN_INCLUDE(shaders_tar, "build/shaders.tar"); +INCBIN_INCLUDE(shaders_tar, INCBINSTR(INCBIN_DIR) "/shaders.tar"); struct buffer inc_shaders_tar(void) { return INCBIN_GET(shaders_tar);