gui: make it compatible with musl libc

This commit is contained in:
bwisn 2026-02-08 15:32:12 +01:00
parent 3c558d6e3d
commit 7df1ebd66b
2 changed files with 68 additions and 2 deletions

View File

@ -71,6 +71,36 @@ else()
set(BBASM_MODE "string")
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <gnu/libc-version.h>
int main() { return 0; }
" HAVE_GLIBC)
if (HAVE_GLIBC)
set(USE_LIBUNWIND OFF)
else()
set(USE_LIBUNWIND ON)
find_library(LIBUNWIND_LIBRARY NAMES unwind)
find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h)
if(LIBUNWIND_LIBRARY)
find_library(LIBUNWIND_LIBRARY_ARCH NAMES "unwind-${CMAKE_SYSTEM_PROCESSOR}")
if(LIBUNWIND_LIBRARY_ARCH)
set(LIBUNWIND_LIBRARY "${LIBUNWIND_LIBRARY};${LIBUNWIND_LIBRARY_ARCH}")
endif()
endif()
if(NOT LIBUNWIND_LIBRARY OR NOT LIBUNWIND_INCLUDE_DIR)
message(FATAL_ERROR "libunwind not found. Install libunwind-dev")
endif()
endif()
else()
set(USE_LIBUNWIND OFF)
endif()
find_package(Threads)
if (NOT Threads_FOUND)
add_definitions(-DNPNR_DISABLE_THREADS)
@ -364,6 +394,10 @@ function(add_nextpnr_architecture target)
target_link_libraries(nextpnr-${target} PRIVATE nextpnr-${target}-core)
if (BUILD_GUI)
target_link_libraries(nextpnr-${target} PRIVATE nextpnr-${target}-gui)
if (USE_LIBUNWIND)
target_include_directories(nextpnr-${target} PRIVATE ${LIBUNWIND_INCLUDE_DIR})
target_link_libraries(nextpnr-${target} PRIVATE ${LIBUNWIND_LIBRARY})
endif()
endif()
install(TARGETS nextpnr-${target} RUNTIME DESTINATION bin)
@ -382,6 +416,10 @@ function(add_nextpnr_architecture target)
if (BUILD_GUI)
target_link_libraries(nextpnr-${target}-test PRIVATE nextpnr-${target}-gui)
target_link_libraries(nextpnr-${target}-test PRIVATE nextpnr_test_gui)
if (USE_LIBUNWIND)
target_include_directories(nextpnr-${target}-test PRIVATE ${LIBUNWIND_INCLUDE_DIR})
target_link_libraries(nextpnr-${target}-test PRIVATE ${LIBUNWIND_LIBRARY})
endif()
endif()
endif()

View File

@ -28,7 +28,11 @@
#include "log.h"
#ifdef __linux__
#if defined(__GLIBC__)
#include <execinfo.h>
#else
#include <libunwind.h>
#endif
#endif
NEXTPNR_NAMESPACE_BEGIN
@ -48,17 +52,41 @@ namespace {
#ifdef __linux__
std::string get_backtrace_str()
{
std::ostringstream ss;
ss << "Backtrace: " << std::endl;
#if defined(__GLIBC__)
static const size_t MAX_BT_SIZE = 1024;
std::array<void *, MAX_BT_SIZE> bt_data;
int bt_len = backtrace(bt_data.data(), MAX_BT_SIZE);
char **bt_symbols = backtrace_symbols(bt_data.data(), bt_len);
if (bt_symbols == nullptr)
return "";
std::ostringstream ss;
ss << "Backtrace: " << std::endl;
for (int i = 0; i < bt_len; i++)
ss << " " << bt_symbols[i] << std::endl;
free(bt_symbols);
#else
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
int frame_num = 0;
while (unw_step(&cursor) > 0) {
unw_word_t ip;
char func_name[256];
unw_word_t offset;
unw_get_reg(&cursor, UNW_REG_IP, &ip);
if (unw_get_proc_name(&cursor, func_name, sizeof(func_name), &offset) == 0) {
ss << " #" << frame_num << ": " << func_name << " + 0x"
<< std::hex << offset << " [0x" << ip << "]\n";
} else {
ss << " #" << frame_num << ": -- unknown -- [0x"
<< std::hex << ip << "]\n";
}
frame_num++;
}
#endif
return ss.str();
}
#else