# $Id: CMakeLists.txt 3685 2015-05-10 23:17:11Z bradbell $ # ----------------------------------------------------------------------------- # CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell # # CppAD is distributed under multiple licenses. This distribution is under # the terms of the # Eclipse Public License Version 1.0. # # A copy of this license is included in the COPYING file of this distribution. # Please visit http://www.coin-or.org/CppAD/ for information on other licenses. # ----------------------------------------------------------------------------- # Build the cppad/configure.hpp file. # Inherit environment from ../CMakeLists.txt # ----------------------------------------------------------------------------- MACRO(check_match match_variable match_constant output_variable) STRING(COMPARE EQUAL ${${match_variable}} ${match_constant} match_flag ) IF( match_flag ) SET(${output_variable} 1) ELSE( match_flag ) SET(${output_variable} 0) ENDIF( match_flag ) MESSAGE(STATUS "${output_variable} = ${${output_variable}}" ) ENDMACRO(check_match) # ----------------------------------------------------------------------------- # command line arguments # # cppad_testvector command_line_arg(cppad_testvector cppad STRING "Namespace of vector used for testing, one of: boost, cppad, eigen, std" ) # # cppad_max_num_threads command_line_arg(cppad_max_num_threads 48 STRING "maximum number of threads that CppAD can use use" ) # cppad_sparse_list command_line_arg(cppad_sparse_list YES BOOL "use sparse list for internal sparse set representation" ) # # cppad_tape_id_type command_line_arg(cppad_tape_id_type "unsigned int" STRING "type used to identify different tapes, size must be <= sizeof(size_t)" ) # # cppad_tape_addr_type command_line_arg(cppad_tape_addr_type "unsigned int" STRING "type used to identify variables on one tape, size must be <= sizeof(size_t)" ) # # cppad_implicit_ctor_from_any_type command_line_arg(cppad_implicit_ctor_from_any_type NO BOOL "implicit (instead of explicit) conversion from any type to AD" ) # ----------------------------------------------------------------------------- # cppad_explicit_ctor IF( cppad_implicit_ctor_from_any_type ) SET(cppad_implicit_ctor_from_any_type 1) ELSE( cppad_implicit_ctor_from_any_type ) SET(cppad_implicit_ctor_from_any_type 0) ENDIF( cppad_implicit_ctor_from_any_type ) # ----------------------------------------------------------------------------- # cppad_internal_sparse_set # IF( cppad_sparse_list ) SET(cppad_internal_sparse_set sparse_list ) ELSE( cppad_sparse_list ) SET(cppad_internal_sparse_set sparse_set ) ENDIF( cppad_sparse_list ) MESSAGE(STATUS "cppad_internal_sparse_set = ${cppad_internal_sparse_set}" ) # # ----------------------------------------------------------------------------- # cppad_boostvector, cppad_cppadvector, cppad_eigenvector, cppad_stdvector # check_match(cppad_testvector boost cppad_boostvector) check_match(cppad_testvector cppad cppad_cppadvector) check_match(cppad_testvector eigen cppad_eigenvector) check_match(cppad_testvector std cppad_stdvector) IF( NOT cppad_boostvector ) IF( NOT cppad_cppadvector ) IF( NOT cppad_eigenvector ) IF( NOT cppad_stdvector ) MESSAGE(FATAL_ERROR "cppad_testvector not one of following: boost, cppad, eigen, std." ) ENDIF( NOT cppad_stdvector ) ENDIF( NOT cppad_eigenvector ) ENDIF( NOT cppad_cppadvector ) ENDIF( NOT cppad_boostvector ) IF( cppad_boostvector ) # FIND_PACKAGE(Boost) done by ../CMakeLists.txt IF( NOT Boost_FOUND ) MESSAGE(FATAL_ERROR "cppad_testvector == boost but cannot find boost include files" ) ENDIF( NOT Boost_FOUND ) ENDIF( cppad_boostvector ) # IF( cppad_eigenvector ) IF( NOT eigen_prefix ) MESSAGE(FATAL_ERROR "cppad_testvector == eigen but eigen_prefix is not specified" ) ENDIF( NOT eigen_prefix ) ENDIF( cppad_eigenvector ) # ============================================================================= # Begin C++11 features # SET(cppad_cplusplus_201100_ok 1) # ----------------------------------------------------------------------------- # cppad_has_rvalue # SET(source " int main(void) { int&& value = 1 + 2; if( value != 3 ) return 1; return 0; }" ) check_source_runs("${source}" cppad_has_rvalue) IF( NOT cppad_has_rvalue ) SET(cppad_cplusplus_201100_ok 0) ENDIF( NOT cppad_has_rvalue ) # ----------------------------------------------------------------------------- # cppad_has_nullptr # SET(source " int main(void) { char *c = nullptr; return 0; }" ) check_source_runs("${source}" cppad_has_nullptr) IF( NOT cppad_has_nullptr ) SET(cppad_cplusplus_201100_ok 0) ENDIF( NOT cppad_has_nullptr ) # ----------------------------------------------------------------------------- # cppad_has_cstdint_8_to_64 # SET(source " # include template inline bool is_pod(void) { return false; } template <> inline bool is_pod(void) { return true; } template <> inline bool is_pod(void) { return true; } template <> inline bool is_pod(void) { return true; } template <> inline bool is_pod(void) { return true; } int main(void) { return 0; } " ) check_source_runs("${source}" cppad_has_cstdint_8_to_64) IF( NOT cppad_has_cstdint_8_to_64 ) SET(cppad_cplusplus_201100_ok 0) ENDIF( NOT cppad_has_cstdint_8_to_64 ) # ----------------------------------------------------------------------------- # cppad_compiler_has_erf # cppad_compiler_has_asinh # cppad_compiler_has_acosh # cppad_compiler_has_atanh # cppad_compiler_has_expm1 # SET(source_template " # include int main(void) { std::c11_function(0.0); return 0; } " ) FOREACH(c11_function erf asinh acosh atanh expm1 log1p) STRING(REPLACE "c11_function" ${c11_function} source "${source_template}" ) # really only checking if program compiles check_source_runs("${source}" cppad_compiler_has_${c11_function} ) IF( NOT cppad_compiler_has_${c11_function} ) SET(cppad_cplusplus_201100_ok 0) ENDIF( NOT cppad_compiler_has_${c11_function} ) ENDFOREACH(c11_function) # ----------------------------------------------------------------------------- # cppad_has_high_resolution_clock # SET(source " # include int main(void) { std::chrono::time_point start, end; start = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now(); std::chrono::duration difference = end - start; double elapsed_seconds = difference.count(); if( elapsed_seconds > 0.0 ) return 0; return 1; } " ) check_source_runs("${source}" cppad_has_high_resolution_clock) IF( NOT cppad_has_high_resolution_clock ) SET(cppad_cplusplus_201100_ok 0) ENDIF( NOT cppad_has_high_resolution_clock ) # ============================================================================= # End C++11 features # MESSAGE(STATUS "cppad_cplusplus_201100_ok = ${cppad_cplusplus_201100_ok}") # ----------------------------------------------------------------------------- # cppad_has_gettimeofday # SET(source " # include int main(void) { struct timeval time; gettimeofday(&time, 0); return 0; }" ) check_source_runs("${source}" cppad_has_gettimeofday) # ----------------------------------------------------------------------------- # cppad_size_t_not_unsigned_int # SET(source " # include template inline bool is_pod(void) { return false; } template <> inline bool is_pod(void) { return true; } template <> inline bool is_pod(void) { return true; } int main(void) { return 0; } " ) check_source_runs("${source}" cppad_size_t_not_unsigned_int) # ----------------------------------------------------------------------------- # cppad_tape_addr_type, cppad_tape_id_type # FOREACH(cmake_var cppad_tape_id_type cppad_tape_addr_type ) SET(source " # include int main(void) { bool is_unsigned = ! std::numeric_limits<${${cmake_var}}>::is_signed; return int(! is_unsigned); } " ) check_source_runs("${source}" ${cmake_var}_is_unsigned) IF( ${cmake_var}_is_unsigned STREQUAL 0 ) MESSAGE(STATUS "Warning: using a signed ${cmake_var} is for CppAD developers only !" ) ENDIF( ${cmake_var}_is_unsigned STREQUAL 0 ) ENDFOREACH( cmake_var ) # ----------------------------------------------------------------------------- # cppad_max_num_threads # SET(CMAKE_REQUIRED_INCLUDES "") SET(CMAKE_REQUIRED_LIBRARIES "") SET(CMAKE_REQUIRED_FLAGS ) SET(source " int main(void) { const char* number = \"${cppad_max_num_threads}\"; int value = 0; while( *number == ' ' ) number++; while( '0' <= *number && *number <= '9' ) { value = 10 * value + (int)(*number - '0'); number++; } while( *number == ' ' ) number++; if( *number != char(0) ) return 1; if( value < 4 ) return 1; return 0; } " ) CHECK_CXX_SOURCE_RUNS("${source}" cppad_max_num_threads_is_integer_ge_4) IF( NOT cppad_max_num_threads_is_integer_ge_4 ) MESSAGE(FATAL_ERROR "cppad_max_num_threads is not an integer greater than or equal 4" ) ENDIF( NOT cppad_max_num_threads_is_integer_ge_4 ) # ----------------------------------------------------------------------------- # Copy a file to another location and modify its contents. # configure_file(InputFile OutputFile [COPYONLY] [ESCAPE_QUOTES] [@ONLY]) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/configure.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/configure.hpp )