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()
# 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 " " ";" OCTLIBS "${OCTLIBS}")
set(MAOXDB_DIR "${PROJECT_SOURCE_DIR}/src/lib")
add_library(maoxdb STATIC "${MAOXDB_DIR}/test.cpp" "${MAOXDB_DIR}/maoxdb.cpp")
set_target_properties(maoxdb PROPERTIES PUBLIC_HEADER "${MAOXDB_DIR}/maoxdb.hpp")
target_compile_options(maoxdb PRIVATE "-I${OCTINCLUDEDIR}")
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 "-l${CONAN_LIBS};maoxdb")
string(REGEX REPLACE ";" ":" _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})
add_custom_target(mex ALL
DEPENDS maoxdb)
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})
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 #
###############################################################################
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
option(TEST "Unit test with gtest" OFF)
if(TEST)
enable_testing()
# append all the test cases here (file name without the ".cpp" suffix)
set(test_cases
test_utilities
)
# add special cmake functions for gtest
include(GoogleTest)
# `make testfiles` shall just build the tests, `make test` 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)
# Use this instead, once cmake 3.14 is available everywhere.
# 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 ${CONAN_LIBS_CAOSDB} ${CONAN_LIBS_GTEST} ${CONAN_LIBS_BOOST})
target_link_directories(${test_case_name} PUBLIC ${OCTLIBDIR})
target_link_options(${test_case_name} PUBLIC ${OCTLIBS})
if(_LINTING)
set_target_properties(${test_case_name}
PROPERTIES
CXX_CLANG_TIDY "${_CMAKE_CXX_CLANG_TIDY};${_CMAKE_CXX_CLANG_TIDY_TEST_CHECKS}"
CXX_INCLUDE_WHAT_YOU_USE "${_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
endif()
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)