2019-06-27 03:55:27 +00:00
# Main CMake file for compiling the library itself, examples and tests.
#
# Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
#
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT)
cmake_minimum_required ( VERSION 2.8.12 ) # first version with add_compile_options()
project ( SQLiteCpp )
message ( STATUS "CMake version: ${CMAKE_VERSION}" )
# Define useful variables to handle OS differences:
if ( WIN32 )
set ( DEV_NULL "NUL" )
else ( WIN32 ) # UNIX
set ( DEV_NULL "/dev/null" )
endif ( WIN32 )
# then Compiler/IDE differences:
if ( MSVC )
set ( CPPLINT_ARG_OUTPUT "--output=vs7" )
set ( CPPCHECK_ARG_TEMPLATE "--template=vs" )
# disable Visual Studio warnings for fopen() used in the example
add_definitions ( -D_CRT_SECURE_NO_WARNINGS )
# Flags for linking with multithread static C++ runtime, required by googletest
if ( SQLITECPP_BUILD_TESTS )
message ( STATUS "Linking against multithread static C++ runtime for unit tests with googletest" )
set ( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT" )
set ( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd" )
set ( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT" )
set ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd" )
endif ( SQLITECPP_BUILD_TESTS )
# Handle the (partly supported) MSVC versions prior to 2015
if ( MSVC_VERSION LESS 1900 ) # OR MSVC_TOOLSET_VERSION LESS 140)
message ( WARNING "MSVC < 2015 detected: Visual Studio prior to 2015 is not fully supported. BLOB storage seems to be corrupted." )
endif ( MSVC_VERSION LESS 1900 )
else ( MSVC )
set ( CPPLINT_ARG_OUTPUT "--output=eclipse" )
set ( CPPCHECK_ARG_TEMPLATE "--template=gcc" )
# Useful compile flags and extra warnings
add_compile_options ( -fstack-protector -Wall -Wextra -Wpedantic -Wno-long-long -Wswitch-enum -Wshadow -Winline )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++0x-compat" ) # C++ only
if ( CMAKE_COMPILER_IS_GNUCXX )
# GCC flags
option ( SQLITECPP_USE_GCOV "USE GCov instrumentation." OFF )
if ( SQLITECPP_USE_GCOV )
message ( STATUS "Using GCov instrumentation" )
add_compile_options ( -coverage ) # NOTE -fkeep-inline-functions would be usefull but not working with current google test and gcc 4.8
set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage" )
endif ( )
endif ( CMAKE_COMPILER_IS_GNUCXX )
endif ( MSVC )
# and then common variables
set ( CPPLINT_ARG_VERBOSE "--verbose=3" )
set ( CPPLINT_ARG_LINELENGTH "--linelength=120" )
# Print CXX compiler information
message ( STATUS "CMAKE_CXX_COMPILER '${CMAKE_CXX_COMPILER}' '${CMAKE_CXX_COMPILER_ID}' '${CMAKE_CXX_COMPILER_VERSION}'" )
# Print CXX FLAGS
message ( STATUS "CMAKE_CXX_FLAGS '${CMAKE_CXX_FLAGS}'" )
if ( MSVC )
message ( STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'" )
message ( STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'" )
message ( STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'" )
message ( STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'" )
else ( NOT MSVC )
if ( CMAKE_BUILD_TYPE STREQUAL Debug )
message ( STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'" )
elseif ( CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo )
message ( STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'" )
elseif ( CMAKE_BUILD_TYPE STREQUAL MinSizeRel )
message ( STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'" )
else ( )
message ( STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'" )
endif ( )
endif ( )
# Options relative to SQLite and SQLiteC++ functions
option ( SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON )
if ( SQLITE_ENABLE_COLUMN_METADATA )
# Enable the use of SQLite column metadata and Column::getColumnOriginName() method,
# Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X).
add_definitions ( -DSQLITE_ENABLE_COLUMN_METADATA )
endif ( SQLITE_ENABLE_COLUMN_METADATA )
option ( SQLITE_ENABLE_ASSERT_HANDLER "Enable the user defintion of a assertion_failed() handler." OFF )
if ( SQLITE_ENABLE_ASSERT_HANDLER )
# Enable the user defintion of a assertion_failed() handler (default to false, easier to handler for begginers).
add_definitions ( -DSQLITECPP_ENABLE_ASSERT_HANDLER )
endif ( SQLITE_ENABLE_ASSERT_HANDLER )
option ( SQLITE_USE_LEGACY_STRUCT "Fallback to forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)" OFF )
if ( SQLITE_USE_LEGACY_STRUCT )
# Force forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)
add_definitions ( -DSQLITE_USE_LEGACY_STRUCT )
endif ( SQLITE_USE_LEGACY_STRUCT )
## Build the C++ Wrapper ##
# adding a new file require explicittly modifing the CMakeLists.txt
# so that CMake knows that it should rebuild the project (it is best practice)
# list of sources files of the library
set ( SQLITECPP_SRC
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / B a c k u p . c p p
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / C o l u m n . c p p
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / D a t a b a s e . c p p
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / E x c e p t i o n . c p p
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / S t a t e m e n t . c p p
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / T r a n s a c t i o n . c p p
)
source_group ( src FILES ${ SQLITECPP_SRC } )
# list of header files of the library
set ( SQLITECPP_INC
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / S Q L i t e C p p . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / A s s e r t i o n . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / B a c k u p . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / C o l u m n . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / D a t a b a s e . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / E x c e p t i o n . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / S t a t e m e n t . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / T r a n s a c t i o n . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / U t i l s . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / V a r i a d i c B i n d . h
$ { P R O J E C T _ S O U R C E _ D I R } / i n c l u d e / S Q L i t e C p p / E x e c u t e M a n y . h
)
source_group ( include FILES ${ SQLITECPP_INC } )
# list of test files of the library
set ( SQLITECPP_TESTS
t e s t s / C o l u m n _ t e s t . c p p
t e s t s / D a t a b a s e _ t e s t . c p p
t e s t s / S t a t e m e n t _ t e s t . c p p
t e s t s / B a c k u p _ t e s t . c p p
t e s t s / T r a n s a c t i o n _ t e s t . c p p
t e s t s / V a r i a d i c B i n d _ t e s t . c p p
t e s t s / E x c e p t i o n _ t e s t . c p p
t e s t s / E x e c u t e M a n y _ t e s t . c p p
)
source_group ( tests FILES ${ SQLITECPP_TESTS } )
# list of example files of the library
set ( SQLITECPP_EXAMPLES
e x a m p l e s / e x a m p l e 1 / m a i n . c p p
)
source_group ( example1 FILES ${ SQLITECPP_EXAMPLES } )
# list of doc files of the library
set ( SQLITECPP_DOC
R E A D M E . m d
L I C E N S E . t x t
C H A N G E L O G . m d
T O D O . t x t
)
source_group ( doc FILES ${ SQLITECPP_DOC } )
# list of script files of the library
set ( SQLITECPP_SCRIPT
. t r a v i s . y m l
a p p v e y o r . y m l
b u i l d . b a t
b u i l d . s h
c p p l i n t . p y
D o x y f i l e
F i n d S Q L i t e C p p . c m a k e
)
source_group ( scripts FILES ${ SQLITECPP_SCRIPT } )
# All includes are relative to the "include" directory
include_directories ( "${PROJECT_SOURCE_DIR}/include" )
# add sources of the wrapper as a "SQLiteCpp" static library
add_library ( SQLiteCpp ${ SQLITECPP_SRC } ${ SQLITECPP_INC } ${ SQLITECPP_DOC } ${ SQLITECPP_SCRIPT } )
# make the sqlite3 library part of the interface of the SQLiteCpp wrapper itself (the client app does not need to link to sqlite3)
# PR https://github.com/SRombauts/SQLiteCpp/pull/111 "linked SQLiteCpp to sqlite3" commented out since it breaks install step from PR #118
#target_link_libraries(SQLiteCpp PUBLIC sqlite3)
if ( UNIX AND ( CMAKE_COMPILER_IS_GNUCXX OR ${ CMAKE_CXX_COMPILER_ID } STREQUAL "Clang" ) )
set_target_properties ( SQLiteCpp PROPERTIES COMPILE_FLAGS "-fPIC" )
endif ( UNIX AND ( CMAKE_COMPILER_IS_GNUCXX OR ${ CMAKE_CXX_COMPILER_ID } STREQUAL "Clang" ) )
# Allow the library to be installed via "make install" and found with "find_package"
install ( TARGETS SQLiteCpp
E X P O R T $ { P R O J E C T _ N A M E } C o n f i g
L I B R A R Y D E S T I N A T I O N l i b
A R C H I V E D E S T I N A T I O N l i b
C O M P O N E N T l i b r a r i e s )
target_include_directories ( SQLiteCpp PUBLIC
$ < B U I L D _ I N T E R F A C E : $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / i n c l u d e >
$ < I N S T A L L _ I N T E R F A C E : i n c l u d e / > )
install ( DIRECTORY include/ DESTINATION include COMPONENT headers FILES_MATCHING REGEX ".*\\.(hpp|h)$" )
install ( EXPORT ${ PROJECT_NAME } Config DESTINATION lib/cmake/ ${ PROJECT_NAME } )
## Build provided copy of SQLite3 C library ##
# TODO
#find_package(sqlite3)
#if(sqlite3_VERSION VERSION_LESS "3.19")
# set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT")
#endif()
option ( SQLITECPP_USE_ASAN "Use Address Sanitizer." OFF )
if ( SQLITECPP_USE_ASAN )
if ( ( CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 6 ) OR ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) )
message ( STATUS "Using Address Sanitizer" )
set_target_properties ( SQLiteCpp PROPERTIES COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer" )
set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" )
if ( CMAKE_COMPILER_IS_GNUCXX )
set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold" )
endif ( )
endif ( )
endif ( SQLITECPP_USE_ASAN )
option ( SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON )
if ( SQLITECPP_INTERNAL_SQLITE )
# build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package
add_subdirectory ( sqlite3 )
target_include_directories ( sqlite3 PUBLIC "${PROJECT_SOURCE_DIR}/sqlite3" )
target_include_directories ( SQLiteCpp PRIVATE "${PROJECT_SOURCE_DIR}/sqlite3" )
endif ( SQLITECPP_INTERNAL_SQLITE )
# Optional additional targets:
option ( SQLITECPP_RUN_CPPLINT "Run cpplint.py tool for Google C++ StyleGuide." ON )
if ( SQLITECPP_RUN_CPPLINT )
find_package ( PythonInterp )
if ( PYTHONINTERP_FOUND )
# add a cpplint target to the "all" target
add_custom_target ( SQLiteCpp_cpplint
A L L
C O M M A N D $ { P Y T H O N _ E X E C U T A B L E } $ { P R O J E C T _ S O U R C E _ D I R } / c p p l i n t . p y $ { C P P L I N T _ A R G _ O U T P U T } $ { C P P L I N T _ A R G _ V E R B O S E } $ { C P P L I N T _ A R G _ L I N E L E N G T H } $ { S Q L I T E C P P _ S R C } $ { S Q L I T E C P P _ I N C }
)
endif ( PYTHONINTERP_FOUND )
else ( SQLITECPP_RUN_CPPLINT )
message ( STATUS "SQLITECPP_RUN_CPPLINT OFF" )
endif ( SQLITECPP_RUN_CPPLINT )
option ( SQLITECPP_RUN_CPPCHECK "Run cppcheck C++ static analysis tool." ON )
if ( SQLITECPP_RUN_CPPCHECK )
find_program ( CPPCHECK_EXECUTABLE NAMES cppcheck )
if ( CPPCHECK_EXECUTABLE )
# add a cppcheck target to the "all" target
add_custom_target ( SQLiteCpp_cppcheck
A L L
C O M M A N D $ { C P P C H E C K _ E X E C U T A B L E } - j 8 c p p c h e c k - - e n a b l e = s t y l e - - q u i e t $ { C P P C H E C K _ A R G _ T E M P L A T E } $ { P R O J E C T _ S O U R C E _ D I R } / s r c
)
execute_process ( COMMAND "${CPPCHECK_EXECUTABLE}" --version OUTPUT_VARIABLE CPPCHECK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE )
message ( STATUS "Found Cppcheck: ${CPPCHECK_EXECUTABLE} ${CPPCHECK_VERSION}" )
else ( CPPCHECK_EXECUTABLE )
message ( STATUS "Could NOT find cppcheck" )
endif ( CPPCHECK_EXECUTABLE )
else ( SQLITECPP_RUN_CPPCHECK )
message ( STATUS "SQLITECPP_RUN_CPPCHECK OFF" )
endif ( SQLITECPP_RUN_CPPCHECK )
option ( SQLITECPP_RUN_DOXYGEN "Run Doxygen C++ documentation tool." OFF )
if ( SQLITECPP_RUN_DOXYGEN )
find_package ( Doxygen )
if ( DOXYGEN_FOUND )
# add a Doxygen target to the "all" target
add_custom_target ( SQLiteCpp_doxygen
A L L
C O M M A N D d o x y g e n D o x y f i l e > $ { D E V _ N U L L }
W O R K I N G _ D I R E C T O R Y $ { P R O J E C T _ S O U R C E _ D I R }
)
endif ( DOXYGEN_FOUND )
else ( SQLITECPP_RUN_DOXYGEN )
message ( STATUS "SQLITECPP_RUN_DOXYGEN OFF" )
endif ( SQLITECPP_RUN_DOXYGEN )
option ( SQLITECPP_BUILD_EXAMPLES "Build examples." OFF )
if ( SQLITECPP_BUILD_EXAMPLES )
# add the basic example executable
add_executable ( SQLiteCpp_example1 ${ SQLITECPP_EXAMPLES } )
target_link_libraries ( SQLiteCpp_example1 SQLiteCpp sqlite3 )
# Link target with pthread and dl for linux
if ( UNIX )
target_link_libraries ( SQLiteCpp_example1 pthread )
if ( NOT APPLE )
target_link_libraries ( SQLiteCpp_example1 dl )
endif ( )
elseif ( MSYS OR MINGW )
target_link_libraries ( SQLiteCpp_example1 ssp )
endif ( )
else ( SQLITECPP_BUILD_EXAMPLES )
message ( STATUS "SQLITECPP_BUILD_EXAMPLES OFF" )
endif ( SQLITECPP_BUILD_EXAMPLES )
option ( SQLITECPP_BUILD_TESTS "Build and run tests." OFF )
if ( SQLITECPP_BUILD_TESTS )
# deactivate some warnings for compiling the gtest library
if ( NOT MSVC )
add_compile_options ( -Wno-variadic-macros -Wno-long-long -Wno-switch-enum -Wno-float-equal -Wno-conversion-null -Wno-switch-default -Wno-pedantic )
endif ( NOT MSVC )
# add the subdirectory containing the CMakeLists.txt for the gtest library
# TODO: under Linux, uses libgtest-dev if found
if ( NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt" )
message ( FATAL_ERROR "Missing 'googletest' submodule! Either use 'git submodule init' and 'git submodule update' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF" )
endif ( )
add_subdirectory ( googletest )
include_directories ( "${PROJECT_SOURCE_DIR}/googletest/googletest/include" )
# Add definitions to keep googletest from making the compilation fail
if ( MSVC )
if ( MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919 ) # OR MSVC_TOOLSET_VERSION EQUAL 141)
target_compile_definitions ( gtest PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING )
target_compile_definitions ( gtest_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING )
target_compile_definitions ( gmock PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING )
target_compile_definitions ( gmock_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING )
endif ( MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919 )
endif ( MSVC )
# add the unit test executable
add_executable ( SQLiteCpp_tests ${ SQLITECPP_TESTS } )
target_link_libraries ( SQLiteCpp_tests gtest_main SQLiteCpp sqlite3 )
# Link target with dl for linux
if ( UNIX AND NOT APPLE )
target_link_libraries ( SQLiteCpp_tests dl )
endif ( )
# add a "test" target:
enable_testing ( )
# does the tests pass?
add_test ( UnitTests SQLiteCpp_tests )
if ( SQLITECPP_BUILD_EXAMPLES )
# does the example1 runs successfully?
add_test ( Example1Run SQLiteCpp_example1 )
endif ( SQLITECPP_BUILD_EXAMPLES )
else ( SQLITECPP_BUILD_TESTS )
message ( STATUS "SQLITECPP_BUILD_TESTS OFF" )
endif ( SQLITECPP_BUILD_TESTS )