Newer
Older
#
# 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)
project(OctaveCaosDB
DESCRIPTION "GNU/Octave wrapper for libcaosdb, the C++ client library of the CaosDB project."
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# dependency management with conan
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(KEEP_RPATHS)
# remove path-like elements from CONAN_LIBS, relevant on MacOS
string(REGEX REPLACE ";/[^;]+" "" CONAN_LIBS "${CONAN_LIBS}")
# 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}")
#######################################################
### code formatting with clang-format
#######################################################
option(AUTOFORMATTING "call clang-format at configure time" ON)
if(AUTOFORMATTING)
find_program(clang_format NAMES clang-format-11 clang-format)
file(GLOB_RECURSE format_sources src/*.cpp)
execute_process(COMMAND ${clang_format} -i --verbose ${format_sources}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endif()
#######################################################
#######################################################
# The library will be called maoxdb until we find a better name. The name is not very important
# though, since the library is used only internally.
execute_process(COMMAND mkoctfile -p OCTINCLUDEDIR
OUTPUT_VARIABLE OCTINCLUDEDIR
)
string(REGEX REPLACE "\n" "" OCTINCLUDEDIR "${OCTINCLUDEDIR}")
# OCTLIBDIR
execute_process(COMMAND mkoctfile -p OCTLIBDIR
OUTPUT_VARIABLE OCTLIBDIR
)
string(REGEX REPLACE "\n" "" OCTLIBDIR "${OCTLIBDIR}")
# OCTLIBS
execute_process(COMMAND mkoctfile -p OCTAVE_LIBS
OUTPUT_VARIABLE OCTLIBS
)
string(REGEX REPLACE "\n" "" OCTLIBS "${OCTLIBS}")
string(REGEX REPLACE "-l" "" OCTLIBS "${OCTLIBS}")
string(REGEX REPLACE " " ";" OCTLIBS "${OCTLIBS}")
set(MAOXDB_DIR "${PROJECT_SOURCE_DIR}/src/lib")
add_library(maoxdb STATIC "${MAOXDB_DIR}/maoxdb.cpp")
set_target_properties(maoxdb PROPERTIES PUBLIC_HEADER "${MAOXDB_DIR}/maoxdb.hpp")
target_compile_options(maoxdb PRIVATE "-I${OCTINCLUDEDIR}" "-fPIC")
get_property(_MAOX_LIB_DIR TARGET maoxdb PROPERTY LIBRARY_OUTPUT_DIRECTORY)
# message("_MAOX_LIB_DIR: ${_MAOX_LIB_DIR}")
#######################################################
#######################################################
# Only files in src/private will be compiled. This is to separate the non-mex files in src/lib; if
# this is to change, the GLOB_RECURSE code needs to be changed.
# Absolute paths to the cpp files.
file(GLOB_RECURSE OCTAVE_CAOSDB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/private/*.cpp)
message("OCTAVE_CAOSDB_SRC: ${OCTAVE_CAOSDB_SRC}")
set(PKG_INST_DIR "${PROJECT_SOURCE_DIR}/inst")
file(MAKE_DIRECTORY ${PKG_INST_DIR})
# Options for mex compilation
string(REGEX REPLACE ";" ";-I" _MKOCTFILE_INCLUDES "-I${CONAN_INCLUDE_DIRS};${MAOXDB_DIR}")
string(REGEX REPLACE ";" ";-L" _MKOCTFILE_LIB_DIRS "-L${CONAN_LIB_DIRS};${_MAOX_LIB_DIR}")
string(REGEX REPLACE ";" ";-l" _MKOCTFILE_LIBS "-lmaoxdb;${CONAN_LIBS}")
# Needs this in front: -Wl,-rpath,
string(REGEX REPLACE ";" ",-rpath," _MKOCTFILE_RPATH "${CONAN_LIB_DIRS}")
set(_MKOCTFILE_OPTIONS "-Wl,-rpath,${_MKOCTFILE_RPATH}" "--mex" "-std=gnu++17"
"-L/usr/local/lib" ${_MKOCTFILE_INCLUDES} ${_MKOCTFILE_LIB_DIRS} ${_MKOCTFILE_LIBS})
file(GLOB_RECURSE _CPP_SOURCES RELATIVE "${PROJECT_SOURCE_DIR}/src" src/private/*.cpp)
foreach(sourcefile ${_CPP_SOURCES})
string(REGEX REPLACE ".cpp$" ".mex" _mex_ext_file ${sourcefile})
string(REGEX REPLACE "/" "__" _target_name "${sourcefile}")
set(_mex_ext_file "${PKG_INST_DIR}/${_mex_ext_file}")
set(_mkoct_output "-o;${_mex_ext_file}")
set(_abs_source "${PROJECT_SOURCE_DIR}/src/${sourcefile}")
add_custom_command(OUTPUT ${_mex_ext_file}
COMMAND mkoctfile
ARGS ${_MKOCTFILE_OPTIONS} ${_mkoct_output} ${_abs_source}
MAIN_DEPENDENCY ${_abs_source}
)
add_custom_target(${_target_name} DEPENDS ${_mex_ext_file} maoxdb)
add_dependencies(mex ${_target_name})
#######################################################
### Linting with clang-tidy and include-what-you-use
#######################################################
option(LINTING "clang-tidy and iwyu" OFF)
if(LINTING)
find_program(clang_tidy NAMES clang-tidy-11 clang-tidy)
if(NOT clang_tidy)
message(WARNING "clang-tidy: Not found")
else()
message(STATUS "clang-tidy: ${clang_tidy}")
set(_CMAKE_CXX_CLANG_TIDY
"--warnings-as-errors=*"
"--fix")
set(_CMAKE_CXX_CLANG_TIDY_CHECKS
"--checks=*,-fuchsia-*,-llvmlibc-*,-llvm-else-after-return,-readability-else-after-return,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cert-err58-cpp")
add_custom_command(
COMMAND ${clang_tidy}
ARGS ${_CMAKE_CXX_CLANG_TIDY} ${_CMAKE_CXX_CLANG_TIDY_CHECKS}
${OCTAVE_CAOSDB_SRC} "--" ${_MKOCTFILE_INCLUDES} "-I/usr/include"
"-I${OCTINCLUDEDIR}" "-std=c++17"
DEPENDS ${OCTAVE_CAOSDB_SRC})
endif()
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
"-Xiwyu" "--no_fwd_decls"
"-Xiwyu" "--cxx17ns")
add_custom_command(
ARGS ${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE} "-I${OCTINCLUDEDIR}"
"-std=c++17" "-I/usr/include" ${_MKOCTFILE_INCLUDES}
DEPENDS ${OCTAVE_CAOSDB_SRC})
endif()
else()
message(STATUS "LINTING is OFF")
endif()
###############################################################################
# Tests #
###############################################################################
option(TEST "Unit test with gtest" OFF)
if(TEST)
# cmake tests suffers from not being able to define dependencies, see
# https://stackoverflow.com/questions/733475, so we disable it for now.
# enable_testing()
add_custom_target(test
echo "[EE] \\`make test\\` does not exist, did you mean \\`make test_detailed\\`?"
COMMAND exit 1)
# append all the test cases here (file name without the ".cpp" suffix)
set(test_cases
test_utilities
# add special cmake functions for gtest, (although they are not used yet, see above)
# `make testfiles` just builds the tests, `make test_detailed` builds and runs the tests
add_custom_target(testfiles)
add_custom_target(test_detailed DEPENDS testfiles)
# loop over all test cases and add them to the test runner
list(LENGTH test_cases len_test_cases)
math(EXPR len_test_cases "${len_test_cases} - 1")
foreach (i RANGE "${len_test_cases}")
list(GET test_cases ${i} test_case_name)
# Once cmake 3.14 is available everywhere, use the new `foreach` instead.
# foreach (test_case_name "${test_cases}")
message(STATUS "test_case_name: ${test_case_name}")
add_executable(${test_case_name} EXCLUDE_FROM_ALL test/${test_case_name}.cpp)
add_custom_target("test_${test_case_name}" "${test_case_name}" DEPENDS "${test_case_name}")
add_dependencies(test_detailed "test_${test_case_name}")
# set(libcaosdb_TEST_SRC
# "${CMAKE_CURRENT_SOURCE_DIR}/${test_case_name}.cpp ${libcaosdb_TEST_SRC}")
target_include_directories(${test_case_name} PUBLIC
${OCTINCLUDEDIR}
${MAOXDB_DIR})
target_link_libraries(${test_case_name} PUBLIC
maoxdb ${OCTLIBS} ${CONAN_LIBS_CAOSDB} ${CONAN_LIBS_GTEST} ${CONAN_LIBS_BOOST})
target_link_directories(${test_case_name} PUBLIC ${OCTLIBDIR})
message(STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}")
gtest_discover_tests(${test_case_name}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
TEST_LIST test_list
)
message(STATUS "tests for ${test_case_name}: ${test_list}")
add_dependencies(testfiles ${test_case_name})
endforeach ()
else()
message(STATUS "TEST is OFF")
endif(TEST)