fp: Improve the CPP build script
This commit is contained in:
parent
1ea15d00e0
commit
e281aa5b39
2
External/tely
vendored
2
External/tely
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a131934ffcc917dda53e0084ff7c3a136b6250ec
|
Subproject commit 798d1a7d5d98801161992259e24e4aa0c926c14f
|
@ -103,7 +103,7 @@ set msvc_sprite_packer_cmd=cl %common_compile_flags% %code_dir%\feely_pona_s
|
|||||||
powershell -Command "$duration = Measure-Command {%msvc_sprite_packer_cmd% | Out-Default}; Write-Host 'msvc (sprite packer):' $duration.TotalSeconds 'seconds'"
|
powershell -Command "$duration = Measure-Command {%msvc_sprite_packer_cmd% | Out-Default}; Write-Host 'msvc (sprite packer):' $duration.TotalSeconds 'seconds'"
|
||||||
powershell -Command "$duration = Measure-Command {%msvc_no_dll_cmd% | Out-Default}; Write-Host 'msvc (no-dll):' $duration.TotalSeconds 'seconds'"
|
powershell -Command "$duration = Measure-Command {%msvc_no_dll_cmd% | Out-Default}; Write-Host 'msvc (no-dll):' $duration.TotalSeconds 'seconds'"
|
||||||
|
|
||||||
REM cl /nologo /Z7 %code_dir%\feely_pona_build.cpp
|
cl /nologo /Z7 %code_dir%\feely_pona_build.cpp
|
||||||
|
|
||||||
popd
|
popd
|
||||||
exit /B 1
|
exit /B 1
|
||||||
|
@ -1,45 +1,78 @@
|
|||||||
// #include <Windows.h>
|
// #include <Windows.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define DQN_IMPLEMENTATION
|
#define DQN_IMPLEMENTATION
|
||||||
#include "External/tely/External/dqn/dqn.h"
|
#include "External/tely/External/dqn/dqn.h"
|
||||||
|
|
||||||
struct Dqn_OSRunCommandAsyncResult
|
struct Dqn_OSExecuteAsyncHandle
|
||||||
{
|
{
|
||||||
void *process;
|
void *process;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_OSRunCommandResult
|
struct Dqn_OSExecuteResult
|
||||||
{
|
{
|
||||||
uint32_t os_error_code;
|
uint32_t os_error_code;
|
||||||
uint32_t exit_code;
|
uint32_t exit_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
Dqn_OSRunCommandResult Dqn_OS_RunCommandWait(Dqn_OSRunCommandAsyncResult run_cmd)
|
struct Dqn_CPPBuildCompileFile
|
||||||
{
|
{
|
||||||
Dqn_OSRunCommandResult result = {};
|
Dqn_Slice<Dqn_String8> flags;
|
||||||
DWORD exec_result = WaitForSingleObject(run_cmd.process, INFINITE);
|
Dqn_String8 path;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Dqn_CPPBuildContext
|
||||||
|
{
|
||||||
|
Dqn_Slice<Dqn_CPPBuildCompileFile> compile_files;
|
||||||
|
Dqn_Slice<Dqn_String8> compile_flags;
|
||||||
|
Dqn_Slice<Dqn_String8> include_dirs;
|
||||||
|
Dqn_Slice<Dqn_String8> link_flags;
|
||||||
|
Dqn_String8 build_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Dqn_CPPBuildStatus
|
||||||
|
{
|
||||||
|
Dqn_CPPBuildStatus_Ok,
|
||||||
|
Dqn_CPPBuildStatus_BuildDirectoryFailedToBeMade,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Dqn_CPPBuildAsyncResult
|
||||||
|
{
|
||||||
|
Dqn_CPPBuildStatus status;
|
||||||
|
Dqn_OSExecuteAsyncHandle async_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
Dqn_OSExecuteResult Dqn_OS_ExecuteWait(Dqn_OSExecuteAsyncHandle handle)
|
||||||
|
{
|
||||||
|
Dqn_OSExecuteResult result = {};
|
||||||
|
if (!handle.process)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
DWORD exec_result = WaitForSingleObject(handle.process, INFINITE);
|
||||||
if (exec_result == WAIT_FAILED) {
|
if (exec_result == WAIT_FAILED) {
|
||||||
result.os_error_code = GetLastError();
|
result.os_error_code = GetLastError();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD exit_status;
|
DWORD exit_status;
|
||||||
if (!GetExitCodeProcess(run_cmd.process, &exit_status)) {
|
if (!GetExitCodeProcess(handle.process, &exit_status)) {
|
||||||
result.os_error_code = GetLastError();
|
result.os_error_code = GetLastError();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.exit_code = exit_status;
|
result.exit_code = exit_status;
|
||||||
CloseHandle(run_cmd.process);
|
CloseHandle(handle.process);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dqn_OSRunCommandAsyncResult Dqn_OS_RunCommandAsync(Dqn_String8 cmd)
|
Dqn_OSExecuteAsyncHandle Dqn_OS_ExecuteAsync(Dqn_String8 cmd, Dqn_String8 working_dir)
|
||||||
{
|
{
|
||||||
Dqn_OSRunCommandAsyncResult result = {};
|
Dqn_OSExecuteAsyncHandle result = {};
|
||||||
#if defined(DQN_OS_WIN32)
|
#if defined(DQN_OS_WIN32)
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
Dqn_String16 cmd16 = Dqn_Win_String8ToString16(scratch.arena, cmd);
|
Dqn_String16 cmd16 = Dqn_Win_String8ToString16(scratch.arena, cmd);
|
||||||
|
Dqn_String16 working_dir16 = Dqn_Win_String8ToString16(scratch.arena, working_dir);
|
||||||
|
|
||||||
PROCESS_INFORMATION proc_info = {};
|
PROCESS_INFORMATION proc_info = {};
|
||||||
STARTUPINFOW startup_info = {};
|
STARTUPINFOW startup_info = {};
|
||||||
@ -48,82 +81,353 @@ Dqn_OSRunCommandAsyncResult Dqn_OS_RunCommandAsync(Dqn_String8 cmd)
|
|||||||
startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
BOOL create_result = CreateProcessW(nullptr, cmd16.data, nullptr, nullptr, true, 0, nullptr, nullptr, &startup_info, &proc_info);
|
BOOL create_result = CreateProcessW(nullptr, cmd16.data, nullptr, nullptr, true, 0, nullptr, working_dir16.data, &startup_info, &proc_info);
|
||||||
if (!create_result)
|
if (!create_result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
CloseHandle(proc_info.hThread);
|
CloseHandle(proc_info.hThread);
|
||||||
result.process = proc_info.hProcess;
|
result.process = proc_info.hProcess;
|
||||||
#else
|
#else
|
||||||
pid_t cpid = fork();
|
pid_t child_pid = fork();
|
||||||
if (cpid < 0) {
|
if (child_pid < 0) {
|
||||||
nob_log(NOB_ERROR, "Could not fork child process: %s", strerror(errno));
|
result.os_error_code = errno;
|
||||||
return NOB_INVALID_PROC;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpid == 0) {
|
if (child_pid == 0) {
|
||||||
// NOTE: This leaks a bit of memory in the child process.
|
if (working_dir.size) {
|
||||||
// But do we actually care? It's a one off leak anyway...
|
if (chdir(working_dir.data) == -1) {
|
||||||
Nob_Cmd cmd_null = {0};
|
result.os_error_code = errno;
|
||||||
nob_da_append_many(&cmd_null, cmd.items, cmd.count);
|
return result;
|
||||||
nob_cmd_append(&cmd_null, NULL);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (execvp(cmd.items[0], (char * const*) cmd_null.items) < 0) {
|
if (execvp(cmd.items[0], (char * const*) cmd_null.items) < 0) {
|
||||||
nob_log(NOB_ERROR, "Could not exec child process: %s", strerror(errno));
|
result.os_error_code = errno;
|
||||||
exit(1);
|
return result;
|
||||||
}
|
}
|
||||||
NOB_ASSERT(0 && "unreachable");
|
DQN_INVALID_CODE_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cpid;
|
result.process = DQN_CAST(void *)child_pid;
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dqn_OSExecuteResult Dqn_OS_Execute(Dqn_String8 cmd, Dqn_String8 working_dir)
|
||||||
|
{
|
||||||
|
Dqn_OSExecuteAsyncHandle async_handle = Dqn_OS_ExecuteAsync(cmd, working_dir);
|
||||||
|
Dqn_OSExecuteResult result = Dqn_OS_ExecuteWait(async_handle);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dqn_String8 Dqn_CPPBuildContext_ToCommandLine(Dqn_CPPBuildContext build_context, Dqn_Allocator allocator)
|
||||||
|
{
|
||||||
|
// NOTE: Check if object files are newer than the source files =================================
|
||||||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(allocator.user_context);
|
||||||
|
Dqn_Slice<Dqn_CPPBuildCompileFile> dirtied_compile_files = Dqn_Slice_Alloc<Dqn_CPPBuildCompileFile>(scratch.arena, build_context.compile_files.size, Dqn_ZeroMem_Yes);
|
||||||
|
dirtied_compile_files.size = 0;
|
||||||
|
DQN_FOR_UINDEX (index, build_context.compile_files.size) {
|
||||||
|
Dqn_CPPBuildCompileFile file = build_context.compile_files.data[index];
|
||||||
|
Dqn_String8 file_stem = Dqn_String8_FileNameNoExtension(file.path);
|
||||||
|
|
||||||
|
Dqn_String8 obj_file = {};
|
||||||
|
if (build_context.build_dir.size)
|
||||||
|
obj_file = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/%.*s.obj", DQN_STRING_FMT(build_context.build_dir), DQN_STRING_FMT(file_stem));
|
||||||
|
else
|
||||||
|
obj_file = Dqn_FsPath_ConvertF(scratch.arena, "%.*s.obj", DQN_STRING_FMT(file_stem));
|
||||||
|
|
||||||
|
Dqn_FsInfo file_info = Dqn_Fs_GetInfo(file.path);
|
||||||
|
Dqn_FsInfo obj_file_info = Dqn_Fs_GetInfo(obj_file);
|
||||||
|
if (obj_file_info.last_write_time_in_s >= file_info.last_write_time_in_s)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dirtied_compile_files.data[dirtied_compile_files.size++] = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dqn_String8 result = {};
|
||||||
|
if (dirtied_compile_files.size <= 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// NOTE: Build the command line invocation =====================================================
|
||||||
|
Dqn_String8Builder builder = {};
|
||||||
|
builder.allocator = allocator;
|
||||||
|
DQN_FOR_UINDEX (index, build_context.compile_flags.size) {
|
||||||
|
Dqn_String8 flag = build_context.compile_flags.data[index];
|
||||||
|
if (index)
|
||||||
|
Dqn_String8Builder_AppendF(&builder, " ");
|
||||||
|
Dqn_String8Builder_AppendRef(&builder, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FOR_UINDEX (index, build_context.include_dirs.size) {
|
||||||
|
Dqn_String8 include_dir = build_context.include_dirs.data[index];
|
||||||
|
if (builder.count)
|
||||||
|
Dqn_String8Builder_AppendF(&builder, " ");
|
||||||
|
Dqn_String8Builder_AppendF(&builder, "/I %.*s", DQN_STRING_FMT(include_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FOR_UINDEX (index, dirtied_compile_files.size) {
|
||||||
|
Dqn_CPPBuildCompileFile file = dirtied_compile_files.data[index];
|
||||||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(allocator.user_context);
|
||||||
|
Dqn_String8 obj_file = {};
|
||||||
|
if (builder.count)
|
||||||
|
Dqn_String8Builder_AppendF(&builder, " ");
|
||||||
|
DQN_FOR_UINDEX (flag_index, file.flags.size) {
|
||||||
|
Dqn_String8 flag = file.flags.data[flag_index];
|
||||||
|
Dqn_String8Builder_AppendF(&builder, "%s%.*s", flag_index ? " " : "", DQN_STRING_FMT(flag));
|
||||||
|
}
|
||||||
|
if (file.flags.size)
|
||||||
|
Dqn_String8Builder_AppendF(&builder, " ");
|
||||||
|
Dqn_String8Builder_AppendRef(&builder, file.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FOR_UINDEX (index, build_context.link_flags.size) {
|
||||||
|
Dqn_String8 file = build_context.link_flags.data[index];
|
||||||
|
if (builder.count)
|
||||||
|
Dqn_String8Builder_AppendF(&builder, " ");
|
||||||
|
Dqn_String8Builder_AppendRef(&builder, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Dqn_String8Builder_Build(&builder, allocator);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dqn_CPPBuildAsyncResult Dqn_CPPBuild_Async(Dqn_CPPBuildContext build_context)
|
||||||
|
{
|
||||||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
|
Dqn_String8 cmd = Dqn_CPPBuildContext_ToCommandLine(build_context, scratch.allocator);
|
||||||
|
Dqn_CPPBuildAsyncResult result = {};
|
||||||
|
if (!cmd.size)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (!Dqn_Fs_MakeDir(build_context.build_dir)) {
|
||||||
|
result.status = Dqn_CPPBuildStatus_BuildDirectoryFailedToBeMade;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.async_handle = Dqn_OS_ExecuteAsync(cmd, build_context.build_dir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dqn_CPPBuild_ExecuteOrAbort(Dqn_CPPBuildContext build_context)
|
||||||
|
{
|
||||||
|
Dqn_CPPBuildAsyncResult build_result = Dqn_CPPBuild_Async(build_context);
|
||||||
|
if (build_result.status == Dqn_CPPBuildStatus_BuildDirectoryFailedToBeMade) {
|
||||||
|
Dqn_Log_ErrorF("Failed to make build dir '%.*s'", DQN_STRING_FMT(build_context.build_dir));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dqn_OSExecuteResult exec_result = Dqn_OS_ExecuteWait(build_result.async_handle);
|
||||||
|
if (exec_result.os_error_code) {
|
||||||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
|
Dqn_WinError error = Dqn_Win_LastError(scratch.arena);
|
||||||
|
Dqn_Log_ErrorF("Build command could not be executed, error returned was (%d): %.*s", error.code, DQN_STRING_FMT(error.msg));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exec_result.exit_code)
|
||||||
|
exit(exec_result.exit_code);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Dqn_Library_Init();
|
Dqn_Library_Init();
|
||||||
Dqn_String8 build_dir = DQN_STRING8("./Build");
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||||||
if (!Dqn_Fs_MakeDir(build_dir)) {
|
Dqn_String8 const exe_dir = Dqn_OS_EXEDir(scratch.arena);
|
||||||
Dqn_Log_ErrorF("Failed to make build dir '%.*s'", DQN_STRING_FMT(build_dir));
|
Dqn_String8 const build_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/Build", DQN_STRING_FMT(exe_dir));
|
||||||
return -1;
|
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));
|
||||||
|
Dqn_OS_Execute(robocopy_cmd, /*working_dir*/ {});
|
||||||
}
|
}
|
||||||
|
|
||||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
// NOTE: Raylib ================================================================================
|
||||||
Dqn_String8 exe_dir = Dqn_OS_EXEDir(scratch.arena);
|
Dqn_CPPBuildContext raylib_build_context = {};
|
||||||
Dqn_String8Builder raylib_cmd_builder = {};
|
Dqn_String8 const raylib_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/External/tely/external/raylib", DQN_STRING_FMT(exe_dir));
|
||||||
raylib_cmd_builder.allocator = scratch.allocator;
|
|
||||||
|
|
||||||
Dqn_String8 raylib_files[] = {
|
uint64_t raylib_timings[2] = {};
|
||||||
DQN_STRING8("rcore.c"),
|
{
|
||||||
DQN_STRING8("utils.c"),
|
raylib_timings[0] = Dqn_OS_PerfCounterNow();
|
||||||
DQN_STRING8("raudio.c"),
|
DQN_DEFER { raylib_timings[1] = Dqn_OS_PerfCounterNow(); };
|
||||||
DQN_STRING8("rmodels.c"),
|
|
||||||
DQN_STRING8("rtext.c"),
|
|
||||||
DQN_STRING8("rtextures.c"),
|
|
||||||
DQN_STRING8("rshapes.c"),
|
|
||||||
DQN_STRING8("rglfw.c"),
|
|
||||||
};
|
|
||||||
|
|
||||||
Dqn_String8 raylib_dir = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/External/tely/external/raylib", DQN_STRING_FMT(exe_dir));
|
raylib_build_context.compile_files = Dqn_Slice_InitCArrayCopy(scratch.arena, {
|
||||||
Dqn_String8 raylib_include_dirs[] = {
|
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/rcore.c", DQN_STRING_FMT(raylib_dir))},
|
||||||
Dqn_FsPath_ConvertF(scratch.arena, "%.*s", DQN_STRING_FMT(raylib_dir)),
|
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/utils.c", DQN_STRING_FMT(raylib_dir))},
|
||||||
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/external/glfw/include", DQN_STRING_FMT(raylib_dir)),
|
Dqn_CPPBuildCompileFile{{}, Dqn_FsPath_ConvertF(scratch.arena, "%.*s/raudio.c", DQN_STRING_FMT(raylib_dir))},
|
||||||
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/glfw/deps/mingw", 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))},
|
||||||
|
});
|
||||||
|
|
||||||
Dqn_String8 compile_flags = DQN_STRING8("/W4 /Z7 /MT /EHsc /nologo");
|
raylib_build_context.include_dirs = Dqn_Slice_InitCArrayCopy(scratch.arena, {
|
||||||
Dqn_String8 link_flags = DQN_STRING8("/link /incremental:no");
|
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)),
|
||||||
|
});
|
||||||
|
|
||||||
Dqn_String8Builder_AppendF(&raylib_cmd_builder, "cl %.*s /w /c /D _DEFAULT_SOURCE /D PLATFORM_DESKTOP", DQN_STRING_FMT(compile_flags));
|
raylib_build_context.compile_flags = Dqn_Slice_InitCArrayCopy(scratch.arena, {
|
||||||
for (Dqn_String8 include_dir : raylib_include_dirs)
|
DQN_STRING8("cl"),
|
||||||
Dqn_String8Builder_AppendF(&raylib_cmd_builder, " /I %.*s", DQN_STRING_FMT(include_dir));
|
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"),
|
||||||
|
});
|
||||||
|
|
||||||
for (Dqn_String8 file_name : raylib_files)
|
raylib_build_context.link_flags = common_link_flags;
|
||||||
Dqn_String8Builder_AppendRef(&raylib_cmd_builder, Dqn_FsPath_ConvertF(scratch.arena, " %.*s/%.*s", DQN_STRING_FMT(raylib_dir), DQN_STRING_FMT(file_name)));
|
raylib_build_context.build_dir = build_dir;
|
||||||
|
|
||||||
Dqn_String8 cmd = Dqn_String8Builder_Build(&raylib_cmd_builder, scratch.allocator);
|
Dqn_CPPBuild_ExecuteOrAbort(raylib_build_context);
|
||||||
Dqn_OSRunCommandAsyncResult run_result = Dqn_OS_RunCommandAsync(cmd);
|
}
|
||||||
Dqn_OS_RunCommandWait(run_result);
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
Dqn_CPPBuild_ExecuteOrAbort(build_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")})},
|
||||||
|
Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_nodll.h", DQN_STRING_FMT(code_dir))
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Dqn_CPPBuild_ExecuteOrAbort(feely_pona_no_dll_build_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
Dqn_CPPBuild_ExecuteOrAbort(build_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
Dqn_CPPBuild_ExecuteOrAbort(build_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "");
|
||||||
|
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): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_platform_timings[0], feely_pona_platform_timings[1]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user