将 CppADCodeGen 与 CMake FetchContent 或 ExternalProject 结合使用
Use CppADCodeGen with CMake FetchContent or ExternalProject
我不擅长 CMake,我找不到关于如何使用它的 FetchContent
功能的好的解释。事实上,大多数存储库似乎需要不同的处理方式,而这种处理方式的规则让我无法理解。
也就是说,这是我的问题。我想在我使用 CMake FetchContent
的项目中使用 CppADCodeGen。这是我的代码:
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)
这是输出和我得到的错误:
[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!
有人能在他们的机器上实现上述目标吗?如果是,他们会分享他们是如何做到的吗? 在上面的错误消息中有几个错误,我已经尝试了一些解决方案,但是 none 其中有效 - 我不会列出他们,因为他们提了也没用!
编辑
@dlivshen 当我将我的库与一个更大的项目集成时,由于目标名称冲突,我遇到了更多问题。这是因为我用FetchContent
得到了Eigen。所以我决定使用 ExternalProject
获取它,为此我将这些行添加到您在解决方案中提出的 CMakeLists.txt.in 文件中:
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)
然后,为了使用 Eigen,我必须将 ${CMAKE_BINARY_DIR}/eigen/include/eigen3
添加到 target_include_directories
命令中。这与我使用 FetchContent
时形成对比,我只需要将 Eigen3::Eigen
添加到 target_link_libraries
命令。 这种方法不适用于 ExternalProject
:这个说法正确吗?如果没有,我该如何实现?
问题概述
如您提供的输出所示,存在 2 个问题:
- 可能
CppAD
和 eigen
之间存在目标名称冲突。他们都有 uninstall
目标。可以在这里看到:
[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
需要已安装的 CppAD
版本。可以在告诉我们发现无效版本的错误消息中看到:
[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)
解决方案
很遗憾,目前我们无法使用 FetchContent
来处理这些问题,因为:
- 没有任何机制可以让我们区分相互冲突的目标(例如,“命名空间”前缀可能是一个解决方案,然后可能有 2 个目标
eigen:uninstall
和 cppad:uninstall
)。
- 我们无法在配置步骤中构建依赖目标。
我们将使用 ExternalProject
模块。这是一个可能的解决方案:
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
)
我使用以下命令对其进行测试:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
说明
大部分参数与FetchContent
中使用的完全相同。唯一的区别是:
我们将 cppad
安装到构建目录而不是系统目录,因此整个过程将是独立的。它是通过在 CMAKE_CACHE_ARGS
选项中将 cppad_prefix
缓存变量设置为 ${CMAKE_BINARY_DIR}/cppad
来实现的。
我们通过将 CPPAD_HOME
缓存变量设置为包含目录(即 ${CMAKE_BINARY_DIR}/cppad/include
)来确保 cppadcodgen
成功找到 CppAD
,并且在使用 DEPENDS
选项安装 CppAD
之后,还将此目标设置为 运行。
cppadcodgen
也设置了测试目标,如果找不到 Google 测试就会失败。幸运的是,他们提供了一个选项,可以使用我们设置为 ON
.
的 GOOGLETEST_GIT
选项下载 Google 测试
最后,我们通过设置 CMAKE_INSTALL_PREFIX
变量来设置在构建目录中安装 cppadcodgen
。
请注意,我没有触及 eigen
,因为我不知道确切的用法是什么,而且它没有使构建失败。如果需要,可以很容易地将其修改为 ExternalProject
,如上所述。
有关 ExternalProject
的更多信息可以在 Cmake 的 documentation 中找到。
使用依赖项
为了使用依赖项,我们必须执行一些修改。
让我们以来自 CppADCodeGen
wiki page 的主文件为例,并尝试用我们的解决方案编译它:
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();
}
请注意 ExternalProject_Add
命令 运行 在构建时执行,我们希望在 Cmake 重新加载期间找到我们的依赖项。所以不幸的是,我们将不得不做一个卑鄙的把戏,在 Cmake 重新加载时强制 ExternalProject_Add
到 运行:
- 我们会将
ExternalProject_Add
命令移动到帮助程序 CMakeLists.txt.in
文件中。
- 我们将配置
CMakeLists.txt.in
以便库的输出路径将保留在我们的构建目录中。
- 我们将调用
execute_process
(在 cmake 重新加载时 运行)来执行助手 CMakeLists.txt.in
的构建过程
- 我们将找到我们的库并使用它们。请注意,我们不能使用现代 Cmake 目标语法,因为整个过程在子过程中 运行 并且我们无权访问创建的目标。但是即使我们没有在子进程中 运行 它,
ExternalProject
目标的类型是实用程序,不能在 target_link_libraries
等命令中使用。因此,我们将使用我们为依赖项创建的自定义路径并将它们传递给 target_link_libraries
和 target_include_directories
命令。
最终结果显示如下:
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)
和以前一样,我使用以下命令对其进行测试:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
./main
解决方案基于this post.
我不擅长 CMake,我找不到关于如何使用它的 FetchContent
功能的好的解释。事实上,大多数存储库似乎需要不同的处理方式,而这种处理方式的规则让我无法理解。
也就是说,这是我的问题。我想在我使用 CMake FetchContent
的项目中使用 CppADCodeGen。这是我的代码:
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)
这是输出和我得到的错误:
[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!
有人能在他们的机器上实现上述目标吗?如果是,他们会分享他们是如何做到的吗? 在上面的错误消息中有几个错误,我已经尝试了一些解决方案,但是 none 其中有效 - 我不会列出他们,因为他们提了也没用!
编辑
@dlivshen 当我将我的库与一个更大的项目集成时,由于目标名称冲突,我遇到了更多问题。这是因为我用FetchContent
得到了Eigen。所以我决定使用 ExternalProject
获取它,为此我将这些行添加到您在解决方案中提出的 CMakeLists.txt.in 文件中:
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)
然后,为了使用 Eigen,我必须将 ${CMAKE_BINARY_DIR}/eigen/include/eigen3
添加到 target_include_directories
命令中。这与我使用 FetchContent
时形成对比,我只需要将 Eigen3::Eigen
添加到 target_link_libraries
命令。 这种方法不适用于 ExternalProject
:这个说法正确吗?如果没有,我该如何实现?
问题概述
如您提供的输出所示,存在 2 个问题:
- 可能
CppAD
和eigen
之间存在目标名称冲突。他们都有uninstall
目标。可以在这里看到:
[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
需要已安装的CppAD
版本。可以在告诉我们发现无效版本的错误消息中看到:
[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)
解决方案
很遗憾,目前我们无法使用 FetchContent
来处理这些问题,因为:
- 没有任何机制可以让我们区分相互冲突的目标(例如,“命名空间”前缀可能是一个解决方案,然后可能有 2 个目标
eigen:uninstall
和cppad:uninstall
)。 - 我们无法在配置步骤中构建依赖目标。
我们将使用 ExternalProject
模块。这是一个可能的解决方案:
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
)
我使用以下命令对其进行测试:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
说明
大部分参数与FetchContent
中使用的完全相同。唯一的区别是:
我们将
cppad
安装到构建目录而不是系统目录,因此整个过程将是独立的。它是通过在CMAKE_CACHE_ARGS
选项中将cppad_prefix
缓存变量设置为${CMAKE_BINARY_DIR}/cppad
来实现的。我们通过将
CPPAD_HOME
缓存变量设置为包含目录(即${CMAKE_BINARY_DIR}/cppad/include
)来确保cppadcodgen
成功找到CppAD
,并且在使用DEPENDS
选项安装CppAD
之后,还将此目标设置为 运行。
的cppadcodgen
也设置了测试目标,如果找不到 Google 测试就会失败。幸运的是,他们提供了一个选项,可以使用我们设置为ON
.GOOGLETEST_GIT
选项下载 Google 测试最后,我们通过设置
CMAKE_INSTALL_PREFIX
变量来设置在构建目录中安装cppadcodgen
。
请注意,我没有触及 eigen
,因为我不知道确切的用法是什么,而且它没有使构建失败。如果需要,可以很容易地将其修改为 ExternalProject
,如上所述。
有关 ExternalProject
的更多信息可以在 Cmake 的 documentation 中找到。
使用依赖项
为了使用依赖项,我们必须执行一些修改。
让我们以来自 CppADCodeGen
wiki page 的主文件为例,并尝试用我们的解决方案编译它:
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();
}
请注意 ExternalProject_Add
命令 运行 在构建时执行,我们希望在 Cmake 重新加载期间找到我们的依赖项。所以不幸的是,我们将不得不做一个卑鄙的把戏,在 Cmake 重新加载时强制 ExternalProject_Add
到 运行:
- 我们会将
ExternalProject_Add
命令移动到帮助程序CMakeLists.txt.in
文件中。 - 我们将配置
CMakeLists.txt.in
以便库的输出路径将保留在我们的构建目录中。 - 我们将调用
execute_process
(在 cmake 重新加载时 运行)来执行助手CMakeLists.txt.in
的构建过程
- 我们将找到我们的库并使用它们。请注意,我们不能使用现代 Cmake 目标语法,因为整个过程在子过程中 运行 并且我们无权访问创建的目标。但是即使我们没有在子进程中 运行 它,
ExternalProject
目标的类型是实用程序,不能在target_link_libraries
等命令中使用。因此,我们将使用我们为依赖项创建的自定义路径并将它们传递给target_link_libraries
和target_include_directories
命令。
最终结果显示如下:
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)
和以前一样,我使用以下命令对其进行测试:
mkdir cmake-build
cd !$
cmake ..
cmake --build .
./main
解决方案基于this post.