soci: `soci` not found when adding as subproject

I can’t seem to be able to add soci as a subproject.

I have tried with ExternalProject_Add, and FetchContent but I can’t figure out why I keep getting:

CMake Error at src/test_app/CMakeLists.txt:21 (add_dependencies):
  The dependency target "soci" of target "test_app" does not exist.

Project description

My project structure is the following:

└── src
    ├── CMakeLists.txt
    ├── cmake
    │   ├── soci.cmake
    │   └── spdlog.cmake
    ├── test_app
    │   └── CMakeLists.txt
    └── (...)

src/CMakeLists.txt

cmake_minimum_required(VERSION 3.11)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(cmake/spdlog.cmake)
include(cmake/soci.cmake)

add_subdirectory(test_app)

src/test_app/CMakeLists.txt

cmake_minimum_required(VERSION 3.11)

project(test_app LANGUAGES CXX)

add_executable(test_app main.cpp)

target_link_libraries(test_app PRIVATE
    spdlog
    SOCI::core
)

add_dependencies(test_app spdlog soci)

spdlog.cmake

cmake_minimum_required(VERSION 3.11)

message(STATUS "Extern: spdlog v1.4.2")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(FetchContent)

FetchContent_Declare( spdlog
    GIT_REPOSITORY https://github.com/gabime/spdlog
    GIT_TAG v1.4.2
    GIT_SHALLOW ON
)
FetchContent_GetProperties(spdlog)
if(NOT spdlog_POPULATED)
    set(SPDLOG_BUILD_EXAMPLE OFF)
    set(SPDLOG_BUILD_EXAMPLE_HO OFF)
    set(SPDLOG_BUILD_TESTS OFF)
    set(SPDLOG_BUILD_TESTS_HO OFF)
    set(SPDLOG_BUILD_BENCH OFF)
    set(SPDLOG_SANITIZE_ADDRESS OFF)
    set(SPDLOG_INSTALL ON)
    set(SPDLOG_FMT_EXTERNAL OFF)
    FetchContent_Populate(spdlog)
    add_subdirectory(
        ${spdlog_SOURCE_DIR}
        ${spdlog_BINARY_DIR}
        EXCLUDE_FROM_ALL)
endif()

soci.cmake

cmake_minimum_required(VERSION 3.11)

message(STATUS "Extern: SOCI pre4.0+git_blksail")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(FetchContent)

FetchContent_Declare( soci
    GIT_REPOSITORY https://github.com/SOCI/soci
    GIT_TAG master
    GIT_SHALLOW ON
)
FetchContent_GetProperties(soci)
if(NOT soci_POPULATED)
    set(SOCI_STATIC ON)
    set(SOCI_SHARED ON)
    set(SOCI_TESTS OFF)
    # set(SOCI_ASAN OFF)
    set(SOCI_CXX11 ON)
    set(SOCI_LIBDIR lib)
    set(WITH_SQLITE3 ON)
    set(WITH_POSTGRESQL ON)
    set(WITH_BOOST OFF)
    set(WITH_DB2 OFF)
    set(WITH_ODBC OFF)
    set(WITH_ORACLE OFF)
    set(WITH_MYSQL OFF)
    set(SOCI_EMPTY OFF)
    FetchContent_Populate(soci)
    add_subdirectory(
        ${soci_SOURCE_DIR}
        ${soci_BINARY_DIR}
        EXCLUDE_FROM_ALL)
endif()

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 23 (11 by maintainers)

Commits related to this issue

Most upvoted comments

In case it’s useful, here’s a CMake function we use at work to bring in soci into our build (note the restrictions and assumptions as mentioned in the comments, etc.):

# Download soci using dependency details from "soci" and adds
# it to the build via add_subdirectory(). It will be assumed
# that Boost should be enabled unless the NO_BOOST option
# is given.
#
# Arguments to the function should be the required backends
# to enable in the soci build (all lowercase). Eg:
#
#  myCustomDependencyAddSoci(oracle postgresql)
#
function(myCustomDependencyAddSoci)
    if(NOT UNIX)
        message(FATAL_ERROR "Soci support only implemented for Unix")
    endif()

    include(FetchContent)
    FetchContent_GetProperties(soci)
    if(soci_POPULATED)
        return()
    endif()
    FetchContent_Populate(soci)

    # Set up for our customizations before bringing soci into the build
    set(options   "NO_BOOST")
    set(singleVal "")
    set(multiVal  "")
    cmake_parse_arguments(ARGS "${options}" "${singleVal}" "${multiVal}" ${ARGN})

    if(ARGS_NO_BOOST)
        set(WITH_BOOST OFF CACHE INTERNAL "")
    else()
        find_package(Boost QUIET)
        if(Boost_FOUND)
            set(WITH_BOOST ON  CACHE INTERNAL "")
        else()
            set(WITH_BOOST OFF CACHE INTERNAL "")
        endif()
    endif()

    set(requestedBackends ${ARGS_UNPARSED_ARGUMENTS})
    set(supportedBackends
        odbc
        oracle
        postgresql
        sqlite3
        db2
        firebird
        mysql
    )

    # Assumes you want C++11, no soci tests and build shared libs
    set(SOCI_CXX_C11 ON  CACHE INTERNAL "")
    set(SOCI_TESTS   OFF CACHE INTERNAL "")
    set(SOCI_STATIC  OFF CACHE INTERNAL "")

    foreach(backend IN LISTS supportedBackends)
        string(TOUPPER "${backend}" beUpper)
        string(TOLOWER "${backend}" beLower)
        if("${beLower}" IN_LIST requestedBackends)
            set(WITH_${beUpper} ON  CACHE INTERNAL "")
        else()
            set(WITH_${beUpper} OFF CACHE INTERNAL "")
        endif()
    endforeach()

    # Take over where soci will install things and under what component name
    include(GNUInstallDirs)
    set(BINDIR ${CMAKE_INSTALL_BINDIR} CACHE INTERNAL "")
    set(LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE INTERNAL "")
    set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME soci)

    # Because of manually defined SOCI_VERSION
    set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)

    add_subdirectory(${soci_SOURCE_DIR} ${soci_BINARY_DIR})

    # Ensure we have namespaced targets. These are what projects
    # should reference directly, not the unnamespaced soci_* targets.
    foreach(lib IN LISTS requestedBackends ITEMS core empty)
        if(NOT TARGET SOCI::soci_${lib})
            add_library(SOCI::soci_${lib} ALIAS soci_${lib})
        endif()
    endforeach()

    # Fix missing information in some targets (haven't tested all backends)
    set_property(TARGET soci_core APPEND PROPERTY
        INTERFACE_INCLUDE_DIRECTORIES
            $<BUILD_INTERFACE:${soci_BINARY_DIR}/include>
    )
    if(WITH_BOOST)
        set_property(TARGET soci_core APPEND PROPERTY
            INTERFACE_INCLUDE_DIRECTORIES
                $<TARGET_PROPERTY:Boost::boost,INTERFACE_INCLUDE_DIRECTORIES>
        )
        set_property(TARGET soci_core APPEND PROPERTY
            INTERFACE_COMPILE_DEFINITIONS SOCI_USE_BOOST
        )
    endif()
    if("oracle" IN_LIST requestedBackends)
        set_property(TARGET soci_oracle APPEND PROPERTY
            INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${ORACLE_HOME}/sdk/include>
        )
    endif()

    # Work around build warning that gets turned into an error when building
    # for release with more recent compilers. The warning seems questionable
    # for the specific case that gets triggered in vector-into-type.cpp.
    if(WITH_ORACLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
        target_compile_options(soci_oracle PRIVATE -Wno-maybe-uninitialized)
    endif()

endfunction()

It assumes you’ve declared the details you want before calling the function. Use it something like the following:

FetchContent_Declare(soci
    GIT_REPOSITORY https://github.com/SOCI/soci
    GIT_TAG 125753ff2fa8457b980fc4186606b9b08b2612b5
)

myCustomDependencySoci(oracle postgresql)

@tt4g, I resolved the issue by changing the following in the soci/CMakeLists.txt:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 004dd07..2125bd1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -149,7 +149,7 @@ set(INCLUDEDIR "include" CACHE PATH "The directory to install includes into.")
 ###############################################################################
 # Configuration files
 ###############################################################################
-set(CONFIG_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
+set(CONFIG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
 install(DIRECTORY ${CONFIG_INCLUDE_DIR}/soci DESTINATION ${INCLUDEDIR})
 set(CONFIG_FILE_IN "include/soci/soci-config.h.in")
 set(CONFIG_FILE_OUT "${CONFIG_INCLUDE_DIR}/soci/soci-config.h")

I have this as a patch during the FetchContent_Declare() in soci.cmake:

cmake_minimum_required(VERSION 3.11)

message(STATUS "Extern: SOCI pre4.0+git_blksail")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(FetchContent)

FetchContent_Declare( soci
    GIT_REPOSITORY https://github.com/SOCI/soci
    GIT_TAG master
    GIT_SHALLOW ON
    PATCH_COMMAND git apply "${CMAKE_SOURCE_DIR}/src/patches/soci.patch"
)
FetchContent_GetProperties(soci)
if(NOT soci_POPULATED)
    set(SOCI_STATIC ON)
    set(SOCI_SHARED ON)
    set(SOCI_TESTS OFF)
    # set(SOCI_ASAN OFF)
    set(SOCI_CXX11 ON)
    set(SOCI_LIBDIR lib)
    set(WITH_SQLITE3 ON)
    set(WITH_POSTGRESQL ON)
    set(WITH_BOOST OFF)
    set(WITH_DB2 OFF)
    set(WITH_ODBC OFF)
    set(WITH_ORACLE OFF)
    set(WITH_MYSQL OFF)
    set(SOCI_EMPTY OFF)
    FetchContent_Populate(soci)
    add_subdirectory(
        ${soci_SOURCE_DIR}
        ${soci_BINARY_DIR}
        EXCLUDE_FROM_ALL)
endif()