From e10c38c112727c0f0acbccd9691328b1bad7c3db Mon Sep 17 00:00:00 2001 From: Konrad Schatz <> Date: Thu, 30 Jun 2022 13:43:19 +0200 Subject: [PATCH 1/5] fix: allow for product entries of different types and avoid compile error C2039: 'ReturnType': is not a member of 'Eigen::ScalarBinaryOpTraits...' --- include/cppad/example/cppad_eigen.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/cppad/example/cppad_eigen.hpp b/include/cppad/example/cppad_eigen.hpp index bb8a10517..56e553edb 100644 --- a/include/cppad/example/cppad_eigen.hpp +++ b/include/cppad/example/cppad_eigen.hpp @@ -156,6 +156,20 @@ namespace Eigen { static CppAD::AD infinity(void) { return CppAD::numeric_limits< CppAD::AD >::infinity(); } }; + + /** + * Determines that the given binary operation of two numeric types involving + * an AD is allowed and what the scalar return type is + */ + template + struct ScalarBinaryOpTraits,S,BinOp>{ + typedef CppAD::AD ReturnType; + }; + template + struct ScalarBinaryOpTraits,BinOp> + { + typedef CppAD::AD ReturnType; + }; } /* %$$ From 90aca75c4d82251c9db98bdf53073374ac3dad8d Mon Sep 17 00:00:00 2001 From: Konrad Schatz <> Date: Thu, 30 Jun 2022 18:31:19 +0200 Subject: [PATCH 2/5] - fixed: no proper cmake interface (e.g. missing targets export) - now simplified usage of cppad via find_package and target_link_libraries in depending projects is possible - fixed: problems if pkgconfig can not be used - fixed: linking error (not finding definition of local::temp_file) - using more generic header install directory --- CMakeLists.txt | 75 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1155eec11..7182c6c80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,31 +292,31 @@ SET(system_include TRUE) SET(remove_coin_or FALSE) # # eigen -IF( include_eigen ) - pkgconfig_info(eigen3 ${system_include} ${remove_coin_or}) - SET(eigen_LIBRARIES "${eigen3_LIBRARIES}") +IF( include_eigen AND NOT USE_CMAKE_INTERFACE) + pkgconfig_info(Eigen3 ${system_include} ${remove_coin_or}) + SET(eigen_LIBRARIES "${Eigen3_LIBRARIES}") SET(cppad_has_eigen 1) -ELSE( include_eigen ) +ELSE() SET(cppad_has_eigen 0) -ENDIF( include_eigen ) +ENDIF() # # adolc -IF( include_adolc ) +IF( include_adolc AND NOT USE_CMAKE_INTERFACE) pkgconfig_info(adolc ${system_include} ${remove_coin_or}) SET(cppad_has_adolc 1) -ELSE( include_adolc ) +ELSE() SET(cppad_has_adolc 0) -ENDIF( include_adolc ) +ENDIF() # # ipopt -IF( include_ipopt ) +IF( include_ipopt AND NOT USE_CMAKE_INTERFACE) SET(remove_coin_or TRUE) pkgconfig_info(ipopt ${system_include} ${remove_coin_or}) SET(cppad_has_ipopt 1) SET(remove_coin_or FALSE) -ELSE( include_ipopt ) +ELSE() SET(cppad_has_ipopt 0) -ENDIF( include_ipopt ) +ENDIF() # # cppadcg IF( include_cppadcg ) @@ -540,7 +540,7 @@ CONFIGURE_FILE( # ${cppad_abs_includedir}/cppad INSTALL( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/cppad/" - DESTINATION ${cppad_abs_includedir}/cppad + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME} FILES_MATCHING PATTERN "*.hpp" PATTERN "omh" EXCLUDE ) # @@ -553,3 +553,54 @@ ENDIF ( cmake_install_docdir ) # uninstall procedure # ============================================================================= ADD_CUSTOM_TARGET(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppad_uninstall.cmake) + + +#============================================================================= +# Support depending projects by providing CMake targets and config file +# TODO: more adaptive implementation of the following as one might have to "generate" twice +#============================================================================= +include(GNUInstallDirs) + +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) + +set(SOURCES + ./cppad_lib/temp_file.cpp +) +add_library(${PROJECT_NAME} STATIC ${SOURCES} ) + +IF( include_eigen AND USE_CMAKE_INTERFACE) + find_package(Eigen3 3.4.0 REQUIRED) + target_link_libraries( ${PROJECT_NAME} INTERFACE + Eigen3::Eigen + ) + SET(cppad_has_eigen 1) +ELSE() + SET(cppad_has_eigen 0) +ENDIF() + +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $ +) + +# install targets of current project and register for export +install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) +set(TARGETS_SCRIPT_FILE ${PROJECT_NAME}Targets.cmake) +set(CONFIG_SCRIPT_FILE_SRC ${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in) +set(CONFIG_SCRIPT_FILE_DST ${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake) + +configure_file("${CONFIG_SCRIPT_FILE_SRC}" "${CONFIG_SCRIPT_FILE_DST}" @ONLY) +install(FILES "${CONFIG_SCRIPT_FILE_DST}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +install( + EXPORT ${PROJECT_NAME}Targets + FILE "${TARGETS_SCRIPT_FILE}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) From 6e4a74b9e2d7271650de45f9d9daa241e2792365 Mon Sep 17 00:00:00 2001 From: Konrad Schatz <> Date: Thu, 30 Jun 2022 18:32:54 +0200 Subject: [PATCH 3/5] - support depending libraries by using transitive dependencies (Eigen3, so far) --- cmake/cppadConfig.cmake.in | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 cmake/cppadConfig.cmake.in diff --git a/cmake/cppadConfig.cmake.in b/cmake/cppadConfig.cmake.in new file mode 100644 index 000000000..3b0556106 --- /dev/null +++ b/cmake/cppadConfig.cmake.in @@ -0,0 +1,8 @@ +include(CMakeFindDependencyMacro) + +set(TARGETS_SCRIPT_FILE @TARGETS_SCRIPT_FILE@) + +include("${CMAKE_CURRENT_LIST_DIR}/${TARGETS_SCRIPT_FILE}") + +# provide transitive dependencies here +find_dependency(Eigen3) \ No newline at end of file From 702de61109071aa3231d278e952c2bef06d3bd4f Mon Sep 17 00:00:00 2001 From: Konrad Schatz <> Date: Tue, 5 Jul 2022 12:36:07 +0200 Subject: [PATCH 4/5] testing Eigen mixed base type conflict --- CMakeLists.txt | 5 +++-- test_more/general/cppad_eigen.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7182c6c80..8974d0192 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -565,12 +565,13 @@ set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) set(SOURCES ./cppad_lib/temp_file.cpp + ./test_more/general/cppad_eigen.cpp ) add_library(${PROJECT_NAME} STATIC ${SOURCES} ) IF( include_eigen AND USE_CMAKE_INTERFACE) find_package(Eigen3 3.4.0 REQUIRED) - target_link_libraries( ${PROJECT_NAME} INTERFACE + target_link_libraries( ${PROJECT_NAME} PUBLIC Eigen3::Eigen ) SET(cppad_has_eigen 1) @@ -578,7 +579,7 @@ ELSE() SET(cppad_has_eigen 0) ENDIF() -target_include_directories(${PROJECT_NAME} INTERFACE +target_include_directories(${PROJECT_NAME} PUBLIC $ $ ) diff --git a/test_more/general/cppad_eigen.cpp b/test_more/general/cppad_eigen.cpp index 8bb0d531b..3ca8fac7e 100644 --- a/test_more/general/cppad_eigen.cpp +++ b/test_more/general/cppad_eigen.cpp @@ -76,5 +76,14 @@ bool cppad_eigen(void) D = A * B * C; ok &= D(0,0) == 6.0 ; + // Multiplying Eigen objects (such as matrices) of mixed base types used to fail without appropriate "ScalarBinaryOpTraits" implementation + const int nn = 3; + Eigen::Matrix AA = Eigen::Matrix::Zero(); + Eigen::Matrix BB = Eigen::Matrix::Zero(); + auto CC = BB*AA; + auto cc = AA(0,0)*BB(0,0); + ok &= CC(0,0) == 0; + ok &= cc == 0; + return ok; } From c43c140bf6c3d1406bfd8431aac064900dc379b4 Mon Sep 17 00:00:00 2001 From: Konrad Schatz <> Date: Wed, 6 Jul 2022 16:27:30 +0200 Subject: [PATCH 5/5] recover "pkgconfig_info(Eigen3 ...)" -> "pkgconfig_info(eigen3 ...)" --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ac80e261..cedbffe4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,7 +293,7 @@ SET(remove_coin_or FALSE) # # eigen IF( include_eigen AND NOT USE_CMAKE_INTERFACE) - pkgconfig_info(Eigen3 ${system_include} ${remove_coin_or}) + pkgconfig_info(eigen3 ${system_include} ${remove_coin_or}) SET(eigen_LIBRARIES "${Eigen3_LIBRARIES}") SET(cppad_has_eigen 1) ELSE()