-
Joscha Schmiedt authored
- _CRT_SECURE_NO_WARNINGS suppresses warnings for "unsafe" fopen, strcpy etc. - int -> size_t
Joscha Schmiedt authored- _CRT_SECURE_NO_WARNINGS suppresses warnings for "unsafe" fopen, strcpy etc. - int -> size_t
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CMakeLists.txt 16.82 KiB
#
# This file is a part of the LinkAhead Project.
#
# Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
# Copyright (C) 2024 Joscha Schmiedt <joscha@schmiedt.dev>
# Copyright (C) 2021-2024 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(liblinkahead_VERSION 0.3.0)
set(liblinkahead_COMPATIBLE_SERVER_VERSION_MAJOR 0)
set(liblinkahead_COMPATIBLE_SERVER_VERSION_MINOR 9)
set(liblinkahead_COMPATIBLE_SERVER_VERSION_PATCH 0)
set(liblinkahead_COMPATIBLE_SERVER_VERSION_PRE_RELEASE "")
project(liblinkahead
VERSION ${liblinkahead_VERSION}
DESCRIPTION "C and C++ client libraries for LinkAhead"
LANGUAGES CXX C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
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)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) # suppress warnings for fopen, strcpy, etc.
endif()
IF (BUILD_ACM)
message(STATUS "BUILD_ACM")
add_compile_definitions("BUILD_ACM")
ENDIF()
message(STATUS "Build directory ${CMAKE_BINARY_DIR}")
###########################################
### 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)
####################################################################
find_package(protobuf CONFIG REQUIRED)
# 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)
set(_PROTOBUF_PROTOC ${Protobuf_PROTOC_EXECUTABLE})
# compiler binaries
IF (WIN32)
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${CMAKE_BINARY_DIR}/build_tools/grpc_cpp_plugin.exe")
ELSE()
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${CMAKE_BINARY_DIR}/build_tools/grpc_cpp_plugin")
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})
# add generated files to include path
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
###############################################################################
### Set up main targets
### * linkahead - The main library including the protobuf and grpc generated files.
### * cxxlinkaheadcli - A C++ test client.
### * clinkahead - A C-Wrapper of the C++ linkahead library.
### * clinkaheadcli - A plain C test client.
###############################################################################
find_package(gRPC CONFIG REQUIRED)
# boost
find_package(Boost REQUIRED COMPONENTS json filesystem log thread system log_setup)
# find_package(Boost REQUIRED COMPONENTS filesystem )
# find_package(Boost REQUIRED COMPONENTS log )
# find_package(Boost REQUIRED COMPONENTS thread )
# find_package(Boost REQUIRED COMPONENTS system )
# Boost settings
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON) # link Boost Static libraries
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}")
message(DEBUG "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(DEBUG "GTest_INCLUDE_DIRS: ${GTest_INCLUDE_DIRS}")
message(DEBUG "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
message(DEBUG "liblinkahead_SOURCE_DIR: ${liblinkahead_SOURCE_DIR}")
message(DEBUG "liblinkahead_BINARY_DIR: ${liblinkahead_BINARY_DIR}")
# libcaosdb_grpc
# --------------
add_library(caosdb_grpc STATIC ${GRPC_GENERATED})
target_link_libraries(caosdb_grpc
gRPC::grpc gRPC::grpc++ protobuf::libprotobuf
)
# liblinkahead
# ---------
add_library(linkahead SHARED
${liblinkahead_INCL} ${liblinkahead_SRC})
target_link_libraries(linkahead PUBLIC
caosdb_grpc gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
)
set(liblinkahead linkahead)
target_include_directories(linkahead PUBLIC
$<BUILD_INTERFACE:${liblinkahead_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${liblinkahead_BINARY_DIR}/include>
$<BUILD_INTERFACE:${liblinkahead_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>
)
# libclinkahead
# ----------
add_library(clinkahead SHARED src/clinkahead.cpp)
target_link_libraries(clinkahead PUBLIC
linkahead caosdb_grpc gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
)
target_include_directories(clinkahead PUBLIC
$<BUILD_INTERFACE:${liblinkahead_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${liblinkahead_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# clinkaheadcli
# ----------
add_executable(clinkaheadcli EXCLUDE_FROM_ALL src/clinkaheadcli.c)
target_include_directories(clinkaheadcli PUBLIC
$<BUILD_INTERFACE:${liblinkahead_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${liblinkahead_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(clinkaheadcli PRIVATE
caosdb_grpc clinkahead
gRPC::grpc protobuf::libprotobuf ${Boost_LIBRARIES}
)
# cxxlinkaheadcli
# ------------
add_executable(cxxlinkaheadcli EXCLUDE_FROM_ALL src/cxxlinkaheadcli.cpp)
target_include_directories(cxxlinkaheadcli PUBLIC
$<BUILD_INTERFACE:${liblinkahead_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${liblinkahead_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(cxxlinkaheadcli PRIVATE
linkahead caosdb_grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
)
#######################################################
### 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")
message(STATUS "PEDANTIC_CMAKE_CXX_FLAGS: [${PEDANTIC_CMAKE_CXX_FLAGS}]")
set(TARGET_LINKAHEAD_COMPILE_FLAGS "${TARGET_LINKAHEAD_COMPILE_FLAGS} ${PEDANTIC_CMAKE_CXX_FLAGS}")
set(TARGET_CLINKAHEAD_COMPILE_FLAGS "${TARGET_CLINKAHEAD_COMPILE_FLAGS} ${PEDANTIC_CMAKE_C_FLAGS}")
set(TARGET_CXXLINKAHEADCLI_COMPILE_FLAGS "${TARGET_CXXLINKAHEADCLI_COMPILE_FLAGS} ${PEDANTIC_CMAKE_CXX_FLAGS}")
set(TARGET_CLINKAHEADCLI_COMPILE_FLAGS "${TARGET_CLINKAHEADCLI_COMPILE_FLAGS} ${PEDANTIC_CMAKE_C_FLAGS}")
set_target_properties(linkahead PROPERTIES
COMPILE_FLAGS "${TARGET_LINKAHEAD_COMPILE_FLAGS}")
set_target_properties(clinkahead PROPERTIES
COMPILE_FLAGS "${TARGET_CLINKAHEAD_COMPILE_FLAGS}")
set_target_properties(cxxlinkaheadcli PROPERTIES
COMPILE_FLAGS "${TARGET_CXXLINKAHEADCLI_COMPILE_FLAGS}")
set_target_properties(clinkaheadcli PROPERTIES
COMPILE_FLAGS "${TARGET_CLINKAHEADCLI_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(linkahead PROPERTIES
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
set_target_properties(cxxlinkaheadcli PROPERTIES
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
set_target_properties(clinkaheadcli PROPERTIES
C_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}"
)
endif()
find_program(clang_tidy NAMES clang-tidy clang-tidy-16)
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(linkahead PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}"
)
set_target_properties(cxxlinkaheadcli PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_CHECKS}"
)
set_target_properties(clinkahead PROPERTIES
C_CLANG_TIDY "${_CMAKE_C_CLANG_TIDY};${_CMAKE_C_CLANG_TIDY_CHECKS}"
)
set_target_properties(clinkaheadcli 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(liblinkahead_INCLUDE_DEST "include/linkahead")
set(liblinkahead_LIB_DEST "lib")
if (WIN32)
set(CMAKE_INSTALL_PREFIX "$ENV{LOCALAPPDATA}/linkahead")
else()
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local/")
endif()
install(
# targets to install
TARGETS linkahead clinkahead caosdb_grpc
# name of the CMake "export group" containing the targets we want to install
EXPORT linkaheadTargets
# Dynamic, static library and include destination locations after running
# "make install"
LIBRARY DESTINATION ${liblinkahead_LIB_DEST}
ARCHIVE DESTINATION ${liblinkahead_LIB_DEST}
INCLUDES DESTINATION ${liblinkahead_INCLUDE_DEST}
)
set(liblinkahead_CMAKE_DEST "${liblinkahead_LIB_DEST}/cmake/linkahead")
install(
# The export we want to save (matches name defined above containing the
# install targets)
EXPORT linkaheadTargets
# CMake file in which to store the export's information
FILE linkaheadTargets.cmake
# Namespace prepends all targets in the export (when we import later, we
# will use linkahead::linkahead)
NAMESPACE linkahead::
# where to place the resulting file (here, we're putting it with the library)
DESTINATION ${liblinkahead_CMAKE_DEST}
)
install(FILES ${liblinkahead_INCL} ${PROJECT_SOURCE_DIR}/include/clinkahead.h DESTINATION ${liblinkahead_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
${liblinkahead_INCLUDE_DEST}/${next_proto_module})
endforeach()
install(FILES ${PROJECT_SOURCE_DIR}/linkaheadConfig.cmake
DESTINATION ${liblinkahead_CMAKE_DEST})
#set_property(TARGET caosdb PROPERTY VERSION ${liblinkahead_VERSION})
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_SOURCE_DIR}/linkaheadConfigVersion.cmake"
VERSION ${liblinkahead_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(FILES ${PROJECT_SOURCE_DIR}/linkaheadConfigVersion.cmake
DESTINATION ${liblinkahead_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-16 clang-format)
file(GLOB format_test_sources test/*.cpp test/*.h test/*.h.in)
execute_process(COMMAND ${clang_format} -i --verbose ${liblinkahead_INCL}
${liblinkahead_SRC} ${liblinkahead_TEST_SRC}
${PROJECT_SOURCE_DIR}/src/cxxlinkaheadcli.cpp
${PROJECT_SOURCE_DIR}/src/clinkaheadcli.c
${PROJECT_SOURCE_DIR}/src/clinkahead.cpp
${PROJECT_SOURCE_DIR}/include/clinkahead.h
${format_test_sources}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endif()