From d90db5f38ae3ca8d5638d26924842de4a168f0ff Mon Sep 17 00:00:00 2001 From: Tim Taplin Date: Sun, 4 Oct 2026 08:47:52 -0600 Subject: [PATCH] Build on libmongoc 2.0-2.2; drop the misleading apt hint 4.0.1 failed to compile against libmongoc 2.2.2 (Ubuntu 26.04 LTS's libmongoc-dev): bson_append_array_unsafe_begin only exists from libbson 2.3, which also deprecated bson_append_array_begin. A PerfectCBSON shim now picks whichever this libbson has, so builds stay warning-free on 2.3+ and work on 2.0-2.2. SwiftPM's apt provider hint said `apt-get install libmongoc-dev`, which installs 1.x on Ubuntu 24.04 (the swift:*-noble images) and Debian 13. It can't vary by release, so it's removed; the README now lists which distributions' packages are new enough. CI gains an Ubuntu 26.04 job using apt's libmongoc (2.2.2), the oldest supported version. Full suite passes on 2.2.2 (Linux) and 2.5.5 (macOS, Linux). Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ Package.swift | 10 ++++++---- README.md | 14 ++++++++++---- README.zh_CN.md | 13 ++++++++++--- Sources/PerfectCBSON/shim.h | 12 ++++++++++++ Sources/PerfectMongoDB/BSON.swift | 2 +- Sources/PerfectMongoDB/BSONCodable.swift | 2 +- 7 files changed, 62 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bbea83..33916fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,28 @@ jobs: export LD_LIBRARY_PATH=$(dirname $(find /opt/mongoc -name 'libmongoc2.so' | head -1)) swift test + linux-apt: + # The oldest libmongoc we support, from the distribution package the README recommends. + name: Linux (Ubuntu 26.04, apt libmongoc) + runs-on: ubuntu-24.04 + container: swift:6.4-resolute + services: + mongo: + image: mongo:8 + env: + MONGODB_URI: mongodb://mongo:27017 + steps: + - uses: actions/checkout@v7 + + - name: Install libmongoc from apt + run: | + apt-get update + apt-get install -y --no-install-recommends pkg-config libmongoc-dev libbson-dev + echo "libmongoc $(pkg-config --modversion mongoc2)" + + - name: Test + run: swift test + macos: name: macOS (build + server-independent tests) runs-on: macos-15 diff --git a/Package.swift b/Package.swift index 1799972..4e4ab4c 100644 --- a/Package.swift +++ b/Package.swift @@ -32,16 +32,18 @@ let package = Package( name: "PerfectCBSON", pkgConfig: "bson2", providers: [ - .brew(["mongo-c-driver"]), - .apt(["libbson-dev"]) + // No apt provider: SwiftPM can't vary it by release, and libmongoc-dev is 2.x only on + // Ubuntu 26.04+ / Debian forky+; on Ubuntu 24.04 it installs 1.x. See the README. + .brew(["mongo-c-driver"]) ] ), .systemLibrary( name: "PerfectCMongo", pkgConfig: "mongoc2", providers: [ - .brew(["mongo-c-driver"]), - .apt(["libmongoc-dev"]) + // No apt provider: SwiftPM can't vary it by release, and libmongoc-dev is 2.x only on + // Ubuntu 26.04+ / Debian forky+; on Ubuntu 24.04 it installs 1.x. See the README. + .brew(["mongo-c-driver"]) ] ), .target( diff --git a/README.md b/README.md index 81a4384..761236a 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ targets: [ ## Requirements -libmongoc **2.x** must be installed where pkg-config can find `mongoc2` and `bson2`. +libmongoc **2.x** must be installed where pkg-config can find `mongoc2` and `bson2`. Tested with 2.2.2 and 2.5.5. **macOS** ([Homebrew](https://brew.sh)): @@ -45,9 +45,15 @@ brew install mongo-c-driver On Apple silicon, if SwiftPM can't find the library, set `PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig`. -**Linux:** most distributions still package libmongoc 1.x (for example Ubuntu's `libmongoc-dev`), which -this version doesn't support. Build libmongoc 2 from source, as the CI workflow in -`.github/workflows/ci.yml` does: +**Linux:** whether your distribution's package is new enough depends on the release: + +| Distribution | `libmongoc-dev` version | What to do | +|---|---|---| +| Ubuntu 26.04 LTS and later | 2.2 or later | `apt-get install libmongoc-dev libbson-dev` | +| Debian forky / sid | 2.5 | `apt-get install libmongoc-dev libbson-dev` | +| Ubuntu 24.04 LTS (used by the `swift:*-noble` images), Debian 13 and older | 1.x, not supported | Build from source (below) | + +To build libmongoc 2 from source, as the CI workflow in `.github/workflows/ci.yml` does: ```sh apt-get install cmake libssl-dev libsasl2-dev libzstd-dev diff --git a/README.zh_CN.md b/README.zh_CN.md index e5f299d..5393e91 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -33,7 +33,7 @@ targets: [ ## 环境要求 -必须安装 libmongoc **2.x**,并确保 pkg-config 能找到 `mongoc2` 和 `bson2`。 +必须安装 libmongoc **2.x**,并确保 pkg-config 能找到 `mongoc2` 和 `bson2`。已在 2.2.2 和 2.5.5 上测试。 **macOS**([Homebrew](https://brew.sh)): @@ -43,8 +43,15 @@ brew install mongo-c-driver 在 Apple 芯片的 Mac 上,如果 SwiftPM 找不到该库,请设置 `PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig`。 -**Linux:** 大多数发行版仍只提供 libmongoc 1.x(例如 Ubuntu 的 `libmongoc-dev`),本版本不支持。请参照 -`.github/workflows/ci.yml` 中 CI 的做法,从源码编译 libmongoc 2: +**Linux:** 发行版自带的软件包是否够新取决于版本: + +| 发行版 | `libmongoc-dev` 版本 | 做法 | +|---|---|---| +| Ubuntu 26.04 LTS 及更新版本 | 2.2 或更新 | `apt-get install libmongoc-dev libbson-dev` | +| Debian forky / sid | 2.5 | `apt-get install libmongoc-dev libbson-dev` | +| Ubuntu 24.04 LTS(`swift:*-noble` 镜像所用)、Debian 13 及更早版本 | 1.x,不支持 | 从源码编译(见下文) | + +参照 `.github/workflows/ci.yml` 中 CI 的做法,从源码编译 libmongoc 2: ```sh apt-get install cmake libssl-dev libsasl2-dev libzstd-dev diff --git a/Sources/PerfectCBSON/shim.h b/Sources/PerfectCBSON/shim.h index 42ee4b4..e358a55 100644 --- a/Sources/PerfectCBSON/shim.h +++ b/Sources/PerfectCBSON/shim.h @@ -1,2 +1,14 @@ #define BCON_H_ #include + +// libbson 2.3 added bson_append_array_unsafe_begin and deprecated bson_append_array_begin +// (same signature and behaviour). Use whichever this libbson has, so the package builds +// warning-free on current libbson and still builds on 2.0-2.2 (e.g. Ubuntu 26.04's 2.2.2). +static inline bool _perfect_bson_append_array_begin(bson_t *bson, const char *key, int key_length, bson_t *child) +{ +#if BSON_CHECK_VERSION(2, 3, 0) + return bson_append_array_unsafe_begin(bson, key, key_length, child); +#else + return bson_append_array_begin(bson, key, key_length, child); +#endif +} diff --git a/Sources/PerfectMongoDB/BSON.swift b/Sources/PerfectMongoDB/BSON.swift index 8ee199b..e10bb36 100644 --- a/Sources/PerfectMongoDB/BSON.swift +++ b/Sources/PerfectMongoDB/BSON.swift @@ -472,7 +472,7 @@ public class BSON: CustomStringConvertible { guard let doc = self.doc, let cdoc = child.doc else { return false } - return bson_append_array_unsafe_begin(toOpaque(doc), k, -1, toOpaque(cdoc)) + return _perfect_bson_append_array_begin(toOpaque(doc), k, -1, toOpaque(cdoc)) } /** diff --git a/Sources/PerfectMongoDB/BSONCodable.swift b/Sources/PerfectMongoDB/BSONCodable.swift index 38c7511..b47c873 100644 --- a/Sources/PerfectMongoDB/BSONCodable.swift +++ b/Sources/PerfectMongoDB/BSONCodable.swift @@ -219,7 +219,7 @@ public struct BSONEncoder: Sendable { case .array(let storage)?: let child = UnsafeMutablePointer.allocate(capacity: 1) defer { child.deallocate() } - guard bson_append_array_unsafe_begin(doc, key, -1, child) else { + guard _perfect_bson_append_array_begin(doc, key, -1, child) else { throw MongoError("could not start array '\(key)'") } for (index, box) in storage.boxes.enumerated() {