SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.41k stars 477 forks source link

Linking backends statically #1017

Closed Tectu closed 1 year ago

Tectu commented 1 year ago

I'm currently including SOCI (commit 074722a62734a14dfa8fe1e8b61fb51a4b505d89) via CMake's FetchContent capability. So far, everything worked just fine.

I'd now like to link SOCI statically instead of dynamically. For this, I set SOCI_STATIC to ON (and SOCI_SHARED to OFF) and linked to the various SOCI CMake targets with the _static suffix.

For example, previously when linking shared libraries I used:

target_link_libraries(
    ${TARGET}
    PRIVATE
        Soci::core
        Soci::sqlite3
        SQLite::SQLite3
)        

Now I changed it to:

target_link_libraries(
    ${TARGET}
    PRIVATE
        Soci::core_static
        Soci::sqlite3_static
        SQLite::SQLite3
)        

The program still builds fine. However, when launching it I get the following exception:

Failed to find shared library for backend sqlite3

Does this mean that the SOCI backend implementation for SQLite3 could not be found or the actual SQLite3 library itself could not be found? From what I can tell it's the former as the SQLite3 library is certainly on the system and nothing changed there when switching from linking SOCI dynamically to linking SOCI statically.

What exactly am I missing here? Both libsoci_core.a and libsoci_sqlite3.a exist in the build directory and were supposedly linked successfully as the build succeeded. Why would the SOCI core attempt to find the shared library backend anyway if I link it statically?

For completion, this is how I include SOCI into my project:

FetchContent_Declare(
    soci
    GIT_REPOSITORY https://github.com/SOCI/soci
    GIT_TAG        074722a62734a14dfa8fe1e8b61fb51a4b505d89
)
FetchContent_GetProperties(soci)
if (NOT soci_POPULATED)
    FetchContent_Populate(soci)

    set(SOCI_SHARED     OFF CACHE INTERNAL "")
    set(SOCI_STATIC     ON  CACHE INTERNAL "")
    set(SOCI_TESTS      OFF CACHE INTERNAL "")
    set(SOCI_VISIBILITY ON  CACHE INTERNAL "")
    set(SOCI_LTO        ON  CACHE INTERNAL "")

    # Enabled backends
    set(SOCI_POSTGRESQL ON CACHE INTERNAL "")
    set(SOCI_SQLITE3    ON CACHE INTERNAL "")

    # Disabled backends
    set(SOCI_EMPTY    OFF CACHE INTERNAL "")
    set(SOCI_DB2      OFF CACHE INTERNAL "")
    set(SOCI_FIREBIRD OFF CACHE INTERNAL "")
    set(SOCI_MYSQL    OFF CACHE INTERNAL "")
    set(SOCI_ODBC     OFF CACHE INTERNAL "")

    add_subdirectory(${soci_SOURCE_DIR} ${soci_BINARY_DIR} EXCLUDE_FROM_ALL)    # EXCLUDE_FROM_ALL to prevent install()
endif()
Tectu commented 1 year ago

Well, I was using the loadable backend in my application code when creating the session. Hence SOCI was looking for the corresponding shared library. Fixed that and now it works as expected :)