From 67f8fe011c1b6b6fb1055b02eab96380fbae54dc Mon Sep 17 00:00:00 2001 From: molyuu Date: Mon, 15 Dec 2025 12:27:51 +0800 Subject: [PATCH 1/5] all: initial support for freebsd --- .github/workflows/build.yml | 39 +++++++++++++++++++++++++++++++ src/core/logging.cpp | 24 +++++++++++++++++-- src/core/paths.cpp | 4 ++-- src/core/toolsupport.cpp | 2 +- src/services/pam/conversation.cpp | 2 ++ src/services/pam/qml.hpp | 4 ++++ src/services/pam/subprocess.cpp | 8 +++++++ 7 files changed, 78 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc6e8a72..fbecb27a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,3 +61,42 @@ jobs: run: | cmake -GNinja -B build -DCRASH_REPORTER=OFF cmake --build build + + freebsd: + name: FreeBSD + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build in FreeBSD VM + uses: vmactions/freebsd-vm@v1 + with: + release: "15.0" + usesh: true + + prepare: | + pkg update -f && pkg install -y \ + cmake \ + pkgconf \ + cli11 \ + spirv-tools \ + qt6-base \ + qt6-declarative \ + qt6-shadertools \ + qt6-wayland \ + wayland \ + wayland-protocols \ + libdrm \ + libxcb \ + pipewire \ + polkit \ + glib \ + mesa-libs \ + git \ + bash \ + ninja \ + gitup + + run: | + cmake -GNinja -B build -DCRASH_REPORTER=OFF -DUSE_JEMALLOC=OFF -DCMAKE_C_FLAGS="-I/usr/local/include -L/usr/local/lib" -DCMAKE_CXX_FLAGS="-I/usr/local/include -L/usr/local/lib" + cmake --build build \ No newline at end of file diff --git a/src/core/logging.cpp b/src/core/logging.cpp index 5c809f68..d362f5fd 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -27,7 +27,12 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#include +#else #include +#endif #include "instanceinfo.hpp" #include "logcat.hpp" @@ -392,7 +397,7 @@ void ThreadLogging::initFs() { delete detailedFile; detailedFile = nullptr; } else { - auto lock = flock { + struct flock lock = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, @@ -414,7 +419,11 @@ void ThreadLogging::initFs() { auto* oldFile = this->file; if (oldFile) { oldFile->seek(0); +#ifdef __FreeBSD__ + copy_file_range(oldFile->handle(), nullptr, file->handle(), nullptr, oldFile->size(), 0); +#else sendfile(file->handle(), oldFile->handle(), nullptr, oldFile->size()); +#endif } this->file = file; @@ -426,7 +435,18 @@ void ThreadLogging::initFs() { auto* oldFile = this->detailedFile; if (oldFile) { oldFile->seek(0); +#ifdef __FreeBSD__ + copy_file_range( + oldFile->handle(), + nullptr, + detailedFile->handle(), + nullptr, + oldFile->size(), + 0 + ); +#else sendfile(detailedFile->handle(), oldFile->handle(), nullptr, oldFile->size()); +#endif } crash::CrashInfo::INSTANCE.logFd = detailedFile->handle(); @@ -889,7 +909,7 @@ bool LogReader::continueReading() { } void LogFollower::FcntlWaitThread::run() { - auto lock = flock { + struct flock lock = { .l_type = F_RDLCK, // won't block other read locks when we take it .l_whence = SEEK_SET, .l_start = 0, diff --git a/src/core/paths.cpp b/src/core/paths.cpp index 55beb87c..6555e54e 100644 --- a/src/core/paths.cpp +++ b/src/core/paths.cpp @@ -361,7 +361,7 @@ void QsPaths::createLock() { return; } - auto lock = flock { + struct flock lock = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, @@ -389,7 +389,7 @@ bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info, bool allowD auto file = QFile(QDir(path).filePath("instance.lock")); if (!file.open(QFile::ReadOnly)) return false; - auto lock = flock { + struct flock lock = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, diff --git a/src/core/toolsupport.cpp b/src/core/toolsupport.cpp index afce008b..8aa5ac9d 100644 --- a/src/core/toolsupport.cpp +++ b/src/core/toolsupport.cpp @@ -54,7 +54,7 @@ bool QmlToolingSupport::lockTooling() { return false; } - auto lock = flock { + struct flock lock = { .l_type = F_WRLCK, .l_whence = SEEK_SET, // NOLINT (fcntl.h??) .l_start = 0, diff --git a/src/services/pam/conversation.cpp b/src/services/pam/conversation.cpp index 6d27978f..500abd5a 100644 --- a/src/services/pam/conversation.cpp +++ b/src/services/pam/conversation.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include "../../core/logcat.hpp" diff --git a/src/services/pam/qml.hpp b/src/services/pam/qml.hpp index a8ffcc35..13ab593c 100644 --- a/src/services/pam/qml.hpp +++ b/src/services/pam/qml.hpp @@ -6,7 +6,11 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#else #include +#endif #include #include "conversation.hpp" diff --git a/src/services/pam/subprocess.cpp b/src/services/pam/subprocess.cpp index f99b279d..dc362284 100644 --- a/src/services/pam/subprocess.cpp +++ b/src/services/pam/subprocess.cpp @@ -7,7 +7,11 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#else #include +#endif #include #include @@ -83,7 +87,11 @@ PamIpcExitCode PamSubprocess::exec(const char* configDir, const char* config, co logIf(this->log) << "Starting pam session for user \"" << user << "\" with config \"" << config << "\" in dir \"" << configDir << "\"" << std::endl; +#ifdef __FreeBSD__ + auto result = pam_start(config, user, &conv, &handle); +#else auto result = pam_start_confdir(config, user, &conv, configDir, &handle); +#endif if (result != PAM_SUCCESS) { logIf(true) << "Unable to start pam conversation with error \"" << pam_strerror(handle, result) From 4c97caaf058f77fc24913064a875ee47465adc22 Mon Sep 17 00:00:00 2001 From: molyuu Date: Mon, 15 Dec 2025 23:44:14 +0800 Subject: [PATCH 2/5] core/logging: use copy_file_range for linux too Both FreeBSD and Linux supports the `copy_file_range(2)` function, which behaves similarly to the `sendfile(2)` function, but has better compatibility. --- src/core/logging.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/core/logging.cpp b/src/core/logging.cpp index d362f5fd..10ea453a 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -27,12 +27,7 @@ #include #include #include -#ifdef __FreeBSD__ -#include #include -#else -#include -#endif #include "instanceinfo.hpp" #include "logcat.hpp" @@ -419,11 +414,7 @@ void ThreadLogging::initFs() { auto* oldFile = this->file; if (oldFile) { oldFile->seek(0); -#ifdef __FreeBSD__ copy_file_range(oldFile->handle(), nullptr, file->handle(), nullptr, oldFile->size(), 0); -#else - sendfile(file->handle(), oldFile->handle(), nullptr, oldFile->size()); -#endif } this->file = file; @@ -435,7 +426,6 @@ void ThreadLogging::initFs() { auto* oldFile = this->detailedFile; if (oldFile) { oldFile->seek(0); -#ifdef __FreeBSD__ copy_file_range( oldFile->handle(), nullptr, @@ -444,9 +434,6 @@ void ThreadLogging::initFs() { oldFile->size(), 0 ); -#else - sendfile(detailedFile->handle(), oldFile->handle(), nullptr, oldFile->size()); -#endif } crash::CrashInfo::INSTANCE.logFd = detailedFile->handle(); From dcc59aaa73e901f689367c3fe27de57e536439a0 Mon Sep 17 00:00:00 2001 From: molyuu Date: Tue, 23 Dec 2025 16:37:57 +0800 Subject: [PATCH 3/5] services/pam: clarify `configDirectory` behavior on FreeBSD --- src/services/pam/qml.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/pam/qml.hpp b/src/services/pam/qml.hpp index 13ab593c..a36184ef 100644 --- a/src/services/pam/qml.hpp +++ b/src/services/pam/qml.hpp @@ -39,6 +39,8 @@ class PamContext /// /// The configuration directory is resolved relative to the current file if not an absolute path. /// + /// On FreeBSD this property is ignored as the pam configuration directory cannot be changed. + /// /// This property may not be set while @@active is true. Q_PROPERTY(QString configDirectory READ configDirectory WRITE setConfigDirectory NOTIFY configDirectoryChanged); /// The user to authenticate as. If unset the current user will be used. From 640aee958dc386289e3418bb52d0d590ed82d873 Mon Sep 17 00:00:00 2001 From: molyuu Date: Tue, 23 Dec 2025 16:57:18 +0800 Subject: [PATCH 4/5] build: disable `CRASH_REPORTER` and `USE_JEMALLOC` for FreeBSD by default - `jemalloc` is a part of FreeBSD's libc, and is the default memory allocator. So disable `USE_JEMALLOC` for FreeBSD by default. - `breakpad` does not support FreeBSD, `CRASH_REPORTER` should be disabled for FreeBSD by default. --- .github/workflows/build.yml | 3 ++- CMakeLists.txt | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbecb27a..46c1a653 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,6 +86,7 @@ jobs: qt6-wayland \ wayland \ wayland-protocols \ + vulkan-headers \ libdrm \ libxcb \ pipewire \ @@ -98,5 +99,5 @@ jobs: gitup run: | - cmake -GNinja -B build -DCRASH_REPORTER=OFF -DUSE_JEMALLOC=OFF -DCMAKE_C_FLAGS="-I/usr/local/include -L/usr/local/lib" -DCMAKE_CXX_FLAGS="-I/usr/local/include -L/usr/local/lib" + cmake -GNinja -B build -DCMAKE_C_FLAGS="-I/usr/local/include -L/usr/local/lib" -DCMAKE_CXX_FLAGS="-I/usr/local/include -L/usr/local/lib" cmake --build build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c8670013..257ad94b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,8 +44,13 @@ boption(BUILD_TESTING "Build tests (dev)" OFF) boption(ASAN "ASAN (dev)" OFF) # note: better output with gcc than clang boption(FRAME_POINTERS "Keep Frame Pointers (dev)" ${ASAN}) -boption(CRASH_REPORTER "Crash Handling" ON) -boption(USE_JEMALLOC "Use jemalloc" ON) +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + boption(CRASH_REPORTER "Crash Handling" OFF) + boption(USE_JEMALLOC "Use jemalloc" OFF) +else() + boption(CRASH_REPORTER "Crash Handling" ON) + boption(USE_JEMALLOC "Use jemalloc" ON) +endif() boption(SOCKETS "Unix Sockets" ON) boption(WAYLAND "Wayland" ON) boption(WAYLAND_WLR_LAYERSHELL " Wlroots Layer-Shell" ON REQUIRES WAYLAND) From a33339e976a5176d616e04f6840fbcd7119cdc09 Mon Sep 17 00:00:00 2001 From: molyuu Date: Tue, 23 Dec 2025 16:57:56 +0800 Subject: [PATCH 5/5] build: add FreeBSD specific include/link dirs for FreeBSD --- .github/workflows/build.yml | 2 +- CMakeLists.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46c1a653..32725477 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,5 +99,5 @@ jobs: gitup run: | - cmake -GNinja -B build -DCMAKE_C_FLAGS="-I/usr/local/include -L/usr/local/lib" -DCMAKE_CXX_FLAGS="-I/usr/local/include -L/usr/local/lib" + cmake -GNinja -B build cmake --build build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 257ad94b..7686ff67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,12 @@ add_compile_options(-Wall -Wextra -Wno-vla-cxx-extension) # pipewire defines this, breaking PCH add_compile_definitions(_REENTRANT) +# FreeBSD specific include/link dirs +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + include_directories(/usr/local/include) + link_directories(/usr/local/lib) +endif() + if (FRAME_POINTERS) add_compile_options(-fno-omit-frame-pointer) endif()