Many changes, building many targets at the same time

This commit is contained in:
Krzosa Karol
2024-01-27 19:32:12 +01:00
parent e39cd78546
commit 43f770b790
18 changed files with 386 additions and 58 deletions

139
build_tool/process.cpp Normal file
View File

@@ -0,0 +1,139 @@
struct TH_Process {
bool is_valid;
char platform[32];
};
#if OS_WINDOWS
TH_Process TH_CreateProcess(S8_String in_cmd, S8_String in_working_dir = "") {
MA_Scratch scratch;
if (in_working_dir != "" && !OS_IsAbsolute(in_working_dir)) {
in_working_dir = OS_GetAbsolutePath(scratch, in_working_dir);
}
wchar_t *application_name = NULL;
wchar_t *cmd = S8_ToWidechar(scratch, in_cmd);
BOOL inherit_handles = FALSE;
DWORD creation_flags = 0;
void *enviroment = NULL;
wchar_t *working_dir = in_working_dir == "" ? NULL : S8_ToWidechar(scratch, in_working_dir);
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(STARTUPINFOW);
TH_Process result = {};
IO_Assert(sizeof(result.platform) >= sizeof(PROCESS_INFORMATION));
PROCESS_INFORMATION *process_info = (PROCESS_INFORMATION *)result.platform;
BOOL success = CreateProcessW(application_name, cmd, NULL, NULL, inherit_handles, creation_flags, enviroment, working_dir, &startup_info, process_info);
result.is_valid = true;
if (!success) {
result.is_valid = false;
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
LocalFree(lpMsgBuf);
IO_FatalErrorf("Failed to create process \nworking_dir: %.*s\ncmd: %.*s\nwindows_message: %s", S8_Expand(in_working_dir), S8_Expand(in_cmd), lpMsgBuf);
}
return result;
}
int TH_WaitForProcessExit(TH_Process *process) {
IO_Assert(process->is_valid);
PROCESS_INFORMATION *pi = (PROCESS_INFORMATION *)process->platform;
WaitForSingleObject(pi->hProcess, INFINITE);
DWORD exit_code;
BOOL err = GetExitCodeProcess(pi->hProcess, &exit_code);
IO_Assert(err != 0);
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
process[0] = {};
return (int)exit_code;
}
#else
#include <spawn.h>
#include <sys/wait.h>
struct TH_UnixProcess {
pid_t pid;
};
extern char **environ;
TH_Process TH_CreateProcess(S8_String cmd, S8_String working_dir = "") {
MA_Scratch scratch;
if (working_dir != "" && !OS_IsAbsolute(working_dir)) {
working_dir = OS_GetAbsolutePath(scratch, working_dir);
}
TH_Process result = {};
IO_Assert(sizeof(result.platform) >= sizeof(TH_UnixProcess));
TH_UnixProcess *u = (TH_UnixProcess *)result.platform;
S8_String exec_file = cmd;
S8_String argv = "";
int64_t pos;
if (S8_Seek(cmd, S8_Lit(" "), 0, &pos)) {
exec_file = S8_GetPrefix(cmd, pos);
argv = S8_Skip(cmd, pos + 1);
}
exec_file = S8_Copy(scratch, exec_file);
// Split string on whitespace and conform with argv format
Array<char *> args = {scratch};
{
args.add(exec_file.str);
for (int64_t i = 0; i < argv.len;) {
while (i < argv.len && CHAR_IsWhitespace(argv.str[i])) {
i += 1;
}
S8_String word = {argv.str + i, 0};
while (i < argv.len && !CHAR_IsWhitespace(argv.str[i])) {
word.len += 1;
i += 1;
}
word = S8_Copy(scratch, word);
args.add(word.str);
}
args.add(NULL);
}
S8_String prev_dir = {};
if (working_dir != "") prev_dir = OS_GetWorkingDir(scratch);
if (working_dir != "") OS_SetWorkingDir(working_dir);
int err = posix_spawnp(&u->pid, exec_file.str, NULL, NULL, args.data, environ);
if (err == 0) {
result.is_valid = true;
}
else {
perror("Failed to create process");
IO_FatalErrorf("Failed to create process \nworking_dir: %.*s\ncmd: %.*s", S8_Expand(working_dir), S8_Expand(cmd));
}
if (working_dir != "") OS_SetWorkingDir(prev_dir);
return result;
}
int TH_WaitForProcessExit(TH_Process *process) {
if (!process->is_valid) return 1;
TH_UnixProcess *u = (TH_UnixProcess *)process->platform;
int status = 0;
int pid = waitpid(u->pid, &status, 0);
IO_Assert(pid != -1);
int result = 0;
if (WIFEXITED(status)) {
result = WEXITSTATUS(status);
}
else {
result = 1;
}
process[0] = {};
return result;
}
#endif