From ab021cb74a2b3f0dab3258bf50929912100d1974 Mon Sep 17 00:00:00 2001 From: hachem Date: Fri, 28 Aug 2026 21:33:19 +0200 Subject: fix: cross platform build --- README.md | 1 + premake5.lua | 70 +++++++++++++++++++++++++++++++++++++++++++++----------- src/core/log.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/log.h | 23 +++---------------- 4 files changed, 120 insertions(+), 33 deletions(-) create mode 100644 src/core/log.cpp diff --git a/README.md b/README.md index df88387..4274f6b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # hsdbg hachem's stupid debugger. + diff --git a/premake5.lua b/premake5.lua index ffda3a8..0f63b57 100644 --- a/premake5.lua +++ b/premake5.lua @@ -3,17 +3,19 @@ output_dir = "%{cfg.buildcfg}-%{cfg.system}" llvm_version = "22.1.0" llvm_vendored_dir = "ext/llvm" +host_arm = os.hostarch() == "ARM64" or os.hostarch() == "arm64" +host_architecture = host_arm and "ARM64" or "x64" + function llvm_release_asset() local host = os.host() - local arm = os.hostarch() == "ARM64" or os.hostarch() == "arm64" if host == "macosx" then - return "LLVM-" .. llvm_version .. "-macOS-ARM64.tar.xz" + return host_arm and ("LLVM-" .. llvm_version .. "-macOS-ARM64.tar.xz") or nil elseif host == "linux" then - return "LLVM-" .. llvm_version .. (arm and "-Linux-ARM64" or "-Linux-X64") .. ".tar.xz" + return "LLVM-" .. llvm_version .. (host_arm and "-Linux-ARM64" or "-Linux-X64") .. ".tar.xz" elseif host == "windows" then return "clang+llvm-" .. llvm_version .. - (arm and "-aarch64-pc-windows-msvc" or "-x86_64-pc-windows-msvc") .. ".tar.xz" + (host_arm and "-aarch64-pc-windows-msvc" or "-x86_64-pc-windows-msvc") .. ".tar.xz" end return nil @@ -92,7 +94,13 @@ function lldb_library() return "" end - local names = { "liblldb.dylib", "liblldb.so", "liblldb.lib" } + local names = { "liblldb.so" } + + if os.target() == "windows" then + names = { "liblldb.lib" } + elseif os.target() == "macosx" then + names = { "liblldb.dylib" } + end for _, name in ipairs(names) do local candidate = library_dir.lldb .. "/" .. name @@ -105,14 +113,49 @@ function lldb_library() local versioned = os.matchfiles(library_dir.lldb .. "/liblldb.so.*") table.sort(versioned) - return versioned[#versioned] - or error("llvm at " .. llvm_dir .. " has lldb headers but no liblldb in " .. library_dir.lldb) + if versioned[#versioned] ~= nil then + return versioned[#versioned] + end + + if os.target() ~= os.host() then + return library_dir.lldb .. "/" .. names[1] + end + + error("llvm at " .. llvm_dir .. " has lldb headers but no liblldb in " .. library_dir.lldb) +end + +function windows_runtime_copies() + local commands = {} + + if llvm_dir == "" then + return commands + end + + local runtimes = os.matchfiles(llvm_dir .. "/bin/liblldb.dll") + + for _, runtime in ipairs(os.matchfiles(llvm_dir .. "/bin/python*.dll")) do + table.insert(runtimes, runtime) + end + + if #runtimes == 0 then + runtimes = { llvm_dir .. "/bin/liblldb.dll" } + end + + for _, runtime in ipairs(runtimes) do + table.insert(commands, '{COPYFILE} "' .. runtime .. '" "%{cfg.targetdir}"') + end + + return commands end function setup_target() targetdir ("bin/" .. output_dir) objdir ("bin-int/" .. output_dir .. "/%{prj.name}") staticruntime "On" + + filter "system:windows" + staticruntime "Off" + filter {} end function setup_c_target() @@ -207,7 +250,8 @@ newaction { local extracted = os.execute('tar -xf "' .. archive .. '" -C "' .. staging .. '"') if extracted ~= true and extracted ~= 0 then - error("could not extract " .. archive .. ", unpack it into " .. llvm_vendored_dir .. " by hand") + error("could not extract " .. archive .. ", the system tar may lack xz support, " .. + "unpack it into " .. llvm_vendored_dir .. " by hand") end local unpacked = os.matchdirs(staging .. "/*")[1] @@ -231,7 +275,7 @@ newaction { workspace "hsdbg" - architecture "x64" + architecture(host_architecture) startproject "hsdbg" multiprocessorcompile "On" @@ -246,7 +290,6 @@ workspace "hsdbg" filter "system:linux" defines "HSDBG_LINUX" filter "system:macosx" - architecture "ARM64" defines "HSDBG_MACOS" filter {} @@ -302,6 +345,8 @@ project "glfw" "ext/glfw/src/posix_time.h", "ext/glfw/src/posix_thread.c", "ext/glfw/src/posix_thread.h", + "ext/glfw/src/posix_poll.c", + "ext/glfw/src/posix_poll.h", "ext/glfw/src/glx_context.c", "ext/glfw/src/egl_context.c", @@ -462,15 +507,14 @@ project "hsdbg" links "opengl32" - postbuildcommands { - '{COPYFILE} "' .. llvm_dir .. '/bin/liblldb.dll" "%{cfg.targetdir}"', - } + postbuildcommands(windows_runtime_copies()) filter "system:not windows" linkoptions { "-Wl,-rpath," .. library_dir.lldb } filter "system:linux" links { "GL", "dl", + "m", "pthread", } filter "system:macosx" diff --git a/src/core/log.cpp b/src/core/log.cpp new file mode 100644 index 0000000..f7285f3 --- /dev/null +++ b/src/core/log.cpp @@ -0,0 +1,59 @@ +#include "core/log.h" + +// there is no standard way to ask whether a stream is a terminal +#ifdef HSDBG_WINDOWS + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include + + #include +#else + #include +#endif + +namespace Hsdbg::Log::Detail +{ + namespace + { + constexpr int STDOUT_DESCRIPTOR = 1; + constexpr int STDERR_DESCRIPTOR = 2; + +#ifdef HSDBG_WINDOWS + // a windows console prints escapes literally until it is asked to + // interpret them, so a console that refuses gets the plain format + auto probe(bool to_stderr) -> bool + { + if (_isatty(to_stderr ? STDERR_DESCRIPTOR : STDOUT_DESCRIPTOR) == 0) + return false; + + const HANDLE console = GetStdHandle(to_stderr ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE); + + if (console == nullptr || console == INVALID_HANDLE_VALUE) + return false; + + DWORD mode = 0; + + if (GetConsoleMode(console, &mode) == 0) + return false; + + if ((mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0) + return true; + + return SetConsoleMode(console, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0; + } +#else + auto probe(bool to_stderr) -> bool + { + return isatty(to_stderr ? STDERR_DESCRIPTOR : STDOUT_DESCRIPTOR) != 0; + } +#endif + } + + auto is_terminal(bool to_stderr) -> bool + { + static const bool out = probe(false); + static const bool err = probe(true); + + return to_stderr ? err : out; + } +} diff --git a/src/core/log.h b/src/core/log.h index a66a61e..7caf93f 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -8,13 +8,6 @@ #include #include -// there is no standard way to ask whether a stream is a terminal -#ifdef HSDBG_WINDOWS - #include -#else - #include -#endif - namespace Hsdbg::Log { enum class Level : uint8_t @@ -66,19 +59,9 @@ namespace Hsdbg::Log return ""; } - inline auto is_terminal(bool to_stderr) -> bool - { - constexpr int STDOUT_DESCRIPTOR = 1; - constexpr int STDERR_DESCRIPTOR = 2; - - const int descriptor = to_stderr ? STDERR_DESCRIPTOR : STDOUT_DESCRIPTOR; - -#ifdef HSDBG_WINDOWS - return _isatty(descriptor) != 0; -#else - return isatty(descriptor) != 0; -#endif - } + // true only when the stream is a terminal that understands ansi escapes, + // which needs platform calls, so it lives in log.cpp + auto is_terminal(bool to_stderr) -> bool; inline auto write(Level level, std::string_view message) -> void { -- cgit v1.3