-
Joscha Schmiedt authored
This was necessary for gcc prior to 9.1 and is no longer necessary.
Joscha Schmiedt authoredThis was necessary for gcc prior to 9.1 and is no longer necessary.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CMakeLists.txt 16.89 KiB
#
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
# Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
cmake_minimum_required(VERSION 3.13)
set(libcaosdb_VERSION 0.3.0)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR 0)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR 9)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH 0)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_PRE_RELEASE "")
project(libcaosdb
VERSION ${libcaosdb_VERSION}
DESCRIPTION "C and C++ client libraries for CaosDB"
LANGUAGES CXX C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
IF (WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
ENDIF()
IF (BUILD_ACM)
message(STATUS "BUILD_ACM")
add_compile_definitions("BUILD_ACM")
ENDIF()
###########################################
### DEPENDENCY MANAGEMENT with CONAN
###########################################
message(STATUS "Build directory ${CMAKE_BINARY_DIR}")
# TODO: Is this still necessary?
# # fix grpc - remove unsecure (no-op ssl implementations)
# string(REGEX REPLACE "grpc\\+?\\+?_unsecure" "" CONAN_LIBS_GRPC
# "${CONAN_LIBS_GRPC}")
# string(REGEX REPLACE "grpc\\+?\\+?_unsecure" "" CONAN_PKG_LIBS_GRPC
# "${CONAN_PKG_LIBS_GRPC}")
# string(REGEX REPLACE "grpc\\+?\\+?_unsecure" "" CONAN_LIBS
# "${CONAN_LIBS}")
# string(REGEX REPLACE "grpc\\+?\\+?_unsecure" "" CONAN_PKG_LIBS
# "${CONAN_PKG_LIBS}")
# message(STATUS "CONAN_LIBS: ${CONAN_LIBS}")
###########################################
### GENERAL SETUP of SOURCES
###########################################
set(PROJECT_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
add_subdirectory(src)
add_subdirectory(include)
add_subdirectory(doc)
####################################################################
### CODE GENERATION (WITH GRPC)
####################################################################
# TODO: Replace this with the protobuf_generate_cpp function
# Protobuf/Grpc source files
set(PROTO_FILES
${PROJECT_SOURCE_DIR}/proto/proto/caosdb/info/v1/main.proto
${PROJECT_SOURCE_DIR}/proto/proto/caosdb/entity/v1/main.proto
)
IF (BUILD_ACM)
list(APPEND PROTO_FILES
${PROJECT_SOURCE_DIR}/proto/proto/caosdb/acm/v1alpha1/main.proto
)
ENDIF()
set(PROTO_PATH ${PROJECT_SOURCE_DIR}/proto/proto)
# compiler binaries
IF (WIN32)
set(_PROTOBUF_PROTOC "${CMAKE_BINARY_DIR}/build_tools/protoc.exe")
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${CMAKE_BINARY_DIR}/build_tools/grpc_cpp_plugin.exe")
set(STDFSLIB "")
ELSE()
set(_PROTOBUF_PROTOC "${CMAKE_BINARY_DIR}/build_tools/protoc")
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${CMAKE_BINARY_DIR}/build_tools/grpc_cpp_plugin")
set(STDFSLIB stdc++fs)
ENDIF()
# Generated sources
list(LENGTH PROTO_FILES len_proto_files)
math(EXPR len_proto_files "${len_proto_files} - 1")
foreach(i RANGE "${len_proto_files}")
list(GET PROTO_FILES ${i} next_proto_file)
# strip away the prefix path and the ".proto" suffix
string(REPLACE
"${PROJECT_SOURCE_DIR}/proto/proto/caosdb/"
""
next_proto_module
"${next_proto_file}")
string(REPLACE
".proto"
""
next_proto_module
"${next_proto_module}")
set(next_proto_src
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}.pb.cc")
set(next_proto_hdr
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}.pb.h")
set(next_grpc_src
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}.grpc.pb.cc")
set(next_grpc_hdr
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}.grpc.pb.h")
list(APPEND GRPC_GENERATED_HEADERS "${next_proto_hdr}" "${next_grpc_hdr}")
list(APPEND GRPC_GENERATED_SOURCES "${next_proto_src}" "${next_grpc_src}")
endforeach()
set(GRPC_GENERATED
${GRPC_GENERATED_SOURCES}
${GRPC_GENERATED_HEADERS})
add_custom_command(
OUTPUT ${GRPC_GENERATED}
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}/include"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}/include"
-I "${PROTO_PATH}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
${PROTO_FILES}
DEPENDS ${PROTO_FILES})
# show generated files
message(DEBUG "GRPC_GENERATED: ${GRPC_GENERATED}")
###############################################################################
### Set up main targets
### * [caosdb_grpc] - only in Debug builds. Otherwise this library is compiled
### into caosdb libraray
### * caosdb (links to caosdb_grpc) - The main library.
### * cxxcaosdbcli - A C++ test client.
### * ccaosdb - A C-Wrapper of the C++ caosdb library.
### * ccaosdbcli - A plain C test client.
###############################################################################
find_package(gRPC CONFIG REQUIRED)
find_package(Protobuf CONFIG REQUIRED)
find_package(Boost REQUIRED)
find_package(GTest REQUIRED)
# print include directories for debugging
message(DEBUG "CMAKE_INCLUDE_PATH: ${CMAKE_INCLUDE_PATH}")
message(DEBUG "PROTOBUF_INCLUDE_DIRS: ${PROTOBUF_INCLUDE_DIRS}")
message(DEBUG "gRPC_INCLUDE_DIRS: ${gRPC_INCLUDE_DIRS}")
# libcaosdb
# ---------
# In Debug, build separate libraries for grpc-generated code and caosdb
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
add_library(caosdb_grpc SHARED ${GRPC_GENERATED})
target_link_libraries(caosdb_grpc
grpc::grpc protobuf::protobuf boost::boost
)
target_include_directories(caosdb_grpc PUBLIC
$<BUILD_INTERFACE:${PROJECT_INCLUDE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
add_library(caosdb SHARED ${libcaosdb_INCL} ${libcaosdb_SRC})
target_link_libraries(caosdb
caosdb_grpc grpc::grpc protobuf::protobuf boost::boost
)
set(LIBCAOSDB caosdb caosdb_grpc)
else()
add_library(caosdb
SHARED ${libcaosdb_INCL} ${libcaosdb_SRC} ${GRPC_GENERATED})
target_link_libraries(caosdb
grpc::grpc protobuf::protobuf boost::boost
)
set(LIBCAOSDB caosdb)
endif()
target_include_directories(caosdb PUBLIC
$<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
$<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>
)
# libccaosdb
# ----------
add_library(ccaosdb SHARED src/ccaosdb.cpp ${GRPC_GENERATED})
target_link_libraries(ccaosdb
grpc::grpc protobuf::protobuf boost::boost
${LIBCAOSDB}
)
target_include_directories(ccaosdb PUBLIC
$<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# ccaosdbcli
# ----------
add_executable(ccaosdbcli EXCLUDE_FROM_ALL src/ccaosdbcli.c)
target_include_directories(ccaosdbcli PUBLIC
$<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_include_directories(ccaosdbcli SYSTEM PUBLIC
${CONAN_INCLUDE_DIRS}
)
target_link_libraries(ccaosdbcli
grpc::grpc protobuf::protobuf boost::boost
${LIBCAOSDB}
ccaosdb
)
# cxxcaosdbcli
# ------------
add_executable(cxxcaosdbcli EXCLUDE_FROM_ALL src/cxxcaosdbcli.cpp)
target_include_directories(cxxcaosdbcli PUBLIC
$<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_include_directories(cxxcaosdbcli SYSTEM PUBLIC
${CONAN_INCLUDE_DIRS}
)
target_link_libraries(cxxcaosdbcli
${LIBCAOSDB}
grpc::grpc protobuf::protobuf boost::boost
)
#######################################################
### LINTING with CLANG-TIDY and INCLUDE-WHAT-YOU-USE
#######################################################
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
function(add_compiler_flag flag)
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" cxx_present)
if(cxx_present EQUAL -1)
check_cxx_compiler_flag("${flag}" flag_supported)
if(flag_supported)
set(PEDANTIC_CMAKE_CXX_FLAGS "${PEDANTIC_CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
endif()
unset(flag_supported CACHE)
endif()
unset(cxx_present CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${flag}" c_present)
if(c_present EQUAL -1)
check_cxx_compiler_flag("${flag}" flag_supported)
if(flag_supported)
set(PEDANTIC_CMAKE_C_FLAGS "${PEDANTIC_CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE)
endif()
unset(flag_supported CACHE)
endif()
unset(c_present CACHE)
endfunction()
option(LINTING "Enable linting with clang-tidy and iwyu when in non-Debug build-type" OFF)
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug" OR LINTING)
set(_LINTING ON)
endif()
option(SKIP_LINTING "Skip linting even when in Debug build-type" OFF)
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug" AND SKIP_LINTING)
message(WARNING "Skipping linting due to SKIP_LINTING option")
set(_LINTING OFF)
endif()
if(_LINTING)
### set paranoid compiler flags
add_compiler_flag("-Wall")
add_compiler_flag("-Wextra")
add_compiler_flag("-pedantic")
# add_compiler_flag("-Werror") # removed until issue #71 is resolved
message(STATUS "PEDANTIC_CMAKE_CXX_FLAGS: [${PEDANTIC_CMAKE_CXX_FLAGS}]")
set(TARGET_CAOSDB_COMPILE_FLAGS "${TARGET_CAOSDB_COMPILE_FLAGS} ${PEDANTIC_CMAKE_CXX_FLAGS}")
set(TARGET_CCAOSDB_COMPILE_FLAGS "${TARGET_CCAOSDB_COMPILE_FLAGS} ${PEDANTIC_CMAKE_C_FLAGS}")
set(TARGET_CXXCAOSDBCLI_COMPILE_FLAGS "${TARGET_CXXCAOSDBCLI_COMPILE_FLAGS} ${PEDANTIC_CMAKE_CXX_FLAGS}")
set(TARGET_CCAOSDBCLI_COMPILE_FLAGS "${TARGET_CCAOSDBCLI_COMPILE_FLAGS} ${PEDANTIC_CMAKE_C_FLAGS}")
set_target_properties(caosdb PROPERTIES
COMPILE_FLAGS "${TARGET_CAOSDB_COMPILE_FLAGS}")
set_target_properties(ccaosdb PROPERTIES
COMPILE_FLAGS "${TARGET_CCAOSDB_COMPILE_FLAGS}")
set_target_properties(cxxcaosdbcli PROPERTIES
COMPILE_FLAGS "${TARGET_CXXCAOSDBCLI_COMPILE_FLAGS}")
set_target_properties(ccaosdbcli PROPERTIES
COMPILE_FLAGS "${TARGET_CCAOSDBCLI_COMPILE_FLAGS}")
find_program(iwyu
NAMES include-what-you-use iwyu
PATHS ${CMAKE_SOURCE_DIR}/tools/include-what-you-use/${iwyu_os}/bin)
if(NOT iwyu)
message(WARNING "include-what-you-use: Not found")
else()
message(STATUS "include-what-you-use: ${iwyu}")
set(_CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${iwyu}
"-Xiwyu" "--cxx17ns" "-Xiwyu" "--no_fwd_decls")
set_target_properties(caosdb PROPERTIES
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
set_target_properties(cxxcaosdbcli PROPERTIES
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
set_target_properties(ccaosdbcli PROPERTIES
C_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
endif()
find_program(clang_tidy NAMES clang-tidy clang-tidy-11)
if(NOT clang_tidy)
message(WARNING "clang-tidy: Not found")
else()
message(STATUS "clang-tidy: ${clang_tidy}")
set(_CMAKE_CXX_CLANG_TIDY_CHECKS
"--checks=*,-fuchsia-*,-llvmlibc-*,-readability-convert-member-functions-to-static,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-llvm-else-after-return,-readability-else-after-return,-modernize-use-trailing-return-type,-bugprone-branch-clone,-altera-*,-misc-include-cleaner,-readability-identifier-*,-llvm-include-order,-misc-const-correctness")
set(_CMAKE_C_CLANG_TIDY_CHECKS "${_CMAKE_CXX_CLANG_TIDY_CHECKS}")
set(_CMAKE_CXX_CLANG_TIDY "${clang_tidy}"
"--header-filter=caosdb/.*[^\(\.pb\.h\)]$")
# "--warnings-as-errors=*")
set(_CMAKE_C_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY}")
option(AUTO_FIX_LINTING "Append --fix option to clang-tidy" OFF)
if(AUTO_FIX_LINTING)
set(_CMAKE_CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};--fix")
endif()
message(STATUS "Using clang-tidy with
'${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}'")
set_target_properties(caosdb PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}"
)
set_target_properties(cxxcaosdbcli PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}"
)
set_target_properties(ccaosdb PROPERTIES
C_CLANG_TIDY "${_CMAKE_C_CLANG_TIDY};${_CMAKE_C_CLANG_TIDY_CHECKS}"
)
set_target_properties(ccaosdbcli PROPERTIES
C_CLANG_TIDY "${_CMAKE_C_CLANG_TIDY};${_CMAKE_C_CLANG_TIDY_CHECKS}"
)
endif()
endif()
#######################################################
### UNIT TEST
#######################################################
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
enable_testing()
add_subdirectory(test)
endif()
# ###############################################
# ############ INSTALLATION #####################
# ###############################################
set(libcaosdb_INCLUDE_DEST "include/caosdb")
set(libcaosdb_LIB_DEST "lib")
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local/")
install(
# targets to install
TARGETS ${LIBCAOSDB} ccaosdb
# name of the CMake "export group" containing the targets we want to install
EXPORT caosdbTargets
# Dynamic, static library and include destination locations after running
# "make install"
LIBRARY DESTINATION ${libcaosdb_LIB_DEST}
ARCHIVE DESTINATION ${libcaosdb_LIB_DEST}
INCLUDES DESTINATION ${libcaosdb_INCLUDE_DEST}
)
set(libcaosdb_CMAKE_DEST "${libcaosdb_LIB_DEST}/cmake/caosdb")
install(
# The export we want to save (matches name defined above containing the
# install targets)
EXPORT caosdbTargets
# CMake file in which to store the export's information
FILE caosdbTargets.cmake
# Namespace prepends all targets in the export (when we import later, we
# will use caosdb::caosdb)
NAMESPACE caosdb::
# where to place the resulting file (here, we're putting it with the library)
DESTINATION ${libcaosdb_CMAKE_DEST}
)
install(FILES ${libcaosdb_INCL} ${PROJECT_SOURCE_DIR}/include/ccaosdb.h DESTINATION ${libcaosdb_INCLUDE_DEST})
foreach(i RANGE "${len_proto_files}")
list(GET PROTO_FILES ${i} next_proto_file)
# strip away the prefix path and the ".proto" suffix
string(REPLACE
"${PROJECT_SOURCE_DIR}/proto/proto/caosdb/"
""
next_proto_module
"${next_proto_file}")
string(REPLACE
"/main.proto"
""
next_proto_module
"${next_proto_module}")
set(next_proto_hdr
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}/main.pb.h")
set(next_grpc_hdr
"${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${next_proto_module}/main.grpc.pb.h")
install(FILES ${next_proto_hdr} ${next_grpc_hdr} DESTINATION
${libcaosdb_INCLUDE_DEST}/${next_proto_module})
endforeach()
install(FILES ${PROJECT_SOURCE_DIR}/caosdbConfig.cmake
DESTINATION ${libcaosdb_CMAKE_DEST})
#set_property(TARGET caosdb PROPERTY VERSION ${libcaosdb_VERSION})
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_SOURCE_DIR}/caosdbConfigVersion.cmake"
VERSION ${libcaosdb_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(FILES ${PROJECT_SOURCE_DIR}/caosdbConfigVersion.cmake
DESTINATION ${libcaosdb_CMAKE_DEST})
#######################################################
### code formatting with clang-format
#######################################################
option(AUTOFORMATTING "call clang-format at configure time" ON)
if(AUTOFORMATTING AND NOT SKIP_LINTING)
find_program(clang_format NAMES clang-format-11 clang-format)
file(GLOB format_test_sources test/*.cpp test/*.h test/*.h.in)
execute_process(COMMAND ${clang_format} -i --verbose ${libcaosdb_INCL}
${libcaosdb_SRC} ${libcaosdb_TEST_SRC}
${PROJECT_SOURCE_DIR}/src/cxxcaosdbcli.cpp
${PROJECT_SOURCE_DIR}/src/ccaosdbcli.c
${PROJECT_SOURCE_DIR}/src/ccaosdb.cpp
${PROJECT_SOURCE_DIR}/include/ccaosdb.h
${format_test_sources}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endif()