diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7fc12e8b051d76854027631531e37eaf69db0fee..a749b92ce5954192af0a599fca3c51d6ec894f4a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,13 +12,13 @@ build_windows: script: - mkdir -Force build - cd build - - cmake -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_UNIT_TESTS=TRUE .. + - cmake -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_UNIT_TESTS=ON -DUSE_3RD_PARTY=ON .. - cmake --build . -- -j6 artifacts: paths: - "./build/petrack.exe" - "./build/tests/unit_test/petrack_tests.exe" - expire_in: 2 hrs + expire_in: 2 hrs # Ggf. muss man nicht in den Ordner der Testskripte verzweigen, da PyTest auch rekusrsiv in Unterorndern nach tests sucht regression test windows: diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a50000405a6b0349631c3bf64a176bc1b342413..74940e17d1afef8a5f7dd0c687352cbff0e6711f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,145 @@ -cmake_minimum_required(VERSION 3.16) - +# Documentation: Some useful options: cmake [options] [path to CMakeLists.txt] +# helpful cmake options: +# -DCMAKE_CXX_COMPILER=clang++ (setting the used C++ compiler) +# -DCMAKE_BUILD_TYPE=Debug (default Release) +# -DCMAKE_VERBOSE_MAKEFILE=ON (default OFF) +# -DCMAKE_PREFIX_PATH=[paths where additionally to search for libraries etc] +# +# petrack options: +# -DUSE_3RD_PARTY=ON (default ON on Windows, OFF else) use the libraries provided in 3rdparty +# -DBUILD_UNIT_TESTS=ON (default ON) for unit tests +# +# currently not supported: +# -DSTEREO=ON (default OFF) +# -DAVI=ON (default OFF) +# -DDISABLE_STEREO=ON (default OFF) +# +################################################################################ +# Project setup +################################################################################ +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) project(petrack LANGUAGES CXX) -include(CMakeDependentOption) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules") + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +include(helper_functions) +# Set default build type to release +set(default_build_type "Release") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build." FORCE) +endif() + +check_prefix_path() + +include(CMakeDependentOption) set(CMAKE_INCLUDE_CURRENT_DIR ON) +################################################################################ +# Optional features +################################################################################ +option(STEREO "Use Point Grey's Triclops SDK? (currently not supported)" OFF) +print_var(STEREO) + +option(AVI "Use Avi File from Point Grey (currently not supported)" OFF) +print_var(AVI) + +option(LIBELAS "Use Libelas" ON) +print_var(LIBELAS) + +option(DISABLE_STEREO "Disable Stereo features (currently must be taken)" ON) +print_var(DISABLE_STEREO) + +option(BUILD_UNIT_TESTS "Build catch2 unit tests" OFF) +print_var(BUILD_UNIT_TESTS) + +CMAKE_DEPENDENT_OPTION(USE_3RD_PARTY "Use the default libraries provided in 3rd party" ON WIN32 OFF) +print_var(USE_3RD_PARTY) + +################################################################################ +# Compilation flags +################################################################################ +# Note: Setting global compile flags via CMAKE_CXX_FLAGS has the drawback that +# generator expressions cannot be used. This leads to all kind of +# conditional adding of flags. It is generally preferable to use generator +# expresssions. +# +# WARNING: Do not break the lines, each option has to be on its own line or +# CMake will enclose multiple flags in '' which the compiler then +# treats as a single flag and does not understand. +list(APPEND COMMON_COMPILE_OPTIONS + $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wall> + $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wextra> + $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-fdiagnostics-color=always> + $<$<CXX_COMPILER_ID:MSVC>:/W2> + $<$<CXX_COMPILER_ID:MSVC>:/EHsc> +) + +################################################################################ +# Check some compile options if allowed +################################################################################ +# Using the default 3rd party libraries only allowed on Windows with MinGW +if (USE_3RD_PARTY AND NOT (WIN32 AND MINGW)) + message(FATAL_ERROR "The provided 3rd party libraries can only be used on + Windows with the MinGW compiler. Please install the required libraries + yourself." ) +endif() + +# Check for currently unavailable options +if (AVI) + message(FATAL_ERROR "Currently the avi File from Point Grey needs to be disabled.") +endif() + +# Stero only allowed +if (NOT DISABLE_STEREO OR STEREO) + message(FATAL_ERROR "Currently the stereo feature needs to be disabled.") +endif() + +################################################################################ +# Dependencies +################################################################################ +# if win32 and mingw use in 3rd party +if (USE_3RD_PARTY) + # Setting path to OpenCV + set(OpenCV_DIR "${CMAKE_SOURCE_DIR}/3rdparty/windows/opencv-4.2.0_64bit") + + # Setting path to QWT + set(QWT_ROOT_DIR "${CMAKE_SOURCE_DIR}/3rdparty/windows/Qwt-6.1.4_64bit") + set(QWT_INCLUDE_DIR "${QWT_ROOT_DIR}/include") + set(QWT_LIBRARY "${QWT_ROOT_DIR}/lib/libqwt.a") +endif () + +# Qt +find_package( + Qt5 5.14 + COMPONENTS Widgets OpenGL Xml Core PrintSupport + REQUIRED) + +# OpenCV +find_package(OpenCV 4.0.0 REQUIRED ) +message("Building with OpenCV${OpenCV_VERSION_MAJOR}(${OpenCV_VERSION})") + +# QWT +if(APPLE) + set(CMAKE_FIND_FRAMEWORK ONLY) + find_library(QWT + NAMES qwt + HINTS /usr/local/opt/qwt/lib/ + REQUIRED) + if(QWT) + include_directories(${QWT}/Headers) + link_libraries(${QWT}) + endif() +else() + find_package(Qwt REQUIRED) +endif() + #********************************************************** # Qt and Misc Stuff * #********************************************************** @@ -13,76 +148,35 @@ list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/ui" "./src") set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package( - Qt5 - COMPONENTS Widgets OpenGL Xml Core PrintSupport - REQUIRED) - +#********************************************************** +# Create library and exectuable * +#********************************************************** add_library(petrack_core STATIC) add_executable(petrack src/main.cpp) target_link_libraries(petrack PRIVATE petrack_core) -target_link_libraries(petrack_core PUBLIC Qt5::Widgets Qt5::OpenGL Qt5::Xml Qt5::Core Qt5::PrintSupport) - -source_group(TREE .) +# TODO we should remove this compile option and be more strict +target_compile_options(petrack_core PRIVATE "-fpermissive" ${COMMON_COMPILE_OPTIONS}) +target_compile_definitions(petrack_core PUBLIC STEREO_DISABLED) #********************************************************** -# Cache Variables * +# Linking Qt * #********************************************************** +target_link_libraries(petrack_core PUBLIC + Qt5::Widgets + Qt5::OpenGL + Qt5::Xml + Qt5::Core + Qt5::PrintSupport +) -set(STEREO - FALSE - CACHE BOOL "Use Point Grey's Triclops SDK? (currently not supported)") - -set(AVI - FALSE - CACHE BOOL "Use Avi File from Point Grey (currently not supported)") - -set(QWT - TRUE - CACHE BOOL "Use Qwt (currently critical)") - -set(LIBELAS - TRUE - CACHE BOOL "Use Libelas") - -set(DISABLE_STEREO - TRUE - CACHE BOOL "Disable Stereo features (currently must be taken)") - -set(CVPATH - "../petrack/3rdparty/windows/opencv-4.2.0_64bit" - CACHE - PATH - "Path to OpenCV installation (should usually not be needed to be changed)") - -set(QWTPATH - "../petrack/3rdparty/windows/Qwt-6.1.4_64bit" - CACHE PATH "Path to Qwt installation. Ususally shouln't be altered.") - -set(BUILD_UNIT_TESTS - OFF - CACHE BOOL "Whether to build or not to build Catch2 Unit Tests") - -cmake_dependent_option(BUILD_UNIT_TESTS_WITH_LLD - "Use -fuse-ld=lld flag for linking unit-tests (need lld to be installed)" - OFF - "BUILD_UNIT_TESTS" OFF) +target_include_directories(petrack_core PRIVATE "${CMAKE_SOURCE_DIR}/ui") #***************************************************************** -# APPLIES ALWAYS * +# Linking OpenCV * #***************************************************************** -target_compile_options(petrack_core PRIVATE "-fpermissive") -target_compile_definitions(petrack_core PUBLIC STEREO_DISABLED) - -set(OpenCV_DIR "${CVPATH}") -find_package(OpenCV REQUIRED) -message("Building with OpenCV${OpenCV_VERSION_MAJOR}(${OpenCV_VERSION})") - add_library(opencv INTERFACE IMPORTED) + # Debug Version of slows our debug down to a unusable degree set_target_properties(${OpenCV_LIBS} PROPERTIES MAP_IMPORTED_CONFIG_DEBUG RELEASE @@ -90,30 +184,26 @@ set_target_properties(${OpenCV_LIBS} PROPERTIES target_link_libraries(petrack_core PUBLIC ${OpenCV_LIBS}) -target_include_directories(petrack_core PRIVATE "../ui") -#************************************************************* -# Handling of Options * -#************************************************************* +#***************************************************************** +# Linking QWT * +#***************************************************************** +if(APPLE) + target_link_directories(petrack_core PUBLIC ${QWT}) +else() + target_compile_definitions( + petrack_core PRIVATE + $<$<AND:$<PLATFORM_ID:Windows>,$<BOOL:USE_3RD_PARTY>>:QWT QWT_DLL>) + target_include_directories(petrack_core PUBLIC ${QWT_INCLUDE_DIR}) + target_link_libraries(petrack_core PUBLIC ${QWT_LIBRARY}) +endif() -if(BUILD_UNIT_TESTS) - enable_testing() - find_package(Qt5Test REQUIRED) - find_package(trompeloeil REQUIRED HINTS "./3rdparty/trompeloeil/lib/cmake/trompeloeil") - add_subdirectory(./tests/unit_test) - target_link_libraries(petrack_tests PRIVATE petrack_core) - add_subdirectory(./3rdparty/Catch2) - target_link_libraries(petrack_tests PRIVATE Catch2::Catch2 Qt5::Test trompeloeil) - target_include_directories(petrack_tests PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/petrack_core_autogen/include") - - if(BUILD_UNIT_TESTS_WITH_LLD) - target_compile_options(petrack_tests PRIVATE "-fuse-ld=lld") - target_link_options(petrack_tests PRIVATE "-fuse-ld=lld") - endif(BUILD_UNIT_TESTS_WITH_LLD) -endif(BUILD_UNIT_TESTS) +target_sources(petrack_core PRIVATE src/analysePlot.cpp) +#************************************************************* +# Handling of Options * +#************************************************************* if(LIBELAS) - message("LIBELAS enabled!") target_compile_definitions(petrack_core PRIVATE LIBELAS) target_sources(petrack_core PRIVATE src/libelas/elasDescriptor.cpp @@ -124,42 +214,53 @@ if(LIBELAS) ) endif(LIBELAS) - -if(QWT) - message("Qwt (analysis) enabled!") - # in qwt.../install steht, dass QWT_DLL gesetzt werden muss - insbesondere - # wegen debug/release mischungs problem - target_compile_definitions( - petrack_core PRIVATE - "QWT" - "QWT_DLL") - target_include_directories(petrack_core PUBLIC "${QWTPATH}/include") - target_link_directories(petrack_core PUBLIC "${QWTPATH}/lib") - target_link_libraries(petrack_core PUBLIC qwt$<$<CONFIG:Debug>:d>) - target_sources(petrack_core PRIVATE src/analysePlot.cpp) -else() - message("Qwt disabled!") -endif(QWT) - - +# TODO currently not available if(AVI) - message("AVI enabled!") target_compile_definitions(petrack_core PRIVATE AVI) - target_sources(petrack_core "src/aviFile.cpp") + target_sources(petrack_core PUBLIC + include/aviFile.h + src/aviFile.cpp + ) else() target_sources(petrack_core PRIVATE "src/aviFileWriter.cpp") endif(AVI) - # WIN32 steht für Windows allgemein, nicht nur 32Bit if(WIN32) target_link_libraries(petrack_core PUBLIC psapi) endif(WIN32) +################################################################################ +# petrack_core unit tests +################################################################################ +if(BUILD_UNIT_TESTS) + enable_testing() + if (USE_3RD_PARTY) + add_subdirectory("${CMAKE_SOURCE_DIR}/3rdparty/Catch2") + else() + find_package(Catch2 REQUIRED) + endif() + + find_package(Qt5Test REQUIRED) + find_package(trompeloeil REQUIRED + HINTS "${CMAKE_SOURCE_DIR}/3rdparty/trompeloeil/lib/cmake/trompeloeil") + + add_subdirectory(${CMAKE_SOURCE_DIR}/tests/unit_test) + target_link_libraries(petrack_tests PRIVATE petrack_core) + + target_link_libraries(petrack_tests PRIVATE Catch2::Catch2 Qt5::Test trompeloeil) + target_include_directories(petrack_tests PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}/petrack_core_autogen/include") + + if(BUILD_UNIT_TESTS_WITH_LLD) + target_compile_options(petrack_tests PRIVATE "-fuse-ld=lld") + target_link_options(petrack_tests PRIVATE "-fuse-ld=lld") + endif(BUILD_UNIT_TESTS_WITH_LLD) +endif(BUILD_UNIT_TESTS) + #************************************************************** # SOURCES * #************************************************************** - # An sich wäre nur target_include_diretories notwendig, aber AUTOUIC # sucht nur in target source nach, ob ein ui header included wurde. # Aus bequemlichkeit dann einfach alle aus der alten .pro rüberkopiert @@ -217,7 +318,6 @@ target_sources(petrack_core PRIVATE include/analysePlot.h ) - target_sources(petrack_core PRIVATE src/helper.cpp src/control.cpp @@ -280,11 +380,9 @@ target_sources(petrack PRIVATE petrack.rc icons/icons.qrc) - #***************************************************************************** # CODE AUS DER ALTEN .PRO DATEI, DER NOCH NICHT IN DIE CMAKE EINGEBAUT WURDE * #***************************************************************************** - if(${STEREO}) # Should not happen at the moment Code below was at this point in .pro # $$STEREO { !build_pass:message(Stereo enabled!) DEFINES += STEREO diff --git a/cmake_modules/FindQwt.cmake b/cmake_modules/FindQwt.cmake new file mode 100644 index 0000000000000000000000000000000000000000..85af368e19c993996b99ba2e09e78089c6feb3c9 --- /dev/null +++ b/cmake_modules/FindQwt.cmake @@ -0,0 +1,88 @@ +# Qt Widgets for Technical Applications +# available at http://www.http://qwt.sourceforge.net/ +# +# The module defines the following variables: +# Qwt_FOUND - the system has Qwt +# QWT_INCLUDE_DIR - where to find qwt_plot.h +# QWT_INCLUDE_DIRS - qwt includes +# QWT_LIBRARY - where to find the Qwt library +# QWT_LIBRARIES - aditional libraries +# QWT_VERSION_STRING - version (ex. 5.2.1) +# +# It also defines this imported target: +# Qwt::Qwt + +#============================================================================= +# Copyright 2010-2013, Julien Schueller +# Copyright 2018-2020, Rolf Eike Beer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of the FreeBSD Project. +#============================================================================= + +if (Qt5Gui_FOUND) + get_target_property(QT_INCLUDE_DIR Qt5::Gui INTERFACE_INCLUDE_DIRECTORIES) +endif () + +find_path ( QWT_INCLUDE_DIR + NAMES qwt_plot.h + HINTS ${QT_INCLUDE_DIR} + PATH_SUFFIXES qwt qwt-qt5 qwt6 +) + +set ( QWT_INCLUDE_DIRS ${QWT_INCLUDE_DIR} ) + +# version +set ( _VERSION_FILE ${QWT_INCLUDE_DIR}/qwt_global.h ) +if ( EXISTS ${_VERSION_FILE} ) + file ( STRINGS ${_VERSION_FILE} _VERSION_LINE REGEX "define[ ]+QWT_VERSION_STR" ) + if ( _VERSION_LINE ) + string ( REGEX REPLACE ".*define[ ]+QWT_VERSION_STR[ ]+\"([^\"]*)\".*" "\\1" QWT_VERSION_STRING "${_VERSION_LINE}" ) + endif () +endif () +unset ( _VERSION_FILE ) + +find_library ( QWT_LIBRARY + NAMES qwt qwt-qt5 + HINTS ${QT_LIBRARY_DIR} +) + +set ( QWT_LIBRARIES ${QWT_LIBRARY} ) + +include ( FindPackageHandleStandardArgs ) +find_package_handle_standard_args( Qwt REQUIRED_VARS QWT_LIBRARY QWT_INCLUDE_DIR VERSION_VAR QWT_VERSION_STRING ) + +if (Qwt_FOUND AND NOT TARGET Qwt::Qwt) + add_library(Qwt::Qwt UNKNOWN IMPORTED) + set_target_properties(Qwt::Qwt PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${QWT_INCLUDE_DIRS}" + IMPORTED_LOCATION "${QWT_LIBRARIES}") +endif () + +mark_as_advanced ( + QWT_LIBRARY + QWT_INCLUDE_DIR +) + diff --git a/cmake_modules/helper_functions.cmake b/cmake_modules/helper_functions.cmake new file mode 100644 index 0000000000000000000000000000000000000000..70532ff127f6814be6d292fdc49f7d869adcf770 --- /dev/null +++ b/cmake_modules/helper_functions.cmake @@ -0,0 +1,17 @@ +function(print_var variable) + message(STATUS "${variable}=${${variable}}") +endfunction() + +# There is a long outstanding issue with CMake where CMake does not support +# relative paths in CMAKE_PREFIX_PATH but does not report anything. Many hours +# have been wasted over this behavior. We are checking to save your this to +# save everyone some headache. :) +function(check_prefix_path) + if(CMAKE_PREFIX_PATH) + foreach(path ${CMAKE_PREFIX_PATH}) + if(NOT IS_ABSOLUTE ${path}) + message(FATAL_ERROR "CMake does not support relative paths for CMAKE_PREFIX_PATH! [${path}]") + endif() + endforeach() + endif() +endfunction()