Skip to content

Build a shim libcurl that can dispatch to runtime or system copies

Simon McVittie requested to merge wip/smcv/task119 into master
  • build-aux: Actually use clang for the build labelled "clang"

    🤦

  • Build a shim libcurl that can dispatch to runtime or system copies

    This works around ABI divergence from upstream in the libcurl in Debian/Ubuntu between about 2005 and 2018, which unfortunately includes the time at which Steam Runtime 1 'scout' started. Modern versions of libcurl have versioned symbols attached to a verdef CURL_OPENSSL_4, but Debian introduced versioned symbols before upstream did, and used CURL_OPENSSL_3. We want to be compatible with both.

    Similarly, modern upstream versions of libcurl when built against GNUTLS have versioned symbols attached to a verdef CURL_GNUTLS_4, but Debian introduced versioned symbols attached to a verdef CURL_GNUTLS_3, and is still using that verdef as of 2022. We want to be compatible with both, if we can.

    The trick here is that since glibc 2.30, the dynamic linker does not require triples (SONAME, version, symbol), but only looks for pairs of (SONAME, version) and, independently, (version, symbol). This means that dependencies on versioned symbols can be satisfied by any of the recursive dependencies of the library found when searching for the SONAME, and not just the library itself. glibc seems to have introduced this functionality so that glibc itself would be able to move symbols from its smaller libraries into libc.so.6 without breaking compatibility.

    The shim library has verdefs for both sets of versioned symbols, so it can be positioned in the search path as libcurl.so.4 and will satisfy both sets of requirements for the verdefs. For the actual symbols, it delegates to libsteam-runtime-system-libcurl.so.4 and libsteam-runtime-our-libcurl.so.4, which are expected to be set up by the runtime's setup.sh as symlinks to the real libraries that implement the two faces of libcurl.

    This requires some setup, which will be coordinated by a new version of setup.sh, in each of the pinned_libs_* directories. The real work is done by libcurl-compat/compat-setup.c, which uses the steam-runtime-tools library to find out whether the system libcurl is compatible with the expected ABIs.

    If there is no system copy of libcurl, then we do not need to do all this and can use the runtime's libcurl directly: binaries that rely on having a newer libcurl will fail, but by definition those binaries can't have been built or tested against the scout runtime.

    Helps: steamrt/tasks#119

  • debian: Build libcurl compat shim if and only if building for scout

    The versioned dependency on base-files is necessary to have VERSION_CODENAME in os-release.

  • libcurl-compat: Install mock libraries for testing

    To test this mechanism, it's useful to have a set of libraries that implement a predictable interface between distributions. Use a small subset of the real libcurl API.

    Helps: steamrt/tasks#119

  • tests: Add a test for the libcurl compatibility shim

    This can either be run as an ordinary build-time test, in which case it uses the just-built mock libraries for the build architecture only, or as an integration test for the LD_LIBRARY_PATH Steam Runtime:

      ~/.steam/root/ubuntu12_32/steam-runtime/run.sh -- \
      ~/tmp/steam-runtime-tools-tests/libcurl-compat.py --verbose

    in which case it expects to be run on an x86_64 machine, tests the mock libraries for both x86_64 and i386, and also asserts that the Steam Runtime has been set up to use the shim to provide the real libcurl ABI.

    Helps: steamrt/tasks#119

Supersedes: steamrt!132 (closed)

Edited by Simon McVittie

Merge request reports