Commit 89172960 authored by Michael Tesch's avatar Michael Tesch
Browse files

Merge branch 'master' into 'master'

Improve CMake Support

See merge request !25
parents 73c8bb6f 6cd43d07
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ cover:
pages:
  script:
  - cmake -Bbuild -H. -DCODE_COVERAGE=ON -DCPPDUALS_TESTING=ON
  - cmake --build build --target docs
  - cmake --build build --target cppduals_docs
  - cmake --build build --target cov-html
  - mv build/docs public/
  - mv build/coverage public/
+99 −45
Original line number Diff line number Diff line
#
# CMake for cppduals
#
cmake_minimum_required (VERSION 3.10)
project (cppduals C CXX)
cmake_minimum_required (VERSION 3.1)
project (cppduals
  VERSION 0.2.0
  LANGUAGES C CXX
  )
include (GNUInstallDirs)

#set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CPPDUALS_VERSION 0.2.0)
set (CMAKE_CXX_STANDARD 11 CACHE STRING "Which C++ standard to test against.")
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CMAKE_DISABLE_IN_SOURCE_BUILD ON)
if (NOT CMAKE_CONFIGURATION_TYPES AND
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    message (STATUS "Configuring cppduals for standalone build")
    set (CPPDUALS_STANDALONE TRUE)
elseif ()
    message (STATUS "Configuring cppduals for subproject build")
    set (CPPDUALS_STANDALONE FALSE)
endif ()
if (CPPDUALS_STANDALONE AND
    NOT CMAKE_CONFIGURATION_TYPES AND
    NOT CMAKE_NO_BUILD_TYPE AND
    NOT CMAKE_BUILD_TYPE AND
    CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
  set (CMAKE_BUILD_TYPE RelWithDebInfo)
    NOT CMAKE_BUILD_TYPE
    )
  message (STATUS "Setting build type to 'RelWithDebInfo' since none specified")
  set_property (CACHE CMAKE_BUILD_TYPE PROPERTY VALUE RelWithDebInfo)
  set_property (CACHE CMAKE_BUILD_TYPE PROPERTY
    STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
    STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo"
    )
endif ()
if (CPPDUALS_STANDALONE AND
    CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set (CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install"
       CACHE PATH "cppduals installation directory"
       FORCE
       )
  message (STATUS "No install prefix specified; using '${CMAKE_INSTALL_PREFIX}'")
endif ()

set_property (CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS 11 14 17 20)
@@ -51,13 +71,28 @@ if (CPPDUALS_USE_LIBCXX)
  endif ()
endif (CPPDUALS_USE_LIBCXX)

################################################################################
#
# Primary Library Target
#
add_library (cppduals_duals INTERFACE)
target_include_directories (cppduals_duals
  INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    )
set_target_properties (cppduals_duals
  PROPERTIES
    EXPORT_NAME duals
    )
add_library (cppduals::duals ALIAS cppduals_duals)

#
# Build external dependencies for testing & benchmarking
#
if (CPPDUALS_TESTING)

  file (MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/thirdparty")
  cmake_minimum_required (VERSION 3.10) # need gtest_discover_tests
  file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/thirdparty")

  # generator name
  if (NOT "${CMAKE_EXTRA_GENERATOR}" STREQUAL "")
@@ -68,8 +103,15 @@ if (CPPDUALS_TESTING)

  # configure the thirdparty build dir
  execute_process (
    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/thirdparty"
    COMMAND ${CMAKE_COMMAND} -G${GENERATOR_STRING} "-DCMAKE_CONFIGURATION_TYPES=${CMAKE_CONFIGURATION_TYPES}" -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DCPPDUALS_BENCHMARK=${CPPDUALS_BENCHMARK} -DCPPDUALS_EIGEN_LATEST=${CPPDUALS_EIGEN_LATEST} -DCPPDUALS_USE_LIBCXX=${CPPDUALS_USE_LIBCXX} ${CMAKE_SOURCE_DIR}/thirdparty
    WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/thirdparty"
    COMMAND ${CMAKE_COMMAND} "-G${GENERATOR_STRING}"
                             "-DCMAKE_CONFIGURATION_TYPES=${CMAKE_CONFIGURATION_TYPES}"
                             "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
                             "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
                             "-DCPPDUALS_BENCHMARK=${CPPDUALS_BENCHMARK}"
                             "-DCPPDUALS_EIGEN_LATEST=${CPPDUALS_EIGEN_LATEST}"
                             "-DCPPDUALS_USE_LIBCXX=${CPPDUALS_USE_LIBCXX}"
                             "${PROJECT_SOURCE_DIR}/thirdparty"
    RESULT_VARIABLE DEPS_CONFIG_RESULT
    )
  if (DEPS_CONFIG_RESULT)
@@ -78,10 +120,10 @@ if (CPPDUALS_TESTING)

  # build the thirdparty
  message ("***************************************************************")
  message ("********** Building '${CMAKE_BINARY_DIR}/thirdparty'...")
  message ("********** Building '${PROJECT_BINARY_DIR}/thirdparty'...")
  message ("***************************************************************")
  execute_process (
    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/thirdparty"
    WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/thirdparty"
    COMMAND "${CMAKE_COMMAND}" --build .
    RESULT_VARIABLE DEPS_BUILD_RESULT
    )
@@ -95,31 +137,26 @@ if (CPPDUALS_TESTING)

  add_subdirectory (thirdparty)

endif (CPPDUALS_TESTING)
#
# done
#
################################################################################
endif ()

#
# Code Coverage Configuration
#
add_library (coverage_config INTERFACE)

add_library (cppduals_coverage_config INTERFACE)
option (CODE_COVERAGE "Enable coverage reporting" OFF)
if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  # Add required flags (GCC & LLVM/Clang)
  target_compile_options (coverage_config INTERFACE
  target_compile_options (cppduals_coverage_config INTERFACE
    -O0        # no optimization
    -g         # generate debug info
    --coverage # sets all required flags
    )
  if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
    target_link_options (coverage_config INTERFACE --coverage)
    target_link_options (cppduals_coverage_config INTERFACE --coverage)
  else ()
    target_link_libraries (coverage_config INTERFACE --coverage)
    target_link_libraries (cppduals_coverage_config INTERFACE --coverage)
  endif ()
endif ()
endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")

#
# Testing
@@ -133,37 +170,54 @@ endif (CPPDUALS_TESTING)
#
# Documentation
#
configure_file (${CMAKE_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_BINARY_DIR}/doc/Doxyfile)
configure_file (${CMAKE_SOURCE_DIR}/doc/DoxygenLayout.xml ${CMAKE_BINARY_DIR}/doc/DoxygenLayout.xml COPYONLY)
configure_file (${CMAKE_SOURCE_DIR}/doc/header.html ${CMAKE_BINARY_DIR}/doc/header.html COPYONLY)
configure_file (${CMAKE_SOURCE_DIR}/doc/footer.html ${CMAKE_BINARY_DIR}/doc/footer.html COPYONLY)
configure_file (${CMAKE_SOURCE_DIR}/doc/favicon.ico ${CMAKE_BINARY_DIR}/doc/favicon.ico COPYONLY)
configure_file (${CMAKE_SOURCE_DIR}/doc/customdoxygen.css ${CMAKE_BINARY_DIR}/doc/customdoxygen.css)
add_custom_target (docs
  COMMAND rm -f docs/*
  COMMAND cd doc && VERSION=1 doxygen Doxyfile
find_program (DOXYGEN doxygen)
if (DOXYGEN)
  configure_file (${PROJECT_SOURCE_DIR}/doc/Doxyfile.in       ${PROJECT_BINARY_DIR}/doc/Doxyfile)
  configure_file (${PROJECT_SOURCE_DIR}/doc/DoxygenLayout.xml ${PROJECT_BINARY_DIR}/doc/DoxygenLayout.xml COPYONLY)
  configure_file (${PROJECT_SOURCE_DIR}/doc/header.html       ${PROJECT_BINARY_DIR}/doc/header.html COPYONLY)
  configure_file (${PROJECT_SOURCE_DIR}/doc/footer.html       ${PROJECT_BINARY_DIR}/doc/footer.html COPYONLY)
  configure_file (${PROJECT_SOURCE_DIR}/doc/favicon.ico       ${PROJECT_BINARY_DIR}/doc/favicon.ico COPYONLY)
  configure_file (${PROJECT_SOURCE_DIR}/doc/customdoxygen.css ${PROJECT_BINARY_DIR}/doc/customdoxygen.css)
  add_custom_target (cppduals_docs
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/doc
    COMMAND cmake -E remove_directory ${PROJECT_BINARY_DIR}/docs
    COMMAND ${DOXYGEN} Doxyfile
    )
else ()
  add_custom_target (cppduals_docs
    COMMAND echo "Please install doxygen and reconfigure to build the docs"
    )
endif ()

#
# Installation
#
install (TARGETS cppduals_duals EXPORT cppduals_export)
install (EXPORT cppduals_export
  FILE cppduals-config.cmake
  NAMESPACE cppduals::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cppduals
  )
install (
  DIRECTORY duals
  DESTINATION include
  DIRECTORY ${PROJECT_SOURCE_DIR}/duals
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
  PATTERN "*~" EXCLUDE
  )
install (
  DIRECTORY ${PROJECT_BINARY_DIR}/docs/   # Trailing slash triggers rename
  DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/cppduals
  OPTIONAL
  )

#
# etags
#
find_program (ETAGS etags)
if (ETAGS)
  add_custom_target (tags
    COMMAND etags --language=c++ ${CMAKE_SOURCE_DIR}/duals/*
    COMMAND etags --language=c++ --append ${CMAKE_SOURCE_DIR}/duals/arch/*/*
    COMMAND etags --language=c++ --append `find ${CMAKE_BINARY_DIR}/thirdparty/eigenX/src/eigenX -type f`
  add_custom_target (cppduals_etags
    COMMAND ${ETAGS} --language=c++ ${PROJECT_SOURCE_DIR}/duals/*
    COMMAND ${ETAGS} --language=c++ --append ${PROJECT_SOURCE_DIR}/duals/arch/*/*
    COMMAND ${ETAGS} --language=c++ --append `find ${PROJECT_BINARY_DIR}/thirdparty/eigenX/src/eigenX -type f`
    )
  add_custom_target (etags DEPENDS tags)
endif (ETAGS)
message ("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
+61 −14
Original line number Diff line number Diff line
@@ -73,34 +73,81 @@ Installation
============

Copy the [duals/](./duals/) directory (or just [dual](./duals/dual) )
somewhere your `#include`\ s can find it.  Then just `#include
somewhere your `#include`s can find it.  Then just `#include
<duals/dual[_eigen]>` from your source.

Or, using cmake:
Alternatively, `cppduals` supports building with CMake. If using CMake v3.14+,
the ``FetchContent`` pattern is straightforward and enables using CMake targets
to specify library dependencies:

```sh
git clone https://gitlab.com/tesch1/cppduals.git && cd cppduals
cmake -Bbuildx -H. -DCPPDUALS_EIGEN_LATEST=OFF -DCPPDUALS_TESTING=OFF -DCPPDUALS_BENCHMARK=OFF
cmake --build buildx --target install
```cmake
  include(FetchContent)

  # Have CMake download the library
  set (CPPDUALS_TAG v0.1.2)
  set (CPPDUALS_MD5 48d9276482e5f07a768875ef692d14cd)
  FetchContent_Declare (cppduals
    URL https://gitlab.com/tesch1/cppduals/-/archive/${CPPDUALS_TAG}/cppduals-${CPPDUALS_TAG}.tar.bz2
    URL_HASH MD5=${CPPDUALS_MD5}
    )
  FetchContent_MakeAvailable (cppduals)

  # Link to cppduals
  target_link_libraries (your_target PRIVATE cppduals::duals)
```

Or, using cmake's `ExternalProject_Add()`
Older versions of CMake can achieve a similar result using the ``ExternalProject``
family of commands and modifying the global preprocessor search path:

```cmake
  include(ExternalProject)

  # Have CMake download the library
  set (CPPDUALS_VER 0.1.2)
  set (CPPDUALS_MD5 48d9276482e5f07a768875ef692d14cd)
  ExternalProject_Add (cppdualsX
    PREFIX cppdualsX
  ExternalProject_Add (cppduals
    URL https://gitlab.com/tesch1/cppduals/-/archive/v${CPPDUALS_VER}/cppduals-v${CPPDUALS_VER}.tar.bz2
    URL_HASH MD5=${CPPDUALS_MD5}
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
    )
  ExternalProject_Get_Property (cppdualsX source_dir)

  # Make include directory globally visible
  ExternalProject_Get_Property (cppduals source_dir)
  include_directories (${source_dir}/)
```

Alternatively, `cppduals` supports installation and discovery via the
`find_package` utility. First, download and install the library to a
location of your choosing:

```sh
  CPPDUALS_PREFIX=<desired_install_location>
  git clone https://gitlab.com/tesch1/cppduals.git && cd cppduals
  mkdir build && cd build
  cmake -DCMAKE_INSTALL_PREFIX="$CPPDUALS_PREFIX" ..
  cmake --build . --target install
```

Then, in your project's `CMakeLists.txt`, find and link to the library in the
standard manner:

```cmake
  find_package(cppduals REQUIRED)
  target_link_libraries(your_target PRIVATE cppduals::cppduals)
```

If you installed `cppduals` to a location that is not on `find_package`'s
default search path, you can specify the location by setting the `cppduals_DIR`
environment variable when configuring your project:

```sh
  cd your_build_dir
  cppduals_DIR="${CPPDUALS_PREFIX}" cmake ..
```


Benchmarks
==========

+11 −11
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ PROJECT_NAME = "cppduals"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER         = ${CPPDUALS_VERSION}
PROJECT_NUMBER         = ${cppduals_VERSION}

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -51,7 +51,7 @@ PROJECT_BRIEF = "Dual numbers for C++"
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.

PROJECT_LOGO           = ../../doc/Greek_Epsilon_archaic.svg
PROJECT_LOGO           = ${PROJECT_SOURCE_DIR}/doc/Greek_Epsilon_archaic.svg

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
@@ -765,9 +765,9 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT                  = ${CMAKE_SOURCE_DIR}/duals/dual \
                         ${CMAKE_SOURCE_DIR}/duals/dual_eigen \
                         ${CMAKE_SOURCE_DIR}/doc
INPUT                  = ${PROJECT_SOURCE_DIR}/duals/dual \
                         ${PROJECT_SOURCE_DIR}/duals/dual_eigen \
                         ${PROJECT_SOURCE_DIR}/doc

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -860,7 +860,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).

IMAGE_PATH             = ${CMAKE_SOURCE_DIR}/doc
IMAGE_PATH             = ${PROJECT_SOURCE_DIR}/doc

# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -908,7 +908,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.

USE_MDFILE_AS_MAINPAGE = ${CMAKE_SOURCE_DIR}/README.md
USE_MDFILE_AS_MAINPAGE = ${PROJECT_SOURCE_DIR}/README.md

#---------------------------------------------------------------------------
# Configuration options related to source browsing
@@ -1984,7 +1984,7 @@ SEARCH_INCLUDES = YES
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.

INCLUDE_PATH           = ${CMAKE_SOURCE_DIR}
INCLUDE_PATH           = ${PROJECT_SOURCE_DIR}

# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -2303,7 +2303,7 @@ DOT_PATH =
# command).
# This tag requires that the tag HAVE_DOT is set to YES.

DOTFILE_DIRS           = ${CMAKE_SOURCE_DIR}/doc
DOTFILE_DIRS           = ${PROJECT_SOURCE_DIR}/doc

# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
+3 −2
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
# Public License v. 2.0. If a copy of the MPL was not distributed
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

# gtest_discover_tests requires 3.10
cmake_minimum_required (VERSION 3.10)

# Configure google-test as a downloadable library.
@@ -72,7 +73,7 @@ foreach (TEST_ ${ALL_TESTS})
    string (REPLACE ";" ", " L2 "${CMAKE_CXX_FLAGS}")
    target_compile_options (${TEST} PUBLIC ${PHASE_FLAGS})
    target_compile_definitions (${TEST} PRIVATE "OPT_FLAGS=${L2}")
    target_link_libraries (${TEST} gtest_main coverage_config )
    target_link_libraries (${TEST} gtest_main cppduals_coverage_config )
    #target_link_libraries (${TEST} -lasan)
    add_dependencies (${TEST} eigenX expokitX)
    gtest_discover_tests (${TEST} TEST_LIST ${TEST}_targets)
@@ -208,7 +209,7 @@ else ()
endif ()

set_target_properties (sandbox PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries (sandbox PUBLIC coverage_config)
target_link_libraries (sandbox PUBLIC cppduals_coverage_config)

#
# Generate coverage reports
Loading