feely_pona/feely_pona_build.cpp

349 lines
17 KiB
C++
Raw Normal View History

2023-10-10 12:00:35 +00:00
// #include <Windows.h>
2023-10-11 13:04:01 +00:00
#include <stdlib.h>
2023-10-10 12:00:35 +00:00
#define DQN_IMPLEMENTATION
#include "External/tely/External/dqn/dqn.h"
2023-10-12 11:20:29 +00:00
#define DQN_CPP_BUILD_IMPLEMENTATION
#include "External/tely/External/dqn/dqn_cppbuild.h"
2023-10-10 12:00:35 +00:00
2023-10-12 11:20:29 +00:00
#if 0
void RebuildProgramIfRequired(int argc, char const **argv)
2023-10-11 13:04:01 +00:00
{
2023-10-12 11:20:29 +00:00
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
Dqn_String8 const exe_dir = Dqn_OS_EXEDir(scratch.arena);
Dqn_String8 build_program_path = Dqn_OS_EXEPath(scratch.arena);
Dqn_FsInfo build_program_info = Dqn_Fs_GetInfo(build_program_path);
Dqn_FsInfo source_path = Dqn_Fs_GetInfo(Dqn_String8_InitCString8(__FILE__));
if (!build_program_info.exists) {
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
Dqn_Log_WarningF("Failed to get the last write time of the build program '%.*s', skipping rebuild (%d): %.*s",
DQN_STRING_FMT(build_program_path), error.code, DQN_STRING_FMT(error.msg));
return;
2023-10-10 12:00:35 +00:00
}
2023-10-12 11:20:29 +00:00
if (!source_path.exists) {
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
Dqn_Log_WarningF(
"Failed to get the last write time of the build program's source code '%s', skipping rebuild (%d): %.*s",
__FILE__, error.code, DQN_STRING_FMT(error.msg));
return;
2023-10-10 12:00:35 +00:00
}
2023-10-12 11:20:29 +00:00
// NOTE: The build program is newer than the source path, no rebuild required
if (source_path.last_write_time_in_s < build_program_info.last_write_time_in_s) {
return;
2023-10-10 12:00:35 +00:00
}
2023-10-12 11:20:29 +00:00
Dqn_Log_InfoF("Build program source code has changed, rebuilding the program (timestamps changed source was %I64u, build program was %I64u)",
source_path.last_write_time_in_s,
build_program_info.last_write_time_in_s);
2023-10-11 13:04:01 +00:00
2023-10-12 11:20:29 +00:00
Dqn_String8 temp_build_program_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s.old", DQN_STRING_FMT(build_program_path));
if (!Dqn_Fs_Move(build_program_path, temp_build_program_path, true)) {
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
Dqn_Log_WarningF("Failed to backup the build program for rebuilding, skipping rebuild (%d): %.*s", error.code, DQN_STRING_FMT(error.msg));
return;
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
// NOTE: Rebuild the build program because a change was detected ===============
Dqn_String8 rebuild_cmd = Dqn_String8_InitF(scratch.allocator, "cl /Z7 /W4 /nologo %s /incremental:no /link", __FILE__);
Dqn_OSExecResult rebuild_result = Dqn_OS_Exec(rebuild_cmd, exe_dir /*working_dir*/);
if (rebuild_result.os_error_code) {
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
Dqn_Log_ErrorF("Detected change in the build program's source code '%s' but the OS failed to rebuild the program, skipping rebuild (%d): %.*s", __FILE__, error.code, DQN_STRING_FMT(error.msg));
return;
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
if (rebuild_result.exit_code) {
Dqn_Fs_Move(temp_build_program_path, build_program_path, true);
exit(rebuild_result.exit_code);
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
Dqn_String8Builder builder = {};
builder.allocator = scratch.allocator;
DQN_FOR_UINDEX (arg_index, argc)
Dqn_String8Builder_AppendF(&builder, "%s%s", arg_index ? " " : "", argv[arg_index]);
2023-10-11 13:04:01 +00:00
2023-10-12 11:20:29 +00:00
Dqn_String8 rebootstrap_cmd = Dqn_String8Builder_Build(&builder, scratch.allocator);
Dqn_OSExecResult exec_result = Dqn_OS_Exec(rebootstrap_cmd, exe_dir /*working_dir*/);
if (exec_result.os_error_code) {
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
Dqn_Log_ErrorF("Detected change in the build program's source code '%s' but the OS failed to rebuild the program, skipping rebuild (%d): %.*s", __FILE__, error.code, DQN_STRING_FMT(error.msg));
Dqn_Fs_Move(temp_build_program_path, build_program_path, true);
return;
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
exit(exec_result.exit_code);
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
#endif
2023-10-11 13:04:01 +00:00
2023-10-12 11:20:29 +00:00
#define PRINT_HELP Dqn_Print_StdLnF(Dqn_PrintStd_Out, "USAGE: feely_pona_build [--help|--dry-run]")
int main(int argc, char const **argv)
2023-10-11 13:04:01 +00:00
{
2023-10-12 11:20:29 +00:00
Dqn_Library_Init(Dqn_LibraryOnInit_Nil);
if (argc > 2) {
PRINT_HELP;
return -1;
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
bool dry_run = false;
if (argc == 2) {
Dqn_String8 arg = Dqn_String8_InitCString8(argv[1]);
if (arg == DQN_STRING8("--help")) {
PRINT_HELP;
return 0;
}
2023-10-11 13:04:01 +00:00
2023-10-12 11:20:29 +00:00
if (arg == DQN_STRING8("--dry-run")) {
dry_run = true;
} else {
PRINT_HELP;
return 0;
}
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
#if 0
RebuildProgramIfRequired(argc, argv);
#else
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "-- Dqn_CPPBuild v0");
#endif
2023-10-11 13:04:01 +00:00
2023-10-12 11:20:29 +00:00
uint64_t build_timings[2] = {};
build_timings[0] = Dqn_OS_PerfCounterNow();
2023-10-11 13:04:01 +00:00
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
Dqn_String8 const exe_dir = Dqn_OS_EXEDir(scratch.arena);
Dqn_String8 const build_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/Build", DQN_STRING_FMT(exe_dir));
Dqn_String8 const tely_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/External/tely", DQN_STRING_FMT(exe_dir));
Dqn_Slice<Dqn_String8> common_compile_flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {
DQN_STRING8("cl"),
DQN_STRING8("/W4"),
DQN_STRING8("/Z7"),
DQN_STRING8("/MT"),
DQN_STRING8("/EHsc"),
DQN_STRING8("/nologo"),
});
Dqn_Slice<Dqn_String8> common_link_flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {
DQN_STRING8("/link"),
DQN_STRING8("/incremental:no"),
});
// NOTE: Assets ================================================================================
uint64_t robocopy_timings[2] = {};
{
robocopy_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { robocopy_timings[1] = Dqn_OS_PerfCounterNow(); };
Dqn_String8 robocopy_cmd = Dqn_String8_InitF(scratch.allocator, "robocopy /MIR /NJH /NJS /NDL /NP %.*s\\Data %.*s\\Data", DQN_STRING_FMT(exe_dir), DQN_STRING_FMT(build_dir));
2023-10-12 11:20:29 +00:00
if (dry_run) {
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(robocopy_cmd));
} else {
Dqn_OS_Exec(robocopy_cmd, /*working_dir*/ {});
}
2023-10-11 13:04:01 +00:00
}
// NOTE: Raylib ================================================================================
Dqn_CPPBuildContext raylib_build_context = {};
Dqn_String8 const raylib_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/External/tely/external/raylib", DQN_STRING_FMT(exe_dir));
uint64_t raylib_timings[2] = {};
{
raylib_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { raylib_timings[1] = Dqn_OS_PerfCounterNow(); };
raylib_build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rcore.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/utils.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/raudio.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rmodels.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rtext.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rtextures.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rshapes.c", DQN_STRING_FMT(raylib_dir))},
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rglfw.c", DQN_STRING_FMT(raylib_dir))},
});
raylib_build_context.include_dirs = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_FsPath_ConvertF(scratch.arena, "%.*s", DQN_STRING_FMT(raylib_dir)),
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/external/glfw/include", DQN_STRING_FMT(raylib_dir)),
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/glfw/deps/mingw", DQN_STRING_FMT(raylib_dir)),
});
raylib_build_context.compile_flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {
DQN_STRING8("cl"),
DQN_STRING8("/w"),
DQN_STRING8("/c"),
DQN_STRING8("/D _DEFAULT_SOURCE"),
DQN_STRING8("/D PLATFORM_DESKTOP"),
DQN_STRING8("/W4"),
DQN_STRING8("/Z7"),
DQN_STRING8("/MT"),
DQN_STRING8("/EHsc"),
DQN_STRING8("/nologo"),
});
raylib_build_context.link_flags = common_link_flags;
raylib_build_context.build_dir = build_dir;
2023-10-12 11:20:29 +00:00
if (dry_run) {
Dqn_String8 cmd = Dqn_CPPBuild_ToCommandLine(raylib_build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(cmd));
} else {
Dqn_CPPBuild_ExecOrAbort(raylib_build_context, Dqn_CPPBuildMode_CacheBuild);
}
2023-10-11 13:04:01 +00:00
}
// NOTE: Feely Pona Sprite Packer ==============================================================
uint64_t feely_pona_sprite_packer_timings[2] = {};
{
feely_pona_sprite_packer_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { feely_pona_sprite_packer_timings[1] = Dqn_OS_PerfCounterNow(); };
Dqn_String8 code_dir = exe_dir;
Dqn_CPPBuildContext build_context = {};
build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_sprite_packer.h", DQN_STRING_FMT(code_dir)) },
});
build_context.compile_flags = common_compile_flags;
build_context.link_flags = common_link_flags;
build_context.build_dir = build_dir;
2023-10-12 11:20:29 +00:00
Dqn_CPPBuild_ExecOrAbort(build_context, Dqn_CPPBuildMode_CacheBuild);
2023-10-11 13:04:01 +00:00
}
// NOTE: Feely Pona No DLL =====================================================================
uint64_t feely_pona_no_dll_timings[2] = {};
Dqn_CPPBuildContext feely_pona_no_dll_build_context = {};
{
feely_pona_no_dll_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { feely_pona_no_dll_timings[1] = Dqn_OS_PerfCounterNow(); };
Dqn_String8 code_dir = exe_dir;
feely_pona_no_dll_build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_CPPBuildCompileFile{
{Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STRING8("/Tp")})},
2023-10-12 11:20:29 +00:00
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity_nodll.h", DQN_STRING_FMT(code_dir))
2023-10-11 13:04:01 +00:00
},
});
feely_pona_no_dll_build_context.include_dirs = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_FsPath_ConvertF(scratch.arena, "%.*s", DQN_STRING_FMT(raylib_dir)),
});
feely_pona_no_dll_build_context.compile_flags = common_compile_flags;
// NOTE: Link to raylib object files and windows libs ======================================
Dqn_List<Dqn_String8> link_flags = Dqn_List_InitSliceCopy(scratch.arena, 128, common_link_flags);
{
for (Dqn_CPPBuildCompileFile file : raylib_build_context.compile_files) {
Dqn_String8 file_stem = Dqn_String8_FileNameNoExtension(file.path);
Dqn_String8 obj_file = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s.obj", DQN_STRING_FMT(raylib_build_context.build_dir), DQN_STRING_FMT(file_stem));
Dqn_List_Add(&link_flags, obj_file);
}
Dqn_List_Add(&link_flags, DQN_STRING8("gdi32.lib"));
Dqn_List_Add(&link_flags, DQN_STRING8("opengl32.lib"));
Dqn_List_Add(&link_flags, DQN_STRING8("winmm.lib"));
Dqn_List_Add(&link_flags, DQN_STRING8("user32.lib"));
Dqn_List_Add(&link_flags, DQN_STRING8("shell32.lib"));
}
feely_pona_no_dll_build_context.link_flags = Dqn_List_ToSliceCopy(&link_flags, scratch.arena);
feely_pona_no_dll_build_context.build_dir = build_dir;
2023-10-12 11:20:29 +00:00
if (dry_run) {
Dqn_String8 cmd = Dqn_CPPBuild_ToCommandLine(feely_pona_no_dll_build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(cmd));
} else {
Dqn_CPPBuild_ExecOrAbort(feely_pona_no_dll_build_context, Dqn_CPPBuildMode_AlwaysRebuild);
}
2023-10-11 13:04:01 +00:00
}
// NOTE: Feely Pona DLL ========================================================================
uint64_t feely_pona_dll_timings[2] = {};
{
feely_pona_dll_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { feely_pona_dll_timings[1] = Dqn_OS_PerfCounterNow(); };
Dqn_String8 code_dir = exe_dir;
Dqn_CPPBuildContext build_context = {};
build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_CPPBuildCompileFile{
{Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STRING8("/Tp")})},
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_unity.h", DQN_STRING_FMT(code_dir))
},
});
Dqn_List<Dqn_String8> compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 128, common_compile_flags);
Dqn_List_Add(&compile_flags, DQN_STRING8("/LD"));
Dqn_List_Add(&compile_flags, DQN_STRING8("/Fotely_dll_msvc"));
Dqn_List_Add(&compile_flags, DQN_STRING8("/Fetely_dll_msvc"));
build_context.compile_flags = Dqn_List_ToSliceCopy(&compile_flags, scratch.arena);
build_context.link_flags = feely_pona_no_dll_build_context.link_flags;
build_context.build_dir = build_dir;
2023-10-12 11:20:29 +00:00
if (dry_run) {
Dqn_String8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(cmd));
} else {
Dqn_CPPBuild_ExecOrAbort(build_context, Dqn_CPPBuildMode_AlwaysRebuild);
}
2023-10-11 13:04:01 +00:00
}
// NOTE: Feely Pona platform ===================================================================
uint64_t feely_pona_platform_timings[2] = {};
{
feely_pona_platform_timings[0] = Dqn_OS_PerfCounterNow();
DQN_DEFER { feely_pona_platform_timings[1] = Dqn_OS_PerfCounterNow(); };
Dqn_String8 code_dir = exe_dir;
Dqn_CPPBuildContext build_context = {};
build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
Dqn_CPPBuildCompileFile{
{Dqn_Slice_InitCArrayCopy(scratch.arena, {DQN_STRING8("/Tp")})},
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/tely_platform_raylib_unity.h", DQN_STRING_FMT(tely_dir))
},
});
build_context.include_dirs = Dqn_Slice_InitCArrayCopy(scratch.arena, {
raylib_dir,
});
Dqn_List<Dqn_String8> compile_flags = Dqn_List_InitSliceCopy(scratch.arena, 128, common_compile_flags);
Dqn_List_Add(&compile_flags, DQN_STRING8("/Fofeely_pona_msvc"));
Dqn_List_Add(&compile_flags, DQN_STRING8("/Fefeely_pona_msvc"));
build_context.compile_flags = Dqn_List_ToSliceCopy(&compile_flags, scratch.arena);
build_context.link_flags = feely_pona_no_dll_build_context.link_flags;
build_context.build_dir = build_dir;
2023-10-12 11:20:29 +00:00
if (dry_run) {
Dqn_String8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(cmd));
} else {
Dqn_String8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_msvc.exe", DQN_STRING_FMT(build_dir));
bool exe_is_locked = false;
if (Dqn_Fs_Exists(exe_path)) {
Dqn_FsFile exe_file = Dqn_Fs_OpenFile(exe_path, Dqn_FsFileOpen_OpenIfExist, Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write);
exe_is_locked = exe_file.error_size;
}
if (!exe_is_locked) {
Dqn_CPPBuild_ExecOrAbort(build_context, Dqn_CPPBuildMode_AlwaysRebuild);
}
2023-10-12 11:20:29 +00:00
}
2023-10-11 13:04:01 +00:00
}
2023-10-12 11:20:29 +00:00
build_timings[1] = Dqn_OS_PerfCounterNow();
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "\n-- Dqn_CPPBuild Timings (%.2fms)", Dqn_OS_PerfCounterMs(build_timings[0], build_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " robocopy: %.2fms", Dqn_OS_PerfCounterMs(robocopy_timings[0], robocopy_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " raylib: %.2fms", Dqn_OS_PerfCounterMs(raylib_timings[0], raylib_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona sprite packer: %.2fms", Dqn_OS_PerfCounterMs(feely_pona_sprite_packer_timings[0], feely_pona_sprite_packer_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (no dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_no_dll_timings[0], feely_pona_no_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_dll_timings[0], feely_pona_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (platform-raylib): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_platform_timings[0], feely_pona_platform_timings[1]));
2023-10-10 12:00:35 +00:00
return 0;
}