diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc6e8a72..32725477 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,3 +61,43 @@ 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 \ + vulkan-headers \ + libdrm \ + libxcb \ + pipewire \ + polkit \ + glib \ + mesa-libs \ + git \ + bash \ + ninja \ + gitup + + run: | + cmake -GNinja -B build + cmake --build build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c8670013..7686ff67 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) @@ -81,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() diff --git a/src/core/logging.cpp b/src/core/logging.cpp index 5c809f68..10ea453a 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "instanceinfo.hpp" #include "logcat.hpp" @@ -392,7 +392,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 +414,7 @@ void ThreadLogging::initFs() { auto* oldFile = this->file; if (oldFile) { oldFile->seek(0); - sendfile(file->handle(), oldFile->handle(), nullptr, oldFile->size()); + copy_file_range(oldFile->handle(), nullptr, file->handle(), nullptr, oldFile->size(), 0); } this->file = file; @@ -426,7 +426,14 @@ void ThreadLogging::initFs() { auto* oldFile = this->detailedFile; if (oldFile) { oldFile->seek(0); - sendfile(detailedFile->handle(), oldFile->handle(), nullptr, oldFile->size()); + copy_file_range( + oldFile->handle(), + nullptr, + detailedFile->handle(), + nullptr, + oldFile->size(), + 0 + ); } crash::CrashInfo::INSTANCE.logFd = detailedFile->handle(); @@ -889,7 +896,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..a36184ef 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" @@ -35,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. 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)