feely_pona/feely_pona_build.cpp

130 lines
4.6 KiB
C++

// #include <Windows.h>
#define DQN_IMPLEMENTATION
#include "External/tely/External/dqn/dqn.h"
struct Dqn_OSRunCommandAsyncResult
{
void *process;
};
struct Dqn_OSRunCommandResult
{
uint32_t os_error_code;
uint32_t exit_code;
};
Dqn_OSRunCommandResult Dqn_OS_RunCommandWait(Dqn_OSRunCommandAsyncResult run_cmd)
{
Dqn_OSRunCommandResult result = {};
DWORD exec_result = WaitForSingleObject(run_cmd.process, INFINITE);
if (exec_result == WAIT_FAILED) {
result.os_error_code = GetLastError();
return result;
}
DWORD exit_status;
if (!GetExitCodeProcess(run_cmd.process, &exit_status)) {
result.os_error_code = GetLastError();
return result;
}
result.exit_code = exit_status;
CloseHandle(run_cmd.process);
return result;
}
Dqn_OSRunCommandAsyncResult Dqn_OS_RunCommandAsync(Dqn_String8 cmd)
{
Dqn_OSRunCommandAsyncResult result = {};
#if defined(DQN_OS_WIN32)
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
Dqn_String16 cmd16 = Dqn_Win_String8ToString16(scratch.arena, cmd);
PROCESS_INFORMATION proc_info = {};
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(STARTUPINFOW);
startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startup_info.dwFlags |= STARTF_USESTDHANDLES;
BOOL create_result = CreateProcessW(nullptr, cmd16.data, nullptr, nullptr, true, 0, nullptr, nullptr, &startup_info, &proc_info);
if (!create_result)
return result;
CloseHandle(proc_info.hThread);
result.process = proc_info.hProcess;
#else
pid_t cpid = fork();
if (cpid < 0) {
nob_log(NOB_ERROR, "Could not fork child process: %s", strerror(errno));
return NOB_INVALID_PROC;
}
if (cpid == 0) {
// NOTE: This leaks a bit of memory in the child process.
// But do we actually care? It's a one off leak anyway...
Nob_Cmd cmd_null = {0};
nob_da_append_many(&cmd_null, cmd.items, cmd.count);
nob_cmd_append(&cmd_null, NULL);
if (execvp(cmd.items[0], (char * const*) cmd_null.items) < 0) {
nob_log(NOB_ERROR, "Could not exec child process: %s", strerror(errno));
exit(1);
}
NOB_ASSERT(0 && "unreachable");
}
return cpid;
#endif
return result;
}
int main()
{
Dqn_Library_Init();
Dqn_String8 build_dir = DQN_STRING8("./Build");
if (!Dqn_Fs_MakeDir(build_dir)) {
Dqn_Log_ErrorF("Failed to make build dir '%.*s'", DQN_STRING_FMT(build_dir));
return -1;
}
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
Dqn_String8 exe_dir = Dqn_OS_EXEDir(scratch.arena);
Dqn_String8Builder raylib_cmd_builder = {};
raylib_cmd_builder.allocator = scratch.allocator;
Dqn_String8 raylib_files[] = {
DQN_STRING8("rcore.c"),
DQN_STRING8("utils.c"),
DQN_STRING8("raudio.c"),
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));
Dqn_String8 raylib_include_dirs[] = {
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_String8 compile_flags = DQN_STRING8("/W4 /Z7 /MT /EHsc /nologo");
Dqn_String8 link_flags = DQN_STRING8("/link /incremental:no");
Dqn_String8Builder_AppendF(&raylib_cmd_builder, "cl %.*s /w /c /D _DEFAULT_SOURCE /D PLATFORM_DESKTOP", DQN_STRING_FMT(compile_flags));
for (Dqn_String8 include_dir : raylib_include_dirs)
Dqn_String8Builder_AppendF(&raylib_cmd_builder, " /I %.*s", DQN_STRING_FMT(include_dir));
for (Dqn_String8 file_name : raylib_files)
Dqn_String8Builder_AppendRef(&raylib_cmd_builder, Dqn_FsPath_ConvertF(scratch.arena, " %.*s/%.*s", DQN_STRING_FMT(raylib_dir), DQN_STRING_FMT(file_name)));
Dqn_String8 cmd = Dqn_String8Builder_Build(&raylib_cmd_builder, scratch.allocator);
Dqn_OSRunCommandAsyncResult run_result = Dqn_OS_RunCommandAsync(cmd);
Dqn_OS_RunCommandWait(run_result);
return 0;
}