FoxSDR 0.99.39 · 公测版
机器翻译
← 返回 FoxSDR

源码构建 · Apple 芯片和 Intel

在 macOS 上构建

还没有人完成过这个构建。FoxSDR 在 Windows 上开发,另有一个每次提交都会通过的 Linux CI 作业。macOS 从未尝试过。本页的所有内容都源自实际的构建文件和那套可用的 Linux 流程——但构建本身未经验证。你很可能会遇到本页没有提到的问题,遇到时请告诉我们。

最难的部分已经完成。该项目在 Linux CI 中构建并通过了完整的测试套件,因此非 Windows 代码路径确实经过了运行,而不只是理论上可行。下面说明的是这条路径与 Mac 之间的差异。

你需要什么

除 SoapySDR 和 OpenSSL 之外,所有依赖都已纳入代码库,位于 third_party/:GLFW 3.4、Dear ImGui、PortAudio、pffft、nlohmann/json、tweetnacl 和 cpp-httplib 都在源码树中从源码构建。纳入代码库的 GLFW 和 PortAudio 本身就真正支持 macOS——Cocoa 和 CoreAudio——因此应该不需要你额外做什么。

xcode-select --install                      # Apple Clang, needs C++20
brew install cmake ninja soapysdr openssl@3

CMake 3.20 或更新版本。本项目使用 C++20 并启用 CMAKE_CXX_STANDARD_REQUIRED ON,因此旧版 Xcode 会在配置阶段就失败,而不是在之后莫名其妙地失败。

在 Mac 上,与 USB SDR 通信的是 SoapySDR。自 0.91.0 起,FoxSDR 为 RTL-SDR、HackRF、Airspy、Mirics 和 RX888 系列带有自己的驱动,但它们的 USB 传输层只针对 Windows(WinUSB)和 Linux(usbfs):在 macOS 上,这一层构建为一个什么也找不到的空壳,因此每个 USB 接收机都要通过 SoapySDR::Device::enumerate() 接入,你安装了哪些 SoapySDR 模块,它就能用哪些。根据你的硬件选择 brew install soapyrtlsdr、soapyairspy、soapyhackrf 等。即使一个都不装,FoxSDR 也能完全正常运行,使用内置的信号发生器或 I/Q 文件回放。

构建

git clone https://github.com/wonderingStars/foxsdr.git
cd foxsdr
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
      -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build build -j"$(sysctl -n hw.ncpu)"

OPENSSL_ROOT_DIR 是 Linux 不需要的那个选项。macOS 自带的是 LibreSSL 而不是 OpenSSL,而 Homebrew 刻意不把 openssl@3 放在默认搜索路径上,因此 find_package(OpenSSL REQUIRED) 自己找不到它。OpenSSL 用于密码摘要原语和插件目录的 HTTPS 客户端;Windows 改用 CNG 和 WinHTTP,所以在那里它不是依赖项。

然后:

ctest --test-dir build --output-on-failure
./build/cascade --selftest

在断定任何东西能用之前,先运行 --selftest。它以无界面方式驱动真实的 DSP 链路,并断言一个已知的频谱峰值,因此能发现那种链接顺利、通过了单元测试、却算出错误数字的构建。

有一项测试会打开真实窗口。在 Linux CI 上需要 Xvfb;在 macOS 上只要在正常登录的图形界面会话中运行测试,应该就没问题。

你几乎一定需要的那个补丁

有两个函数使用 Linux 的 /proc 查找可执行文件自身所在的文件夹,而 macOS 上没有它:

  • src/core/band_plan.cpp,位于 BandPlan::defaultDir()
  • src/core/plugin_host.cpp,约第 888 行

两者的做法都是:

const fs::path link = fs::read_symlink("/proc/self/exe", ec);

在 macOS 上这会失败,ec 被设置,路径保持为空,两者都会回退到相对于当前文件夹的路径。不会崩溃——但除非你恰好从构建文件夹启动,否则应用程序找不到它的频段规划或插件。修复方法是添加一个使用 _NSGetExecutablePath 的 __APPLE__ 分支,而两个文件都已有可以挂上它的 #ifdef 结构:

#elif defined(__APPLE__)
    char buf[PATH_MAX];
    uint32_t size = sizeof(buf);
    if (_NSGetExecutablePath(buf, &size) == 0) {
        std::error_code rc;
        const fs::path resolved = fs::canonical(fs::path(buf), rc);
        exe = rc ? fs::path(buf) : resolved;
    }
#else
    // existing Linux /proc branch
#endif

并在其他平台头文件旁加上 #include <mach-o/dyld.h> 和 #include <climits>。_NSGetExecutablePath 可能返回包含符号链接和 .. 的路径,所以值得再经过 fs::canonical 处理。

第一个函数有对应的测试——test_band_plan 断言 defaultDir() 以 bandplans 结尾,并且绝不是一个普通文件——因此无论哪种情况你都会得到信号。

哪些无法工作,也不值得去追

  • 没有崩溃报告。崩溃处理程序基于 dbghelp 构建,仅限 Windows。
  • 使用情况报告尚未测试。在 Windows 以外,报告由 Linux 构建所用的同一个 HTTPS 发送器发送,所以 Mac 构建应该会像 Linux 一样报告;目前还没有人在 Mac 上验证过。
  • 窗口保留标题栏。src/gui/win_frame.cpp 通过 WM_NCCALCSIZE 和 WM_NCHITTEST 实现无边框窗口;它的整个函数体都在 #ifdef _WIN32 之内,因此在其他平台上会编译为空,窗口看起来就是普通窗口。仅影响外观。

这些都不会妨碍接收机工作。

频段规划

0.81.0 附带九个频段规划——全球、三个 ITU 区域,以及英国、美国、加拿大、日本和澳大利亚。CMake 在每个平台上都会把它们放到构建出的二进制文件旁边,所以构建完成后你应该有:

build/resources/bandplans/*.json

在应用中通过显示 → 地区选择你所在的地区。如果选择器为空或图层从不绘制,那是上面所说的 /proc/self/exe 问题,而不是缺少文件——请先检查 build/resources/bandplans/ 是否存在。

参考:Linux CI 流程

.github/workflows/build.yml 在 ubuntu-latest 上构建,是目前最接近已知可用的非 Windows 构建。其依赖列表对应如下:

LinuxmacOS
build-essentialXcode 命令行工具
cmake ninja-buildbrew install cmake ninja
libsoapysdr-devbrew install soapysdr
libssl-devbrew install openssl@3 + OPENSSL_ROOT_DIR
libgl1-mesa-dev已包含在 macOS SDK 中
libx11-dev, libwayland-dev, libxkbcommon-dev, …不需要——GLFW 使用 Cocoa
libasound2-dev不需要——PortAudio 使用 CoreAudio
xvfb在图形界面会话中不需要

配置和构建命令在其他方面完全相同。

如果你成功了

告诉我们。一个真正有人运行过的 Mac 构建比本页更有价值,第一个做到的人会把“未经验证”变成受支持的平台。请在公测计划中告诉我们,或写信至 [email protected]。

许可证

FoxSDR 采用 PolyForm Noncommercial 许可——非商业用途免费,为自己构建它完全在此范围之内。商业用途需要单独的许可证。纳入代码库的第三方组件保留各自的许可证,列在 third_party/THIRD_PARTY.md 中。