130 lines
4.6 KiB
C++
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;
|
||
|
}
|