Repository navigation
Conversation
Moving to session-deps dropped the explicit libsession_static_bundle() registrations, so libsession-util.a shipped without libquic, oxen-logging, fmt, spdlog, ngtcp2, gnutls, nettle/hogweed, gmp, idn2, unistring, tasn1 and libevent. The 1.9.3 iOS xcframework therefore failed to link (74 undefined symbols in Session iOS). Resolve the bundle's full static closure once all targets are linked, instead of relying on per-dependency registration. The iOS modulemap now autolinks iconv. libunistring needs it, and session-deps takes it from the system on Apple rather than bundling it as 1.9.2 did.
session-deps' libunistring recipe never passed on the -liconv that libunistring needs on Apple, where iconv is its own system dylib rather than part of libSystem.
The bundle's archive list came from libsession_static_bundle() calls scattered across src/, proto/ and external/, each of which also tried to recurse into the target's dependencies at a point (right after add_library) where it had none yet. When dependencies stopped being registered by hand with the move to session-deps, the bundle silently lost libquic, oxen-logging, fmt, spdlog, ngtcp2, gnutls, nettle and the rest, and the 1.9.3 iOS build failed to link. Replace all of that with a single walk, run once every target is linked, from the libraries we export: every static library in their link closure goes into the bundle, so it can no longer drift from what is actually linked. Everything else in the closure (system libraries, frameworks, imported non-static targets such as Threads::Threads) is returned separately, since it has to be supplied by whatever links the bundle. A generator expression or imported target the walk cannot see into is a configure error rather than a silent omission.
static-bundle-test linked quic and oxenc next to libsession-util.a and only called config code, so it could not notice libquic or anything the network needs going missing from the bundle -- and no CI job built it anyway: the debian jobs build shared libraries, and the static jobs ran static-bundle.sh with WITH_TESTS=OFF and built only session-util. It now links the bundle and nothing but the system requirements the bundle walk reports, calls into the network as well as config, and is defined alongside the bundle rather than under tests/ so it does not need WITH_TESTS. static-bundle.sh, which every static job (Linux, Windows, macOS, iOS) goes through, builds it after the bundle, so a dependency missing from the bundle now fails the build that produces it.
|
I've pushed four commits on top of this:
Tested on Linux only: the normal build and tests pass, and |
service_node.hpp, session_network.hpp and session_network_types.hpp all include <nlohmann/json.hpp>, so it is part of the network target's public interface, not a private detail. It only went unnoticed because testAll adds nlohmann itself, and most build machines have a system copy on the default include path; static-bundle-test, which takes its headers purely from network's usage requirements, failed to compile on every static CI job (Android, iOS, macOS, Windows).
The 1.9.3 iOS xcframework doesn't link. Session iOS fails with 74 undefined symbols from libquic, oxen-logging, spdlog, fmt, nettle and libevent. The release
libsession-util.adropped from 2303 object files (1.9.2) to 260. Its simulator slice went from 64 MB to 22 MB.Cause
STATIC_BUNDLEbuildslibsession-util.afromLIBSESSION_STATIC_BUNDLE_LIBS, which targets join throughlibsession_static_bundle(). Before #179, every dependency was registered explicitly: libquic vialibsession_system_or_submodule, and gnutls/nettle/gmp/libevent viaStaticBuild.cmake'sadd_static_target. The session-deps switch removed both.session_dep,sessiondep_or_submoduleand oxen-logging'sload.cmakedon't register anything, so only sodium, zstd, simdutf and protobuf were still bundled.The recursive walk in
libsession_static_bundle()couldn't recover them:add_libsession_util_libraryregisters each library right afteradd_library, before itstarget_link_libraries, so the walk finds no dependencies.LINK_LIBRARIESfor static targets. session-deps'sessiondep_ext_*targets are imported, so their own deps (e.g. hogweed → nettle → gmp) are only inINTERFACE_LINK_LIBRARIES.Changes
libsession_static_bundle_resolve(), called just beforecombine_archives. It walks the full static closure of the registered targets once everything is linked. It followsINTERFACE_LINK_LIBRARIESfor imported/interface targets andLINK_LIBRARIESfor built ones, unwraps$<LINK_ONLY:>, and dedupes through aliases. The bundle list goes from 10 to 25 libraries, adding oxen-logging, fmt, spdlog, quic, ngtcp2 (+ crypto_gnutls), gnutls, hogweed, nettle, gmp, idn2, unistring, tasn1, and libevent core + pthreads.utils/ios.shaddslink "iconv"to the generated modulemap. libunistring callsiconv_open. 1.9.2 bundled GNU libiconv. session-deps deliberately uses the system libiconv on Apple and doesn't bundle it, so the bundle now needs-liconv, and an SPM binary target can't declare linker flags. With the module link declaration,import SessionUtilautolinks it.Verification (Xcode 27.0, 27A266a)
ios.sh's flags: stock bundles 10 libraries, this branch 25.utils/ios.shwith the bundle change: the xcframework builds. It has 2283 arm64 object files in both device and simulator slices, and all 74 symbols that were undefined in 1.9.3 are now defined.quic_max_udp_payload:_iconv,_iconv_openand_iconv_close.link "iconv"added to the modulemap: it links. 2251/2252 tests pass. The one failure,ThreadDisappearingMessagesSettingsViewModelSpec"can change to another setting and change back", is a flaky test that predates this change. Against the unmodified 1.9.2 release artifact, that spec failed in 4 of 5 iterations.ios.shrun with the finalios.shedit. The iconv line was tested by editing the generated modulemap by hand. Theios.shchange itself passedbash -n, and a dry run of its modulemap block produces the same output.Notes
Scripts/build_libSession_util.sh) generates its own modulemap. It will need the samelink "iconv"(or-liconv) once it builds against session-deps libsession.ios.sh. Android and the other bundle consumers go through the samecombine_archivespath, but I didn't build them.