add linux support to runtime build

This commit is contained in:
theofficialgman
2026-08-25 19:50:37 -04:00
parent 6d836dab3e
commit f63d0c84b5
5 changed files with 83 additions and 26 deletions
+22
View File
@@ -10,7 +10,11 @@
#include <cstdlib>
#include <cpuid.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif
namespace {
@@ -137,7 +141,12 @@ bool CollectMissingBaselineFeatures(TextBuffer& missing) {
// up yet, and fprintf(stderr, ...) faults there. Verified on this toolchain:
// WriteFile on the raw standard-error handle and MessageBoxA both work, printf
// does not. Anything added to this reporting path has to respect that.
//
// The POSIX path runs from an __attribute__((constructor)) instead, ahead of libc's own startup
// guarantees; ::write() on the raw fd is the same kind of allocation-free, libc-init-independent
// primitive as WriteFile is on Windows, so the same restriction is honored here.
void WriteStdErrEarly(const char* text) {
#if defined(_WIN32)
const HANDLE handle = ::GetStdHandle(STD_ERROR_HANDLE);
if (handle == nullptr || handle == INVALID_HANDLE_VALUE) {
return;
@@ -148,6 +157,13 @@ void WriteStdErrEarly(const char* text) {
}
DWORD written = 0;
::WriteFile(handle, text, static_cast<DWORD>(length), &written, nullptr);
#else
size_t length = 0;
while (text[length] != '\0') {
++length;
}
(void)::write(STDERR_FILENO, text, length);
#endif
}
[[noreturn]] void ReportUnsupportedCpu(const char* missing) {
@@ -168,12 +184,18 @@ void WriteStdErrEarly(const char* text) {
WriteStdErrEarly(message.data);
WriteStdErrEarly("\n");
#if defined(_WIN32)
::MessageBoxA(nullptr, message.data, "WiiCompiled - Unsupported Processor",
MB_OK | MB_ICONERROR | MB_SETFOREGROUND | MB_TASKMODAL);
// Leave through the OS rather than exit(): the C++ dynamic initializers
// have not run yet, so there is no constructed program state to unwind and
// the teardown path itself lives in AVX2 translation units.
::ExitProcess(1u);
#else
// Same reasoning as the Windows path above: no C++ dynamic initializer has run yet, so
// _exit() (skips atexit/global destructors, unlike exit()) is the correct way out.
::_exit(1);
#endif
}
} // namespace