Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,33 @@ option(DEPENDENCY_CHECK "Check for dependencies of connector and the library" ON

set(SQLPP23_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Sqlpp23 CACHE STRING "Path to sqlpp23 cmake files")

# If we are building without C++20 modules, don't scan the sources for module dependencies
# This speeds up the build process.
if(NOT BUILD_WITH_MODULES)
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
endif()

### Main (core) library
add_core()

### Mock Database
add_component(NAME mock_db HEADER_DIR mock_db MODULE_INTERFACE sqlpp23.mock_db.cppm NO_INSTALL)

### Connector components
if(BUILD_SQLITE3_CONNECTOR)
add_component(NAME SQLite3 PACKAGE SQLite3 DEPENDENCIES SQLite::SQLite3 HEADER_DIR sqlite3)
add_component(NAME SQLite3 PACKAGE SQLite3 DEPENDENCIES SQLite::SQLite3 HEADER_DIR sqlite3 MODULE_INTERFACE sqlpp23.sqlite3.cppm)
endif()
if(BUILD_SQLCIPHER_CONNECTOR)
add_component(NAME SQLCipher PACKAGE SQLCipher DEPENDENCIES SQLCipher::SQLCipher DEFINES SQLPP_USE_SQLCIPHER HEADER_DIR sqlite3)
add_component(NAME SQLCipher PACKAGE SQLCipher DEPENDENCIES SQLCipher::SQLCipher DEFINES SQLPP_USE_SQLCIPHER HEADER_DIR sqlite3 MODULE_INTERFACE sqlpp23.sqlite3.cppm)
endif()
if(BUILD_MYSQL_CONNECTOR)
add_component(NAME MySQL PACKAGE MySQL DEPENDENCIES MySQL::MySQL HEADER_DIR mysql)
add_component(NAME MySQL PACKAGE MySQL DEPENDENCIES MySQL::MySQL HEADER_DIR mysql MODULE_INTERFACE sqlpp23.mysql.cppm)
endif()
if(BUILD_MARIADB_CONNECTOR)
add_component(NAME MariaDB PACKAGE MariaDB DEPENDENCIES MariaDB::MariaDB HEADER_DIR mysql)
add_component(NAME MariaDB PACKAGE MariaDB DEPENDENCIES MariaDB::MariaDB HEADER_DIR mysql MODULE_INTERFACE sqlpp23.mysql.cppm)
endif()
if(BUILD_POSTGRESQL_CONNECTOR)
add_component(NAME PostgreSQL PACKAGE PostgreSQL DEPENDENCIES PostgreSQL::PostgreSQL HEADER_DIR postgresql)
add_component(NAME PostgreSQL PACKAGE PostgreSQL DEPENDENCIES PostgreSQL::PostgreSQL HEADER_DIR postgresql MODULE_INTERFACE sqlpp23.postgresql.cppm)
endif()

# Utility programs
Expand All @@ -82,15 +91,9 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Sqlpp23ConfigVersion.cmake
install(EXPORT Sqlpp23Targets
DESTINATION ${SQLPP23_INSTALL_CMAKEDIR}
NAMESPACE sqlpp23::
CXX_MODULES_DIRECTORY .
)

# C++20 modules
if(BUILD_WITH_MODULES)
add_subdirectory(modules)
else()
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
endif()

### Tests
if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
add_subdirectory(tests)
Expand Down
157 changes: 120 additions & 37 deletions cmake/Sqlpp23TargetHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,86 +25,169 @@
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# Helper macro that is used to forward option arguments in function calls
# Taken from https://stackoverflow.com/a/75994425/5689371
macro(set_if OPTION CONDITION)
if(${CONDITION})
set(${OPTION} "${OPTION}")
else()
set(${OPTION})
endif()
endmacro()

function(add_core)
# The core library needs the core headers plus all the headers in the top include directory
file(GLOB_RECURSE HDR_COMPONENT LIST_DIRECTORIES false ${PROJECT_SOURCE_DIR}/include/sqlpp23/core/*.h)
file(GLOB HDR_COMMON LIST_DIRECTORIES false ${PROJECT_SOURCE_DIR}/include/sqlpp23/*.h)
set(HEADERS ${HDR_COMPONENT} ${HDR_COMMON})
add_common(
add_regular_and_module(
CONFIG_SCRIPT Sqlpp23Config.cmake
HEADERS ${HEADERS}
MODULE_INTERFACE sqlpp23.core.cppm
TARGET_NAME sqlpp23
TARGET_ALIAS sqlpp23::core
TARGET_EXPORTED core
)
endfunction()

function(add_component)
set(options)
set(oneValueArgs HEADER_DIR NAME PACKAGE)
set(options NO_INSTALL)
set(oneValueArgs HEADER_DIR MODULE_INTERFACE NAME PACKAGE)
set(multiValueArgs DEFINES DEPENDENCIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

file(GLOB_RECURSE HEADERS LIST_DIRECTORIES false ${PROJECT_SOURCE_DIR}/include/sqlpp23/${ARG_HEADER_DIR}/*.h)
string(TOLOWER ${ARG_NAME} LC_NAME)
add_common(
set_if(NO_INSTALL ARG_NO_INSTALL)
add_regular_and_module(
CONFIG_SCRIPT Sqlpp23${ARG_NAME}Config.cmake
DEFINES ${ARG_DEFINES}
DEPENDENCIES ${ARG_DEPENDENCIES}
DEPENDENCIES sqlpp23::core ${ARG_DEPENDENCIES}
HEADERS ${HEADERS}
MODULE_INTERFACE ${ARG_MODULE_INTERFACE}
PACKAGE ${ARG_PACKAGE}
TARGET_NAME sqlpp23_${LC_NAME}
TARGET_ALIAS sqlpp23::${LC_NAME}
TARGET_EXPORTED ${LC_NAME}
${NO_INSTALL}
)
endfunction()

function(add_regular_and_module)
set(options NO_INSTALL)
set(oneValueArgs CONFIG_SCRIPT MODULE_INTERFACE PACKAGE TARGET_NAME TARGET_ALIAS TARGET_EXPORTED)
set(multiValueArgs DEFINES DEPENDENCIES HEADERS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if(ARG_PACKAGE)
if(DEPENDENCY_CHECK)
find_package(${ARG_PACKAGE} REQUIRED)
endif()
if(NOT ARG_NO_INSTALL)
# If the package needs a special find script, copy it to the destination scripts directory
set(FIND_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/modules/Find{ARG_PACKAGE}.cmake)
if(EXISTS ${FIND_SCRIPT})
install(FILES ${FIND_SCRIPT} DESTINATION ${SQLPP23_INSTALL_CMAKEDIR})
endif()
endif()
endif()
if(NOT ARG_NO_INSTALL)
install(
FILES ${PROJECT_SOURCE_DIR}/cmake/configs/${ARG_CONFIG_SCRIPT}
DESTINATION ${SQLPP23_INSTALL_CMAKEDIR}
)
endif()
set_if(NO_INSTALL ARG_NO_INSTALL)
add_common(
DEFINES ${ARG_DEFINES}
DEPENDENCIES ${ARG_DEPENDENCIES}
HEADERS ${HEADERS}
TARGET_NAME ${ARG_TARGET_NAME}
TARGET_ALIAS ${ARG_TARGET_ALIAS}
TARGET_EXPORTED ${ARG_TARGET_EXPORTED}
${NO_INSTALL}
)
if(BUILD_WITH_MODULES AND ARG_MODULE_INTERFACE)
add_common(
DEFINES ${ARG_DEFINES}
DEPENDENCIES ${ARG_DEPENDENCIES}
HEADERS ${HEADERS}
MODULE_INTERFACE ${ARG_MODULE_INTERFACE}
TARGET_NAME ${ARG_TARGET_NAME}
TARGET_ALIAS ${ARG_TARGET_ALIAS}
TARGET_EXPORTED ${ARG_TARGET_EXPORTED}
${NO_INSTALL}
)
endif()
endfunction()

function(add_common)
set(options)
set(oneValueArgs CONFIG_SCRIPT PACKAGE TARGET_NAME TARGET_ALIAS TARGET_EXPORTED)
set(options NO_INSTALL)
set(oneValueArgs MODULE_INTERFACE TARGET_NAME TARGET_ALIAS TARGET_EXPORTED)
set(multiValueArgs DEFINES DEPENDENCIES HEADERS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

# If the component needs a specific package, check if it is installed
if(ARG_PACKAGE AND DEPENDENCY_CHECK)
find_package(${ARG_PACKAGE} REQUIRED)
# Initialize helper variables based on target type (regular or module)
if(ARG_MODULE_INTERFACE)
set(TARGET_SUFFIX "_module")
# FILE_SETs of type CXX_MODULES cannot have the INTERFACE scope (exept
# on IMPORTED targets) and INTERFACE libraries only allow INTERFACE
# scope on their properties. That's why we cannot use the INTERFACE
# library type. For details see the discussion at
# https://discourse.cmake.org/t/header-only-libraries-and-c-20-modules/10680/11
set(LIB_TYPE OBJECT)
set(LIB_PROP_SCOPE PUBLIC)
else()
set(TARGET_SUFFIX "")
set(LIB_TYPE INTERFACE)
set(LIB_PROP_SCOPE INTERFACE)
endif()
set(TARGET_NAME ${ARG_TARGET_NAME}${TARGET_SUFFIX})
set(TARGET_ALIAS ${ARG_TARGET_ALIAS}${TARGET_SUFFIX})
set(TARGET_EXPORTED ${ARG_TARGET_EXPORTED}${TARGET_SUFFIX})

# Create the component targets
add_library(${ARG_TARGET_NAME} INTERFACE)
add_library(${ARG_TARGET_ALIAS} ALIAS ${ARG_TARGET_NAME})
set_target_properties(${ARG_TARGET_NAME} PROPERTIES EXPORT_NAME ${ARG_TARGET_EXPORTED})
target_compile_features(${ARG_TARGET_NAME} INTERFACE cxx_std_23)
add_library(${TARGET_NAME} ${LIB_TYPE})
add_library(${TARGET_ALIAS} ALIAS ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME ${TARGET_EXPORTED})
target_compile_features(${TARGET_NAME} ${LIB_PROP_SCOPE} cxx_std_23)
if(ARG_DEFINES)
target_compile_definitions(${ARG_TARGET_NAME} INTERFACE ${ARG_DEFINES})
endif()
if(ARG_DEPENDENCIES)
target_link_libraries(${ARG_TARGET_NAME} INTERFACE sqlpp23 ${ARG_DEPENDENCIES})
target_compile_definitions(${TARGET_NAME} ${LIB_PROP_SCOPE} ${ARG_DEFINES})
endif()
foreach(DEP ${ARG_DEPENDENCIES})
if(DEP MATCHES "^sqlpp23::")
set(DEP ${DEP}${TARGET_SUFFIX})
endif()
target_link_libraries(${TARGET_NAME} ${LIB_PROP_SCOPE} ${DEP})
endforeach()

# Add the component headers to the HEADERS file set. This also adds the base directory to the
# target's build interface include directories.
target_sources(
${ARG_TARGET_NAME}
INTERFACE
FILE_SET HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR}/include FILES ${ARG_HEADERS}
)

# Install the component
install(
TARGETS ${ARG_TARGET_NAME}
EXPORT Sqlpp23Targets
${TARGET_NAME}
${LIB_PROP_SCOPE}
FILE_SET HEADERS
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
FILES ${PROJECT_SOURCE_DIR}/cmake/configs/${ARG_CONFIG_SCRIPT}
DESTINATION ${SQLPP23_INSTALL_CMAKEDIR}
BASE_DIRS ${PROJECT_SOURCE_DIR}/include
FILES ${ARG_HEADERS}
)
if(ARG_PACKAGE)
set(FIND_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/modules/Find{ARG_PACKAGE}.cmake)
if(EXISTS ${FIND_SCRIPT})
install(FILES ${FIND_SCRIPT} DESTINATION ${SQLPP23_INSTALL_CMAKEDIR})
endif()
if(ARG_MODULE_INTERFACE)
# Add the component module interface file to the CXX_MODULES file set
target_sources(
${TARGET_NAME}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${PROJECT_SOURCE_DIR}/modules
FILES ${PROJECT_SOURCE_DIR}/modules/${ARG_MODULE_INTERFACE}
)
endif()
if(NOT ARG_NO_INSTALL)
# Install the component output artifacts
install(
TARGETS ${TARGET_NAME}
EXPORT Sqlpp23Targets
FILE_SET HEADERS
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_PREFIX}/modules/sqlpp23
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
endfunction()
38 changes: 26 additions & 12 deletions docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,32 @@ You can find examples for both methods in the examples folder.
1. FetchContent (Recommended, no installation required)
1. FindPackage (installation required, see below)

Both methods will provide the core target `sqlpp23::core` as well as its alias
`sqlpp23::sqlpp23` for backwards compatibility. Also the following connector-specific
targets are provided:

- sqlpp23::mysql
- sqlpp23::mariadb
- sqlpp23::sqlite3
- sqlpp23::sqlcipher
- sqlpp23::postgresql

These targets will make sure all required dependencies are available and
correctly linked and include directories are set correctly.
Both methods will provide the following CMake targets

| Target | How to include | Description |
| ------ | -------------- | ----------- |
| sqlpp23::core | #include <sqlpp23/sqlpp23.h> | The core functionality, which is not connector-specifix, as headers |
| sqlpp23::core_module | import sqlpp23::core; | The core functionality, which is not connector-specifix, as a module |
| sqlpp23::sqlpp23 | #include <sqlpp23/sqlpp23.h> | A backwards-compatible alias of sqlpp23::core |
| sqlpp23::mariadb | #include <sqlpp23/mysql/mysql.h>[^1] | The MariaDB connector as headers |
| sqlpp23::mariadb_module | import sqlpp23::mariadb; | The MariaDB connector as a module |
| sqlpp23::mysql | #include <sqlpp23/mysql/mysql.h> | The MySQL connector as headers |
| sqlpp23::mysql_module | import sqlpp23::mysql; | The MySQL connector as a module |
| sqlpp23::postgresql | #include <sqlpp23/postgresql/postgresql.h> | The PostgreSQL connector as headers |
| sqlpp23::postgresql_module | import sqlpp23::postgresql; | The PostgreSQL connector as a module |
| sqlpp23::sqlcipher | #include <sqlpp23/sqlite3/sqlite3.h>[^2] | The SQLCipher connector as headers |
| sqlpp23::sqlcipher_module | import sqlpp23::sqlcipher; | The SQLCipher connector as a module |
| sqlpp23::sqlite3 | #include <sqlpp23/sqlite3/sqlite3.h> | The SQLite3 connector as headers |
| sqlpp23::sqlite3_module | import sqlpp23::sqlite3; | The SQLite3 connector as a module |

[^1]: The SQLCipher connector re-uses the codebase of the SQLite3 connector.
That's why you use the SQLCipher connector by including the SQLite3 headers.
[^2]: The MariaDB connector re-uses the codebase of the MySQL connector. That's
why you use the MariaDB connector by including the MySQL headers.

These targets will make sure all required dependencies are available, correctly
linked, include directories are set correctly and module interface files (if
using the module targets) are added to your project sources.

## Build and install

Expand Down
88 changes: 0 additions & 88 deletions modules/CMakeLists.txt

This file was deleted.

Loading