I am not good with CMake, and I cannot find good explanations about how to use its FetchContent
functionality. Indeed, most repositories seem to require different treatment, and the rules of such treatment defy my comprehension.
That said, here is my problem. I would like to use CppADCodeGen in my project using CMake FetchContent
. Here is my code:
include(FetchContent)
message(STATUS "Fetching eigen...")
FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
option(EIGEN_BUILD_DOC OFF)
option(BUILD_TESTING OFF)
option(EIGEN_LEAVE_TEST_IN_ALL_TARGET OFF)
option(EIGEN_BUILD_PKGCONFIG OFF)
FetchContent_MakeAvailable(eigen)
message(STATUS "Fetching cppad...")
FetchContent_Declare(
cppad
GIT_REPOSITORY https://github.com/coin-or/CppAD.git
GIT_TAG 20210000.8
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(cppad)
message(STATUS "Fetching cppadcodgen...")
FetchContent_Declare(
cppadcodgen
GIT_REPOSITORY https://github.com/joaoleal/CppADCodeGen.git
GIT_TAG v2.4.3
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(cppadcodgen)
Here is the output and the errors I get:
[cmake] Not searching for unused variables given on the command line.
[cmake] -- The C compiler identification is GNU 11.1.0
[cmake] -- The CXX compiler identification is GNU 11.1.0
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: /bin/x86_64-linux-gnu-gcc-11 - skipped
[cmake] -- Detecting C compile features
[cmake] -- Detecting C compile features - done
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: /bin/x86_64-linux-gnu-g++-11 - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done
[cmake] -- Fetching eigen...
[cmake] -- Performing Test EIGEN_COMPILER_SUPPORT_CPP11
[cmake] -- Performing Test EIGEN_COMPILER_SUPPORT_CPP11 - Success
[cmake] -- Performing Test COMPILER_SUPPORT_std=cpp03
[cmake] -- Performing Test COMPILER_SUPPORT_std=cpp03 - Success
[cmake] -- Performing Test standard_math_library_linked_to_automatically
[cmake] -- Performing Test standard_math_library_linked_to_automatically - Success
[cmake] -- Standard libraries to link to explicitly: none
[cmake] -- Performing Test COMPILER_SUPPORT_WERROR
[cmake] -- Performing Test COMPILER_SUPPORT_WERROR - Success
[cmake] -- Performing Test COMPILER_SUPPORT_pedantic
[cmake] -- Performing Test COMPILER_SUPPORT_pedantic - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wall
[cmake] -- Performing Test COMPILER_SUPPORT_Wall - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wextra
[cmake] -- Performing Test COMPILER_SUPPORT_Wextra - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wundef
[cmake] -- Performing Test COMPILER_SUPPORT_Wundef - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wcastalign
[cmake] -- Performing Test COMPILER_SUPPORT_Wcastalign - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wcharsubscripts
[cmake] -- Performing Test COMPILER_SUPPORT_Wcharsubscripts - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wnonvirtualdtor
[cmake] -- Performing Test COMPILER_SUPPORT_Wnonvirtualdtor - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wunusedlocaltypedefs
[cmake] -- Performing Test COMPILER_SUPPORT_Wunusedlocaltypedefs - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wpointerarith
[cmake] -- Performing Test COMPILER_SUPPORT_Wpointerarith - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wwritestrings
[cmake] -- Performing Test COMPILER_SUPPORT_Wwritestrings - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wformatsecurity
[cmake] -- Performing Test COMPILER_SUPPORT_Wformatsecurity - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wshorten64to32
[cmake] -- Performing Test COMPILER_SUPPORT_Wshorten64to32 - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_Wlogicalop
[cmake] -- Performing Test COMPILER_SUPPORT_Wlogicalop - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wenumconversion
[cmake] -- Performing Test COMPILER_SUPPORT_Wenumconversion - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wcpp11extensions
[cmake] -- Performing Test COMPILER_SUPPORT_Wcpp11extensions - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_Wdoublepromotion
[cmake] -- Performing Test COMPILER_SUPPORT_Wdoublepromotion - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wshadow
[cmake] -- Performing Test COMPILER_SUPPORT_Wshadow - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wnopsabi
[cmake] -- Performing Test COMPILER_SUPPORT_Wnopsabi - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wnovariadicmacros
[cmake] -- Performing Test COMPILER_SUPPORT_Wnovariadicmacros - Success
[cmake] -- Performing Test COMPILER_SUPPORT_Wnolonglong
[cmake] -- Performing Test COMPILER_SUPPORT_Wnolonglong - Success
[cmake] -- Performing Test COMPILER_SUPPORT_fnochecknew
[cmake] -- Performing Test COMPILER_SUPPORT_fnochecknew - Success
[cmake] -- Performing Test COMPILER_SUPPORT_fnocommon
[cmake] -- Performing Test COMPILER_SUPPORT_fnocommon - Success
[cmake] -- Performing Test COMPILER_SUPPORT_fstrictaliasing
[cmake] -- Performing Test COMPILER_SUPPORT_fstrictaliasing - Success
[cmake] -- Performing Test COMPILER_SUPPORT_wd981
[cmake] -- Performing Test COMPILER_SUPPORT_wd981 - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_wd2304
[cmake] -- Performing Test COMPILER_SUPPORT_wd2304 - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_STRICTANSI
[cmake] -- Performing Test COMPILER_SUPPORT_STRICTANSI - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_Qunusedarguments
[cmake] -- Performing Test COMPILER_SUPPORT_Qunusedarguments - Failed
[cmake] -- Performing Test COMPILER_SUPPORT_ansi
[cmake] -- Performing Test COMPILER_SUPPORT_ansi - Success
[cmake] -- Performing Test COMPILER_SUPPORT_OPENMP
[cmake] -- Performing Test COMPILER_SUPPORT_OPENMP - Success
[cmake] -- Looking for a Fortran compiler
[cmake] -- Looking for a Fortran compiler - /usr/bin/f95
[cmake] -- The Fortran compiler identification is GNU 9.3.0
[cmake] -- Detecting Fortran compiler ABI info
[cmake] -- Detecting Fortran compiler ABI info - done
[cmake] -- Check for working Fortran compiler: /usr/bin/f95 - skipped
[cmake] -- Checking whether /usr/bin/f95 supports Fortran 90
[cmake] -- Checking whether /usr/bin/f95 supports Fortran 90 - yes
[cmake] -- Found unsuitable Qt version "5.12.8" from /usr/bin/qmake
[cmake] -- Qt4 not found, so disabling the mandelbrot and opengl demos
[cmake] -- Found CHOLMOD: /usr/include/suitesparse
[cmake] -- Found UMFPACK: /usr/include/suitesparse
[cmake] -- Found KLU: /usr/include/suitesparse
[cmake] -- Performing Test SUPERLU_HAS_GLOBAL_MEM_USAGE_T
[cmake] -- Performing Test SUPERLU_HAS_GLOBAL_MEM_USAGE_T - Success
[cmake] -- Performing Test SUPERLU_HAS_CLEAN_ENUMS
[cmake] -- Performing Test SUPERLU_HAS_CLEAN_ENUMS - Success
[cmake] -- Performing Test SUPERLU_HAS_GLOBALLU_T
[cmake] -- Performing Test SUPERLU_HAS_GLOBALLU_T - Success
[cmake] -- Found SuperLU: /usr/include/superlu (found suitable version "5.0", minimum required is "4.0")
[cmake] -- Checking for one of the modules 'hwloc'
[cmake] -- Performing Test HAVE_HWLOC_PARENT_MEMBER
[cmake] -- Performing Test HAVE_HWLOC_PARENT_MEMBER - Success
[cmake] -- Performing Test HAVE_HWLOC_CACHE_ATTR
[cmake] -- Performing Test HAVE_HWLOC_CACHE_ATTR - Success
[cmake] -- Performing Test HAVE_HWLOC_OBJ_PU
[cmake] -- Performing Test HAVE_HWLOC_OBJ_PU - Success
[cmake] -- Looking for hwloc_bitmap_free in hwloc
[cmake] -- Looking for hwloc_bitmap_free in hwloc - found
[cmake] -- A version of Pastix has been found but pastix_nompi.h does not exist in the include directory. Because Eigen tests require a version without MPI, we disable the Pastix backend.
[cmake] --
[cmake] -- Configured Eigen 3.4.0
[cmake] --
[cmake] -- Available targets (use: make TARGET):
[cmake] -- ---------+--------------------------------------------------------------
[cmake] -- Target | Description
[cmake] -- ---------+--------------------------------------------------------------
[cmake] -- install | Install Eigen. Headers will be installed to:
[cmake] -- | <CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>
[cmake] -- | Using the following values:
[cmake] -- | CMAKE_INSTALL_PREFIX: /usr/local
[cmake] -- | INCLUDE_INSTALL_DIR: include/eigen3
[cmake] -- | Change the install location of Eigen headers using:
[cmake] -- | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix
[cmake] -- | Or:
[cmake] -- | cmake . -DINCLUDE_INSTALL_DIR=yourdir
[cmake] -- doc | Generate the API documentation, requires Doxygen & LaTeX
[cmake] -- blas | Build BLAS library (not the same thing as Eigen)
[cmake] -- uninstall| Remove files installed by the install target
[cmake] -- ---------+--------------------------------------------------------------
[cmake] --
[cmake] -- Fetching cppad...
[cmake] CMake Deprecation Warning at build/_deps/cppad-src/CMakeLists.txt:20 (CMAKE_MINIMUM_REQUIRED):
[cmake] Compatibility with CMake < 2.8.12 will be removed from a future version of
[cmake] CMake.
[cmake]
[cmake] Update the VERSION argument <min> value or use a ...<max> suffix to tell
[cmake] CMake that the project does not need compatibility with older versions.
[cmake]
[cmake]
[cmake] CMake Warning (dev) at build/_deps/cppad-src/CMakeLists.txt:35 (PROJECT):
[cmake] Policy CMP0048 is not set: project() command manages VERSION variables.
[cmake] Run "cmake --help-policy CMP0048" for policy details. Use the cmake_policy
[cmake] command to set the policy and suppress this warning.
[cmake]
[cmake] The following variable(s) would be set to empty:
[cmake]
[cmake] PROJECT_VERSION
[cmake] PROJECT_VERSION_MAJOR
[cmake] PROJECT_VERSION_MINOR
[cmake] PROJECT_VERSION_PATCH
[cmake] This warning is for project developers. Use -Wno-dev to suppress it.
[cmake]
[cmake] -- Performing Test cppad_cplusplus_201100_ok
[cmake] -- Performing Test cppad_cplusplus_201100_ok - Success
[cmake] -- cppad_cplusplus_201100_ok = 1
[cmake] -- cmake_install_datadir = share
[cmake] -- cmake_install_docdir = NOTFOUND
[cmake] -- cmake_install_includedirs = include
[cmake] -- cmake_install_libdirs = lib
[cmake] -- cppad_prefix = /usr/local
[cmake] -- cppad_postfix = NOTFOUND
[cmake] -- cppad_cxx_flags =
[cmake] -- cppad_profile_flag = NOTFOUND
[cmake] -- cppad_testvector = cppad
[cmake] -- cppad_max_num_threads = 48
[cmake] -- cppad_tape_id_type = unsigned int
[cmake] -- cppad_tape_addr_type = unsigned int
[cmake] -- cppad_debug_which = debug_all
[cmake] -- include_eigen = false
[cmake] -- include_adolc = false
[cmake] -- include_ipopt = false
[cmake] -- include_cppadcg = false
[cmake] -- colpack_prefix = NOTFOUND
[cmake] -- sacado_prefix = NOTFOUND
[cmake] -- fadbad_prefix = NOTFOUND
[cmake] -- CMAKE_CXX_FLAGS_DEBUG = -g
[cmake] -- CMAKE_CXX_FLAGS_RELEASE = -O3 -DNDEBUG
[cmake] -- Found OpenMP_C: -fopenmp (found version "4.5")
[cmake] -- Found OpenMP_CXX: -fopenmp (found version "4.5")
[cmake] -- Found OpenMP: TRUE (found version "4.5")
[cmake] -- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components: thread
[cmake] -- boost_prefix = /usr
[cmake] -- Found /usr/include
[cmake] -- Found /usr/lib
[cmake] -- Performing Test compiler_has_conversion_warn
[cmake] -- Performing Test compiler_has_conversion_warn - Success
[cmake] -- compiler_has_conversion_warn = 1
[cmake] -- cppad_boostvector = 0
[cmake] -- cppad_cppadvector = 1
[cmake] -- cppad_eigenvector = 0
[cmake] -- cppad_stdvector = 0
[cmake] -- cppad_cplusplus_201100_ok = 1
[cmake] -- Performing Test cppad_has_gettimeofday
[cmake] -- Performing Test cppad_has_gettimeofday - Success
[cmake] -- cppad_has_gettimeofday = 1
[cmake] -- Performing Test cppad_tape_id_type_is_unsigned
[cmake] -- Performing Test cppad_tape_id_type_is_unsigned - Success
[cmake] -- cppad_tape_id_type_is_unsigned = 1
[cmake] -- Performing Test cppad_tape_addr_type_is_unsigned
[cmake] -- Performing Test cppad_tape_addr_type_is_unsigned - Success
[cmake] -- cppad_tape_addr_type_is_unsigned = 1
[cmake] -- Performing Test cppad_max_num_threads_is_integer_ge_4
[cmake] -- Performing Test cppad_max_num_threads_is_integer_ge_4 - Success
[cmake] -- Performing Test cppad_has_mkstemp
[cmake] -- Performing Test cppad_has_mkstemp - Success
[cmake] -- cppad_has_mkstemp = 1
[cmake] -- Performing Test cppad_has_tmpnam_s
[cmake] -- Performing Test cppad_has_tmpnam_s - Failed
[cmake] -- cppad_has_tmpnam_s = 0
[cmake] -- soversion = 712.8
[cmake] -- Not Windows system so building shared cppad_lib
[cmake] -- make check_example_abs_normal: available
[cmake] -- make check_example_atomic_two: available
[cmake] -- make check_example_atomic_three: available
[cmake] -- make check_example_chkpoint_two: available
[cmake] -- make check_example_graph: available
[cmake] -- make check_example_general: available
[cmake] -- make check_example_get_started: available
[cmake] -- make check_example_json: available
[cmake] -- make check_example_multi_thread_openmp: available
[cmake] -- pthread library path = /usr/lib/x86_64-linux-gnu/libpthread.so
[cmake] -- Looking for pthread_barrier_wait in pthread
[cmake] -- Looking for pthread_barrier_wait in pthread - found
[cmake] -- make check_example_multi_thread_pthread: available
[cmake] -- Performing Test boost_multi_thread_ok
[cmake] -- Performing Test boost_multi_thread_ok - Success
[cmake] -- make check_example_multi_thread_bthread: available
[cmake] -- make check_example_multi_thread: available
[cmake] -- make check_example_optimize: available
[cmake] -- make check_example_print_for: available
[cmake] -- make check_example_sparse: available
[cmake] -- make check_example_utility: available
[cmake] -- make check_example: available
[cmake] -- make check_introduction: available
[cmake] -- make check_test_more_deprecated_atomic_two: available
[cmake] -- make check_test_more_deprecated_chkpoint_one: available
[cmake] -- make check_test_more_deprecated: available
[cmake] -- make check_det_by_minor_c: available
[cmake] -- make check_det_by_minor_cpp: available
[cmake] -- make check_test_more_compare_c: available
[cmake] -- make check_test_more_debug_rel: available
[cmake] -- make check_test_more_cppad_for_tmb: available
[cmake] -- make check_test_more_general: available
[cmake] -- make check_test_more: available
[cmake] -- make check_speed_cppad: available
[cmake] -- make check_speed_double: available
[cmake] -- make check_speed_example: available
[cmake] -- make check_speed_program: available
[cmake] -- make check_speed_xpackage: available
[cmake] -- make check_speed: available
[cmake] -- make check: avialable
[cmake] CMake Error at build/_deps/cppad-src/CMakeLists.txt:452 (ADD_CUSTOM_TARGET):
[cmake] ADD_CUSTOM_TARGET cannot create target "uninstall" because another target
[cmake] with the same name already exists. The existing target is a custom target
[cmake] created in source directory
[cmake] "project/build/_deps/eigen-src". See documentation for
[cmake] policy CMP0002 for more details.
[cmake]
[cmake]
[cmake] -- Fetching cppadcodgen...
[cmake] CMake Deprecation Warning at build/_deps/cppadcodgen-src/CMakeLists.txt:18 (CMAKE_MINIMUM_REQUIRED):
[cmake] Compatibility with CMake < 2.8.12 will be removed from a future version of
[cmake] CMake.
[cmake]
[cmake] Update the VERSION argument <min> value or use a ...<max> suffix to tell
[cmake] CMake that the project does not need compatibility with older versions.
[cmake]
[cmake]
[cmake] CMake Warning (dev) at build/_deps/cppadcodgen-src/CMakeLists.txt:20 (PROJECT):
[cmake] Policy CMP0048 is not set: project() command manages VERSION variables.
[cmake] Run "cmake --help-policy CMP0048" for policy details. Use the cmake_policy
[cmake] command to set the policy and suppress this warning.
[cmake]
[cmake] The following variable(s) would be set to empty:
[cmake]
[cmake] PROJECT_VERSION
[cmake] PROJECT_VERSION_MAJOR
[cmake] PROJECT_VERSION_MINOR
[cmake] PROJECT_VERSION_PATCH
[cmake] This warning is for project developers. Use -Wno-dev to suppress it.
[cmake]
[cmake] -- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
[cmake] -- Found CppAD: project/build/_deps/cppad-src/include (Required is at least version "20200000.1")
[cmake] CMake Error at build/_deps/cppadcodgen-src/cmake/FindCppAD.cmake:86 (FILE):
[cmake] FILE STRINGS file
[cmake] "project/build/_deps/cppadcodgen-src/CPPAD_INCLUDE_DIR-NOTFOUND/cppad/configure.hpp"
[cmake] cannot be read.
[cmake] Call Stack (most recent call first):
[cmake] build/_deps/cppadcodgen-src/CMakeLists.txt:42 (FIND_PACKAGE)
[cmake]
[cmake]
[cmake] CMake Error at build/_deps/cppadcodgen-src/cmake/FindCppAD.cmake:99 (MESSAGE):
[cmake] Found CppAD version '' but at least version '20200000.1' is required
[cmake] Call Stack (most recent call first):
[cmake] build/_deps/cppadcodgen-src/CMakeLists.txt:42 (FIND_PACKAGE)
[cmake]
[cmake]
[cmake] -- Configuring incomplete, errors occurred!
Is anyone able to achieve the above goal on their machine? If yes, would they kindly share how they did it? In the above error messages there are several errors, and I have already tried some solutions, but none of them worked -- I will not list them because they are no use mentioning!
EDIT
@dlivshen When I integrated my library with a bigger project, I had more problems due to conflicting target names. This is because I used FetchContent
to get Eigen. So I decided to obtain it using ExternalProject
, and for this purpose I added these lines to the CMakeLists.txt.in file you proposed in your solution:
ExternalProject_Add(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
CMAKE_CACHE_ARGS
-DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_BINARY_DIR}/eigen
-DEIGEN_BUILD_DOC
OFF
-DBUILD_TESTING
OFF
-DEIGEN_LEAVE_TEST_IN_ALL_TARGET
OFF
-DEIGEN_BUILD_PKGCONFIG
OFF)
Then, in order to use Eigen I have to necessarily add ${CMAKE_BINARY_DIR}/eigen/include/eigen3
to the target_include_directories
command. This is in contrast to when I used FetchContent
whereby I only needed to add Eigen3::Eigen
to the target_link_libraries
command. This approach is not possible with ExternalProject
: is this statement correct? If not, how can I achieve it?
As seen in the output you've provided, there are 2 problems:
CppAD
and eigen
. They both have the uninstall
target. It can be seen here:[cmake] CMake Error at build/_deps/cppad-src/CMakeLists.txt:452 (ADD_CUSTOM_TARGET):
[cmake] ADD_CUSTOM_TARGET cannot create target "uninstall" because another target
[cmake] with the same name already exists. The existing target is a custom target
[cmake] created in source directory
[cmake] "project/build/_deps/eigen-src".
cppadcodgen
requires an already installed version of CppAD
. It can be seen in the error message which tells us that an invalid version was found:[cmake] CMake Error at build/_deps/cppadcodgen-src/cmake/FindCppAD.cmake:99 (MESSAGE):
[cmake] Found CppAD version '' but at least version '20200000.1' is required
[cmake] Call Stack (most recent call first):
[cmake] build/_deps/cppadcodgen-src/CMakeLists.txt:42 (FIND_PACKAGE)
Unfortunately, currently we can't use FetchContent
to deal with those problems, because:
eigen:uninstall
and cppad:uninstall
).Instead we'll use the ExternalProject
module. Here's a possible solution:
include(FetchContent)
message(STATUS "Fetching eigen...")
FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
option(EIGEN_BUILD_DOC OFF)
option(BUILD_TESTING OFF)
option(EIGEN_LEAVE_TEST_IN_ALL_TARGET OFF)
option(EIGEN_BUILD_PKGCONFIG OFF)
FetchContent_MakeAvailable(eigen)
include(ExternalProject)
ExternalProject_Add(cppad
GIT_REPOSITORY https://github.com/coin-or/CppAD.git
GIT_TAG 20210000.8
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
CMAKE_CACHE_ARGS -Dcppad_prefix:STRING=${CMAKE_BINARY_DIR}/cppad
)
ExternalProject_Add(cppadcodgen
GIT_REPOSITORY https://github.com/joaoleal/CppADCodeGen.git
GIT_TAG v2.4.3
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
CMAKE_CACHE_ARGS -DCPPAD_HOME:STRING=${CMAKE_BINARY_DIR}/cppad/include -DGOOGLETEST_GIT:BOOL=ON -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_BINARY_DIR}/cppadcodegen
DEPENDS cppad
)
I used the following commands to test it:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
Most of the parameters are exactly the same as used in FetchContent
. The only differences are:
We install cppad
to the build directory instead of a system wide directory, so the whole process will be self-contained. It is achieved by setting the cppad_prefix
cache variable to ${CMAKE_BINARY_DIR}/cppad
in the CMAKE_CACHE_ARGS
option.
We make sure that cppadcodgen
succeeds finding CppAD
by setting the CPPAD_HOME
cache variable to the include directory (which is ${CMAKE_BINARY_DIR}/cppad/include
) and also setting this target to run after CppAD
is installed using the DEPENDS
option.
cppadcodgen
sets the test targets as well and it will fail if it cannot find Google Test. Fortunately they provide an option to download Google Test using the GOOGLETEST_GIT
option which we set to ON
.
Finally, we set to install cppadcodgen
inside the build directory, by setting CMAKE_INSTALL_PREFIX
variable.
Note that I haven't touched eigen
because I don't know what would be the exact usage and it didn't fail the build. It could be easily modified to be ExternalProject
as written above if needed.
More information on ExternalProject
can be found in Cmake's documentation.
In order to consume the dependencies we have to perform some modifications.
Let's take as example the main file from CppADCodeGen
wiki page and try to compile it with our solution:
main.cpp
#include <iosfwd>
#include <vector>
#include <cppad/cg.hpp>
using namespace CppAD;
using namespace CppAD::cg;
int main() {
// use a special object for source code generation
typedef CG<double> CGD;
typedef AD<CGD> ADCG;
/***************************************************************************
* the model
**************************************************************************/
// independent variable vector
CppAD::vector<ADCG> x(2);
x[0] = 2.;
x[1] = 3.;
Independent(x);
// dependent variable vector
CppAD::vector<ADCG> y(1);
// the model
ADCG a = x[0] / 1. + x[1] * x[1];
y[0] = a / 2;
ADFun<CGD> fun(x, y); // the model tape
/***************************************************************************
* Generate the C source code
**************************************************************************/
/**
* start the special steps for source code generation for a Jacobian
*/
CodeHandler<double> handler;
CppAD::vector<CGD> indVars(2);
handler.makeVariables(indVars);
CppAD::vector<CGD> jac = fun.SparseJacobian(indVars);
LanguageC<double> langC("double");
LangCDefaultVariableNameGenerator<double> nameGen;
std::ostringstream code;
handler.generateCode(code, langC, jac, nameGen);
std::cout << code.str();
}
Note that ExternalProject_Add
command runs on build time, and we would like to find our dependencies already during Cmake reload time. So unfortunately we'll have to do a dirty trick to force ExternalProject_Add
to run on Cmake reload time:
ExternalProject_Add
commands into a helper, CMakeLists.txt.in
file.CMakeLists.txt.in
so the output paths of the libraries will remain inside our build directory.execute_process
(which run on cmake reload time) to execute the build process of the helper CMakeLists.txt.in
ExternalProject
targets' type is utility which can't be used in commands such as target_link_libraries
. So we'll use the custom paths we created for the dependencies and pass them to target_link_libraries
and target_include_directories
commands.The end results are displayed below:
CMakeLists.txt.in
cmake_minimum_required(VERSION 2.8)
project(deps-download NONE)
include(ExternalProject)
ExternalProject_Add(cppad
GIT_REPOSITORY https://github.com/coin-or/CppAD.git
GIT_TAG 20210000.8
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
CMAKE_CACHE_ARGS -Dcppad_prefix:STRING=${CMAKE_BINARY_DIR}/cppad
)
ExternalProject_Add(cppadcodgen
GIT_REPOSITORY https://github.com/joaoleal/CppADCodeGen.git
GIT_TAG v2.4.3
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
CMAKE_CACHE_ARGS -DCPPAD_HOME:STRING=${CMAKE_BINARY_DIR}/cppad/include -DGOOGLETEST_GIT:BOOL=ON -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_BINARY_DIR}/cppadcodegen
DEPENDS cppad
)
CMakeLists.txt
include(FetchContent)
message(STATUS "Fetching eigen...")
FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
option(EIGEN_BUILD_DOC OFF)
option(BUILD_TESTING OFF)
option(EIGEN_LEAVE_TEST_IN_ALL_TARGET OFF)
option(EIGEN_BUILD_PKGCONFIG OFF)
FetchContent_MakeAvailable(eigen)
# Configure the helper CMakeLists with the dependencies
configure_file(CMakeLists.txt.in ${CMAKE_BINARY_DIR}/deps-build/CMakeLists.txt)
# Build it
execute_process(COMMAND ${CMAKE_COMMAND} .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/deps-build)
execute_process(COMMAND ${CMAKE_COMMAND} --build .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/deps-build)
# Find cppad_lib's path
find_library(cppad_lib cppad_lib HINTS ${CMAKE_BINARY_DIR}/cppad/lib REQUIRED)
# Create our target
add_executable(main
main.cpp)
target_link_libraries(main ${cppad_lib})
target_include_directories(main PUBLIC
${CMAKE_BINARY_DIR}/cppad/include
${CMAKE_BINARY_DIR}/cppadcodegen/include)
As before, I used the following commands to test it:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
./main
The solution is based on this post.