In my previous post, How to Build Statically Linked Transmission Daemon 4, I demostrated the way to create a statically linked transmission-daemon. While effective, that approach involved manually linking the final binary which is not ideal in my optinion. After some trials and erros, I discovered a more elegant solution by patching the CMakeLists.txt file for transmission-daemon, which simplifies the process significantly.

The New Approach

The key improvement in this refined method is to apply a patch to the daemon/CMakeLists.txt file. This patch, available here, modifies the build process to better support static linking. Here’s a detailed look at what the patch does.

What the Patch Does

The patch makes several critical changes to the CMakeLists.txt file:

  1. Sets Library Search Preferences:

    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so")
    

    This line prioritizes static libraries (.a) over shared libraries (.so) during the build process.

  2. Explicitly Finds Required Libraries:

    The patch adds several find_library commands to locate necessary dependencies:

    find_library(LIB_CURL NAMES curl PATHS /usr/lib REQUIRED)
    find_library(LIB_BROTLIDEC NAMES brotlidec PATHS /usr/lib REQUIRED)
    find_library(LIB_NGHTTP2 NAMES nghttp2 PATHS /usr/lib REQUIRED)
    find_library(LIB_CARES NAMES cares PATHS /usr/lib REQUIRED)
    find_library(LIB_IDN2 NAMES idn2 PATHS /usr/lib REQUIRED)
    find_library(LIB_UNISTRING NAMES unistring PATHS /usr/lib REQUIRED)
    find_library(LIB_SSL NAMES ssl PATHS /usr/lib REQUIRED)
    find_library(LIB_Z NAMES z PATHS /lib /usr/lib REQUIRED)
    find_library(LIB_CRYPTO NAMES crypto PATHS /usr/lib REQUIRED)
    find_library(LIB_BROTLICOMMON NAMES brotlicommon PATHS /usr/lib REQUIRED)
    

    These commands ensure that the necessary libraries for static linking are located during the build configuration.

  3. Links Libraries Statically:

    The target_link_libraries command is updated to link these static libraries:

    target_link_libraries(${TR_NAME}-daemon
        PRIVATE
            ${TR_NAME}
            libevent::event
            fmt::fmt-header-only
            $<$<BOOL:${WITH_SYSTEMD}>:${SYSTEMD_LIBRARIES}>
        PUBLIC
            ${LIB_CURL}
            ${LIB_BROTLIDEC}
            ${LIB_NGHTTP2}
            ${LIB_CARES}
            ${LIB_IDN2}
            ${LIB_UNISTRING}
            ${LIB_SSL}
            ${LIB_Z}
            ${LIB_CRYPTO}
            ${LIB_BROTLICOMMON}
    )
    

    This ensures that the Transmission daemon binary is linked against the static versions of these libraries, creating a fully self-contained executable.