diff options
Diffstat (limited to 'Modules')
57 files changed, 2167 insertions, 654 deletions
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 602b065..7d89420 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -1,5 +1,6 @@ set(AM_SOURCES @_cpp_files@ ) set(AM_RCC_SOURCES @_rcc_files@ ) +set(AM_RCC_INPUTS @_qt_rcc_inputs@) set(AM_SKIP_MOC @_skip_moc@ ) set(AM_SKIP_UIC @_skip_uic@ ) set(AM_HEADERS @_moc_headers@ ) diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 6b425c6..937aa8c 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -108,7 +108,7 @@ if(NOT CMAKE_C_COMPILER_ID_RUN) CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c) # Set old compiler and platform id variables. - if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") set(CMAKE_COMPILER_IS_GNUCC 1) endif() if("${CMAKE_C_PLATFORM_ID}" MATCHES "MinGW") @@ -131,11 +131,11 @@ endif () # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-" if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) - if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) - elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_C_COMPILER_TARGET) set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-) endif() @@ -150,7 +150,7 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) endif () - elseif("${CMAKE_C_COMPILER_ID}" MATCHES "TI") + elseif(CMAKE_C_COMPILER_ID MATCHES "TI") # TI compilers are named e.g. cl6x, cl470 or armcl.exe get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$") diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake index 0ab3af6..85c8662 100644 --- a/Modules/CMakeDetermineCompiler.cmake +++ b/Modules/CMakeDetermineCompiler.cmake @@ -71,16 +71,31 @@ macro(_cmake_find_compiler lang) unset(_languages) # Look for a make tool provided by Xcode - if(CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND" AND CMAKE_HOST_APPLE) - foreach(comp ${CMAKE_${lang}_COMPILER_LIST}) - execute_process(COMMAND xcrun --find ${comp} + if(CMAKE_HOST_APPLE) + macro(_query_xcrun compiler_name result_var_keyword result_var) + if(NOT "x${result_var_keyword}" STREQUAL "xRESULT_VAR") + message(FATAL_ERROR "Bad arguments to macro") + endif() + execute_process(COMMAND xcrun --find ${compiler_name} OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE _xcrun_err) - if(_xcrun_out) - set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${_xcrun_out}") - break() - endif() - endforeach() + set("${result_var}" "${_xcrun_out}") + endmacro() + + set(xcrun_result) + if (CMAKE_${lang}_COMPILER MATCHES "^/usr/bin/(.+)$") + _query_xcrun("${CMAKE_MATCH_1}" RESULT_VAR xcrun_result) + elseif (CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND") + foreach(comp ${CMAKE_${lang}_COMPILER_LIST}) + _query_xcrun("${comp}" RESULT_VAR xcrun_result) + if(xcrun_result) + break() + endif() + endforeach() + endif() + if (xcrun_result) + set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${xcrun_result}") + endif() endif() endmacro() diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index 4bc42dd..344ae47 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -26,7 +26,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin") set(CMAKE_FLAGS ) if(DEFINED CMAKE_${lang}_VERBOSE_FLAG) - set(CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}") + set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}") endif() if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") # Avoid adding our own platform standard libraries for compilers diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 8702138..dfed00e 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -48,7 +48,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang}) endif() - if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL GNU) + if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU") execute_process( COMMAND "${CMAKE_${lang}_COMPILER}" -V diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index 96df6a2..a4bb86c 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -152,12 +152,12 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN) endif() # Set old compiler and platform id variables. - if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU") + if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") set(CMAKE_COMPILER_IS_GNUG77 1) endif() - if("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "MinGW") + if(CMAKE_Fortran_PLATFORM_ID MATCHES "MinGW") set(CMAKE_COMPILER_IS_MINGW 1) - elseif("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "Cygwin") + elseif(CMAKE_Fortran_PLATFORM_ID MATCHES "Cygwin") set(CMAKE_COMPILER_IS_CYGWIN 1) endif() endif() @@ -175,7 +175,7 @@ endif () # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-" if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) - if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU") + if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)g?fortran(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake index 365d381..064e650 100644 --- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake +++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake @@ -26,11 +26,18 @@ macro(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines if (${_lang} STREQUAL "c++") set(_compilerExecutable "${CMAKE_CXX_COMPILER}") set(_arg1 "${CMAKE_CXX_COMPILER_ARG1}") + + if (CMAKE_CXX_FLAGS MATCHES "(-stdlib=[^ ]+)") + set(_stdlib "${CMAKE_MATCH_1}") + endif () + if (CMAKE_CXX_FLAGS MATCHES "(-std=[^ ]+)") + set(_stdver "${CMAKE_MATCH_1}") + endif () else () set(_compilerExecutable "${CMAKE_C_COMPILER}") set(_arg1 "${CMAKE_C_COMPILER_ARG1}") endif () - execute_process(COMMAND ${_compilerExecutable} ${_arg1} -v -E -x ${_lang} -dD dummy + execute_process(COMMAND ${_compilerExecutable} ${_arg1} ${_stdver} ${_stdlib} -v -E -x ${_lang} -dD dummy WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles ERROR_VARIABLE _gccOutput OUTPUT_VARIABLE _gccStdout ) @@ -90,7 +97,7 @@ set(ENV{LANG} C) # Now check for C, works for gcc and Intel compiler at least if (NOT CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS) - if ("${CMAKE_C_COMPILER_ID}" MATCHES GNU OR "${CMAKE_C_COMPILER_ID}" MATCHES Intel OR "${CMAKE_C_COMPILER_ID}" MATCHES Clang) + if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Intel OR CMAKE_C_COMPILER_ID MATCHES Clang) _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c _dirs _defines) set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "C compiler system include directories") set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "C compiler system defined macros") diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake index 0e6b5af..1d8b110 100644 --- a/Modules/CMakeForceCompiler.cmake +++ b/Modules/CMakeForceCompiler.cmake @@ -70,7 +70,7 @@ macro(CMAKE_FORCE_C_COMPILER compiler id) set(CMAKE_C_COMPILER_FORCED TRUE) # Set old compiler id variables. - if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") set(CMAKE_COMPILER_IS_GNUCC 1) endif() endmacro() @@ -94,7 +94,7 @@ macro(CMAKE_FORCE_Fortran_COMPILER compiler id) set(CMAKE_Fortran_COMPILER_FORCED TRUE) # Set old compiler id variables. - if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU") + if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") set(CMAKE_COMPILER_IS_GNUG77 1) endif() endmacro() diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake index c3ca767..2f35cf4 100644 --- a/Modules/CMakeNinjaFindMake.cmake +++ b/Modules/CMakeNinjaFindMake.cmake @@ -12,6 +12,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_program(CMAKE_MAKE_PROGRAM ninja +find_program(CMAKE_MAKE_PROGRAM + NAMES ninja-build ninja DOC "Program used to build from build.ninja files.") mark_as_advanced(CMAKE_MAKE_PROGRAM) diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake index d8293c0..d26a0b3 100644 --- a/Modules/CPackBundle.cmake +++ b/Modules/CPackBundle.cmake @@ -33,6 +33,31 @@ # Path to a startup script. This is a path to an executable or script that # will be run whenever an end-user double-clicks the generated bundle in the # OSX Finder. Optional. +# +# .. variable:: CPACK_BUNDLE_APPLE_CERT_APP +# +# The name of your Apple supplied code signing certificate for the application. +# The name usually takes the form "Developer ID Application: [Name]" or +# "3rd Party Mac Developer Application: [Name]". If this variable is not set +# the application will not be signed. +# +# .. variable:: CPACK_BUNDLE_APPLE_ENTITLEMENTS +# +# The name of the plist file that contains your apple entitlements for sandboxing +# your application. This file is required for submission to the Mac App Store. +# +# .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_FILES +# +# A list of additional files that you wish to be signed. You do not need to +# list the main application folder, or the main executable. You should +# list any frameworks and plugins that are included in your app bundle. +# +# .. variable:: CPACK_COMMAND_CODESIGN +# +# Path to the codesign(1) command used to sign applications with an +# Apple cert. This variable can be used to override the automatically +# detected command (or specify its location if the auto-detection fails +# to find it.) #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index 2864b21..d2cb2ee 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -29,6 +29,7 @@ # However as a handy reminder here comes the list of specific variables: # # .. variable:: CPACK_RPM_PACKAGE_SUMMARY +# CPACK_RPM_<component>_PACKAGE_SUMMARY # # The RPM package summary. # @@ -100,11 +101,13 @@ # * Default : - # # .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION +# CPACK_RPM_<component>_PACKAGE_DESCRIPTION # # RPM package description. # # * Mandatory : YES -# * Default : CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package +# * Default : CPACK_COMPONENT_<compName>_DESCRIPTION (component based installers +# only) if set, CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package # description available" # # .. variable:: CPACK_RPM_COMPRESSION_TYPE @@ -135,6 +138,56 @@ # # rpm -qp --requires file.rpm # +# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PRE +# +# RPM spec requires(pre) field. +# +# * Mandatory : NO +# * Default : - +# +# May be used to set RPM preinstall dependencies (requires(pre)). Note that you must enclose +# the complete requires string between quotes, for example:: +# +# set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils, initscripts") +# +# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POST +# +# RPM spec requires(post) field. +# +# * Mandatory : NO +# * Default : - +# +# May be used to set RPM postinstall dependencies (requires(post)). Note that you must enclose +# the complete requires string between quotes, for example:: +# +# set(CPACK_RPM_PACKAGE_REQUIRES_POST "shadow-utils, initscripts") +# +# +# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POSTUN +# +# RPM spec requires(postun) field. +# +# * Mandatory : NO +# * Default : - +# +# May be used to set RPM postuninstall dependencies (requires(postun)). Note that you must enclose +# the complete requires string between quotes, for example:: +# +# set(CPACK_RPM_PACKAGE_REQUIRES_POSTUN "shadow-utils, initscripts") +# +# +# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PREUN +# +# RPM spec requires(preun) field. +# +# * Mandatory : NO +# * Default : - +# +# May be used to set RPM preuninstall dependencies (requires(preun)). Note that you must enclose +# the complete requires string between quotes, for example:: +# +# set(CPACK_RPM_PACKAGE_REQUIRES_PREUN "shadow-utils, initscripts") +# # .. variable:: CPACK_RPM_PACKAGE_SUGGESTS # # RPM spec suggest field. @@ -384,7 +437,7 @@ if(CPACK_RPM_PACKAGE_DEBUG) OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REPLACE "\n" ", " + string(REGEX REPLACE "\n" ", " LSB_RELEASE_OUTPUT ${_TMP_LSB_RELEASE_OUTPUT}) else () @@ -397,7 +450,7 @@ endif() # to shut down warning about space in buildtree # some recent RPM version should support space in different places. # not checked [yet]. -if(CPACK_TOPLEVEL_DIRECTORY MATCHES " ") +if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*") message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.") endif() @@ -414,6 +467,7 @@ endif() # Are we packaging components ? if(CPACK_RPM_PACKAGE_COMPONENT) set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") + string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) else() set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "") endif() @@ -430,12 +484,31 @@ set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACK # # CPACK_RPM_PACKAGE_SUMMARY (mandatory) + +# CPACK_RPM_PACKAGE_SUMMARY_ is used only locally so that it can be unset each time before use otherwise +# component packaging could leak variable content between components +unset(CPACK_RPM_PACKAGE_SUMMARY_) +if(CPACK_RPM_PACKAGE_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY_ ${CPACK_RPM_PACKAGE_SUMMARY}) + unset(CPACK_RPM_PACKAGE_SUMMARY) +endif() + +#Check for component summary first. +#If not set, it will use regular package summary logic. +if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY}) + endif() +endif() + if(NOT CPACK_RPM_PACKAGE_SUMMARY) - # if neither var is defined lets use the name as summary - if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) - string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) - else() + if(CPACK_RPM_PACKAGE_SUMMARY_) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) + elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY) set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + else() + # if neither var is defined lets use the name as summary + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) endif() endif() @@ -508,12 +581,33 @@ endif() # if it is defined # - set to a default value # -if (NOT CPACK_RPM_PACKAGE_DESCRIPTION) - if (CPACK_PACKAGE_DESCRIPTION_FILE) - file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION) - else () - set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available") - endif () + +# CPACK_RPM_PACKAGE_DESCRIPTION_ is used only locally so that it can be unset each time before use otherwise +# component packaging could leak variable content between components +unset(CPACK_RPM_PACKAGE_DESCRIPTION_) +if(CPACK_RPM_PACKAGE_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION_ ${CPACK_RPM_PACKAGE_DESCRIPTION}) + unset(CPACK_RPM_PACKAGE_DESCRIPTION) +endif() + +#Check for a component description first. +#If not set, it will use regular package description logic. +if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION}) + elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION}) + endif() +endif() + +if(NOT CPACK_RPM_PACKAGE_DESCRIPTION) + if(CPACK_RPM_PACKAGE_DESCRIPTION_) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) + elseif(CPACK_PACKAGE_DESCRIPTION_FILE) + file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION) + else () + set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available") + endif () endif () # CPACK_RPM_COMPRESSION_TYPE @@ -556,7 +650,7 @@ endif() # There may be some COMPONENT specific variables as well # If component specific var is not provided we use the global one # for each component -foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV) +foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) if(CPACK_RPM_PACKAGE_DEBUG) message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}") endif() @@ -584,24 +678,29 @@ foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLIC endif() endif() + # Do not forget to unset previously set header (from previous component) + unset(TMP_RPM_${_RPM_SPEC_HEADER}) # Treat the RPM Spec keyword iff it has been properly defined if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) # Transform NAME --> Name e.g. PROVIDES --> Provides # The Upper-case first letter and lowercase tail is the # appropriate value required in the final RPM spec file. - string(LENGTH ${_RPM_SPEC_HEADER} _PACKAGE_HEADER_STRLENGTH) - math(EXPR _PACKAGE_HEADER_STRLENGTH "${_PACKAGE_HEADER_STRLENGTH} - 1") - string(SUBSTRING ${_RPM_SPEC_HEADER} 1 ${_PACKAGE_HEADER_STRLENGTH} _PACKAGE_HEADER_TAIL) + string(SUBSTRING ${_RPM_SPEC_HEADER} 1 -1 _PACKAGE_HEADER_TAIL) string(TOLOWER "${_PACKAGE_HEADER_TAIL}" _PACKAGE_HEADER_TAIL) string(SUBSTRING ${_RPM_SPEC_HEADER} 0 1 _PACKAGE_HEADER_NAME) set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}${_PACKAGE_HEADER_TAIL}") + # The following keywords require parentheses around the "pre" or "post" suffix in the final RPM spec file. + set(SCRIPTS_REQUIREMENTS_LIST REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + list(FIND SCRIPTS_REQUIREMENTS_LIST ${_RPM_SPEC_HEADER} IS_SCRIPTS_REQUIREMENT_FOUND) + if(NOT ${IS_SCRIPTS_REQUIREMENT_FOUND} EQUAL -1) + string(REPLACE "_" "(" _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}") + set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME})") + endif() if(CPACK_RPM_PACKAGE_DEBUG) message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") endif() set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") - else() - # Do not forget to unset previously set header (from previous component) - unset(TMP_RPM_${_RPM_SPEC_HEADER}) + unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) endif() endforeach() @@ -991,6 +1090,10 @@ Group: \@CPACK_RPM_PACKAGE_GROUP\@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ \@TMP_RPM_URL\@ \@TMP_RPM_REQUIRES\@ +\@TMP_RPM_REQUIRES_PRE\@ +\@TMP_RPM_REQUIRES_POST\@ +\@TMP_RPM_REQUIRES_PREUN\@ +\@TMP_RPM_REQUIRES_POSTUN\@ \@TMP_RPM_PROVIDES\@ \@TMP_RPM_OBSOLETES\@ \@TMP_RPM_CONFLICTS\@ @@ -1100,3 +1203,15 @@ else() message(FATAL_ERROR "RPM packaging through alien not done (yet)") endif() endif() + +# reset variables from temporary variables +if(CPACK_RPM_PACKAGE_SUMMARY_) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) +else() + unset(CPACK_RPM_PACKAGE_SUMMARY) +endif() +if(CPACK_RPM_PACKAGE_DESCRIPTION_) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) +else() + unset(CPACK_RPM_PACKAGE_DESCRIPTION) +endif() diff --git a/Modules/CheckStructHasMember.cmake b/Modules/CheckStructHasMember.cmake index c8949cf..de31d2c 100644 --- a/Modules/CheckStructHasMember.cmake +++ b/Modules/CheckStructHasMember.cmake @@ -69,8 +69,7 @@ macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT) ${_INCLUDE_FILES} int main() { - ${_STRUCT}* tmp; - (void) tmp->${_MEMBER}; + (void)((${_STRUCT} *)0)->${_MEMBER}; return 0; } ") diff --git a/Modules/Compiler/AppleClang-C-FeatureTests.cmake b/Modules/Compiler/AppleClang-C-FeatureTests.cmake new file mode 100644 index 0000000..6f3d6a7 --- /dev/null +++ b/Modules/Compiler/AppleClang-C-FeatureTests.cmake @@ -0,0 +1,11 @@ + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400") + +set(AppleClang_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L") +set(_cmake_feature_test_c_static_assert "${AppleClang_C11}") +set(AppleClang_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L") +set(_cmake_feature_test_c_restrict "${AppleClang_C99}") +set(_cmake_feature_test_c_variadic_macros "${AppleClang_C99}") + +set(AppleClang_C90 "${_cmake_oldestSupported} && !defined(__STDC_VERSION__)") +set(_cmake_feature_test_c_function_prototypes "${AppleClang_C90}") diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake index 98fcd0b..16f420f 100644 --- a/Modules/Compiler/AppleClang-C.cmake +++ b/Modules/Compiler/AppleClang-C.cmake @@ -1,2 +1,32 @@ include(Compiler/Clang) __compiler_clang(C) + +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") + + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") +endif() + +set(CMAKE_C_STANDARD_DEFAULT 99) + +macro(cmake_record_c_compile_features) + macro(_get_appleclang_features std_version list) + record_compiler_features(C "${std_version}" ${list}) + endmacro() + + set(_result 0) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) + _get_appleclang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) + endif() + endif() +endmacro() diff --git a/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake new file mode 100644 index 0000000..f67082c --- /dev/null +++ b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake @@ -0,0 +1,52 @@ + +# No known reference for AppleClang versions. +# Generic reference: http://clang.llvm.org/cxx_status.html +# http://clang.llvm.org/docs/LanguageExtensions.html + +# Note: CXX compiler in Xcode 4.3 does not set __apple_build_version__ and so is +# not recognized as AppleClang. +# Xcode_43 - Apple clang version 3.1 (tags/Apple/clang-318.0.61) (based on LLVM 3.1svn) +# Xcode_44 - Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn) +# Xcode_45 - Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) +# Xcode_46 - Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) +# Xcode_50 - Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) +# Xcode_51 - Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn) +# Xcode_60 - Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn) +# Xcode_61 - Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) + +# There is some non-correspondance. __has_feature(cxx_user_literals) is +# false for AppleClang 4.0 and 4.1, although it is reported as +# supported in the reference link for Clang 3.1. The compiler does not pass +# the CompileFeatures/cxx_user_literals.cpp test. +# cxx_attributes is listed as not supported until Clang 3.3. It works without +# warning with AppleClang 5.0, but issues a gcc-compat warning for +# AppleClang 4.0-4.2. +# cxx_alignof and cxx_alignas tests work for early AppleClang versions, though +# they are listed as supported for Clang 3.3 and later. + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400") + +include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake") + +set(AppleClang51_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 501 && __cplusplus > 201103L") +# http://llvm.org/bugs/show_bug.cgi?id=19242 +set(_cmake_feature_test_cxx_attribute_deprecated "${AppleClang51_CXX14}") +# http://llvm.org/bugs/show_bug.cgi?id=19698 +set(_cmake_feature_test_cxx_decltype_auto "${AppleClang51_CXX14}") +set(_cmake_feature_test_cxx_digit_separators "${AppleClang51_CXX14}") +# http://llvm.org/bugs/show_bug.cgi?id=19674 +set(_cmake_feature_test_cxx_generic_lambdas "${AppleClang51_CXX14}") + +set(AppleClang40_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_enum_forward_declarations "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_sizeof_member "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_extended_friend_declarations "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_extern_templates "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_func_identifier "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_inline_namespaces "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_long_long_type "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_right_angle_brackets "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_variadic_macros "${AppleClang40_CXX11}") + +set(AppleClang_CXX98 "${_cmake_oldestSupported} && __cplusplus >= 199711L") +set(_cmake_feature_test_cxx_template_template_parameters "${AppleClang_CXX98}") diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake index c1acae6..978c382 100644 --- a/Modules/Compiler/AppleClang-CXX.cmake +++ b/Modules/Compiler/AppleClang-CXX.cmake @@ -4,3 +4,39 @@ __compiler_clang(CXX) if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") + + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") +endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) + # AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") +endif() + +set(CMAKE_CXX_STANDARD_DEFAULT 98) + +macro(cmake_record_cxx_compile_features) + macro(_get_appleclang_features std_version list) + record_compiler_features(CXX "${std_version}" ${list}) + endmacro() + + set(_result 0) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) + set(_result 0) + if(CMAKE_CXX14_STANDARD_COMPILE_OPTION) + _get_appleclang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) + endif() + endif() +endmacro() diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index d504d69..548d0a5 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -25,18 +25,17 @@ endif() macro(cmake_record_c_compile_features) macro(_get_clang_features std_version list) - record_compiler_features(C "-std=${std_version}" ${list}) + record_compiler_features(C "${std_version}" ${list}) endmacro() + set(_result 0) if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) - _get_clang_features(c11 CMAKE_C11_COMPILE_FEATURES) + _get_clang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) if (_result EQUAL 0) - _get_clang_features(c99 CMAKE_C99_COMPILE_FEATURES) + _get_clang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_clang_features(c90 CMAKE_C90_COMPILE_FEATURES) + _get_clang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake index 4c532fb..df2e1a8 100644 --- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake +++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake @@ -2,61 +2,9 @@ # Reference: http://clang.llvm.org/cxx_status.html # http://clang.llvm.org/docs/LanguageExtensions.html -set(testable_features - cxx_alias_templates - cxx_alignas - cxx_attributes - cxx_auto_type - cxx_binary_literals - cxx_constexpr - cxx_contextual_conversions - cxx_decltype - cxx_decltype_incomplete_return_types - cxx_default_function_template_args - cxx_defaulted_functions - cxx_delegating_constructors - cxx_deleted_functions - cxx_explicit_conversions - cxx_generalized_initializers - cxx_inheriting_constructors - cxx_lambdas - cxx_local_type_template_args - cxx_noexcept - cxx_nonstatic_member_init - cxx_nullptr - cxx_range_for - cxx_raw_string_literals - cxx_reference_qualified_functions - cxx_relaxed_constexpr - cxx_return_type_deduction - cxx_rvalue_references - cxx_static_assert - cxx_strong_enums - cxx_thread_local - cxx_unicode_literals - cxx_unrestricted_unions - cxx_user_literals - cxx_variable_templates - cxx_variadic_templates -) - set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304") -foreach(feature ${testable_features}) - set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})") -endforeach() - -unset(testable_features) - -set(_cmake_feature_test_cxx_aggregate_default_initializers "${_cmake_oldestSupported} && __has_feature(cxx_aggregate_nsdmi)") - -set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)") -set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)") -set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") -set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") -set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)") -set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)") -set(_cmake_feature_test_cxx_lambda_init_captures "${_cmake_oldestSupported} && __has_feature(cxx_init_captures)") +include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake") set(Clang34_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 304 && __cplusplus > 201103L") # http://llvm.org/bugs/show_bug.cgi?id=19242 diff --git a/Modules/Compiler/Clang-CXX-TestableFeatures.cmake b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake new file mode 100644 index 0000000..b39475c --- /dev/null +++ b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake @@ -0,0 +1,54 @@ + +set(testable_features + cxx_alias_templates + cxx_alignas + cxx_attributes + cxx_auto_type + cxx_binary_literals + cxx_constexpr + cxx_contextual_conversions + cxx_decltype + cxx_decltype_incomplete_return_types + cxx_default_function_template_args + cxx_defaulted_functions + cxx_delegating_constructors + cxx_deleted_functions + cxx_explicit_conversions + cxx_generalized_initializers + cxx_inheriting_constructors + cxx_lambdas + cxx_local_type_template_args + cxx_noexcept + cxx_nonstatic_member_init + cxx_nullptr + cxx_range_for + cxx_raw_string_literals + cxx_reference_qualified_functions + cxx_relaxed_constexpr + cxx_return_type_deduction + cxx_rvalue_references + cxx_static_assert + cxx_strong_enums + cxx_thread_local + cxx_unicode_literals + cxx_unrestricted_unions + cxx_user_literals + cxx_variable_templates + cxx_variadic_templates +) + +foreach(feature ${testable_features}) + set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})") +endforeach() + +unset(testable_features) + +set(_cmake_feature_test_cxx_aggregate_default_initializers "${_cmake_oldestSupported} && __has_feature(cxx_aggregate_nsdmi)") + +set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)") +set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)") +set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)") +set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)") +set(_cmake_feature_test_cxx_lambda_init_captures "${_cmake_oldestSupported} && __has_feature(cxx_init_captures)") diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 9ef1413..e07eace 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -35,18 +35,17 @@ set(CMAKE_CXX_STANDARD_DEFAULT 98) macro(cmake_record_cxx_compile_features) macro(_get_clang_features std_version list) - record_compiler_features(CXX "-std=${std_version}" ${list}) + record_compiler_features(CXX "${std_version}" ${list}) endmacro() + set(_result 0) if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) - _get_clang_features(c++1y CMAKE_CXX14_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) if (_result EQUAL 0) - _get_clang_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_clang_features(c++98 CMAKE_CXX98_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/GNU-C-FeatureTests.cmake b/Modules/Compiler/GNU-C-FeatureTests.cmake index dfaeebf..7e840aa 100644 --- a/Modules/Compiler/GNU-C-FeatureTests.cmake +++ b/Modules/Compiler/GNU-C-FeatureTests.cmake @@ -1,7 +1,12 @@ -set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407") +set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406") -set(GNU46_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L") +# GNU 4.7 correctly sets __STDC_VERSION__ to 201112L, but GNU 4.6 sets it +# to 201000L. As the former is strictly greater than the latter, test only +# for the latter. If in the future CMake learns about a C feature which was +# introduced with GNU 4.7, that should test for the correct version, similar +# to the distinction between __cplusplus and __GXX_EXPERIMENTAL_CXX0X__ tests. +set(GNU46_C11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201000L") set(_cmake_feature_test_c_static_assert "${GNU46_C11}") # Since 4.4 at least: set(GNU44_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L") diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake index 24d439d..d5e747d 100644 --- a/Modules/Compiler/GNU-C.cmake +++ b/Modules/Compiler/GNU-C.cmake @@ -1,37 +1,41 @@ include(Compiler/GNU) __compiler_gnu(C) -if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") +endif() +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") +elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c1x") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x") endif() if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) set(CMAKE_C_STANDARD_DEFAULT 11) -else(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) +else() set(CMAKE_C_STANDARD_DEFAULT 90) endif() macro(cmake_record_c_compile_features) macro(_get_gcc_features std_version list) - record_compiler_features(C "-std=${std_version}" ${list}) + record_compiler_features(C "${std_version}" ${list}) endmacro() - if (UNIX AND NOT APPLE AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) - _get_gcc_features(c90 CMAKE_C90_COMPILE_FEATURES) + set(_result 0) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) + _get_gcc_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) if (_result EQUAL 0) - _get_gcc_features(c99 CMAKE_C99_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_gcc_features(c11 CMAKE_C11_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake index 9c98e44..267d658 100644 --- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake +++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake @@ -1,8 +1,15 @@ # Reference: http://gcc.gnu.org/projects/cxx0x.html +# http://gcc.gnu.org/projects/cxx1y.html -set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407") +set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406") +set(GNU50_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L") +set(_cmake_feature_test_cxx_variable_templates "${GNU50_CXX14}") + +# GNU 4.9 in c++14 mode sets __cplusplus to 201300L, so don't test for the +# correct value of it below. +# https://patchwork.ozlabs.org/patch/382470/ set(GNU49_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L") set(_cmake_feature_test_cxx_contextual_conversions "${GNU49_CXX14}") set(_cmake_feature_test_cxx_attribute_deprecated "${GNU49_CXX14}") @@ -39,7 +46,6 @@ set(_cmake_feature_test_cxx_alias_templates "${GNU47_CXX11}") set(_cmake_feature_test_cxx_delegating_constructors "${GNU47_CXX11}") set(_cmake_feature_test_cxx_extended_friend_declarations "${GNU47_CXX11}") set(_cmake_feature_test_cxx_final "${GNU47_CXX11}") -set(_cmake_feature_test_cxx_noexcept "${GNU47_CXX11}") set(_cmake_feature_test_cxx_nonstatic_member_init "${GNU47_CXX11}") set(_cmake_feature_test_cxx_override "${GNU47_CXX11}") set(_cmake_feature_test_cxx_user_literals "${GNU47_CXX11}") @@ -48,22 +54,28 @@ set(_cmake_feature_test_cxx_user_literals "${GNU47_CXX11}") # support -std=c++11. Prior to that, support for C++11 features is technically # experiemental and possibly incomplete (see for example the note below about # cxx_variadic_template_template_parameters) +# GNU does not define __cplusplus correctly before version 4.7. +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773 +# __GXX_EXPERIMENTAL_CXX0X__ is defined in prior versions, but may not be +# defined in the future. +set(GNU_CXX0X_DEFINED "(__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__))") # TODO: Should be supported by GNU 4.6 -set(GNU46_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU46_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_constexpr "${GNU46_CXX11}") set(_cmake_feature_test_cxx_defaulted_move_initializers "${GNU46_CXX11}") set(_cmake_feature_test_cxx_enum_forward_declarations "${GNU46_CXX11}") +set(_cmake_feature_test_cxx_noexcept "${GNU46_CXX11}") set(_cmake_feature_test_cxx_nullptr "${GNU46_CXX11}") set(_cmake_feature_test_cxx_range_for "${GNU46_CXX11}") set(_cmake_feature_test_cxx_unrestricted_unions "${GNU46_CXX11}") # TODO: Should be supported by GNU 4.5 -set(GNU45_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU45_CXX11 "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_explicit_conversions "${GNU45_CXX11}") set(_cmake_feature_test_cxx_lambdas "${GNU45_CXX11}") set(_cmake_feature_test_cxx_local_type_template_args "${GNU45_CXX11}") set(_cmake_feature_test_cxx_raw_string_literals "${GNU45_CXX11}") # TODO: Should be supported by GNU 4.4 -set(GNU44_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU44_CXX11 "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_auto_type "${GNU44_CXX11}") set(_cmake_feature_test_cxx_defaulted_functions "${GNU44_CXX11}") set(_cmake_feature_test_cxx_deleted_functions "${GNU44_CXX11}") @@ -83,7 +95,7 @@ set(_cmake_feature_test_cxx_variadic_templates "${GNU44_CXX11}") # templates capability in CMake. See # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf # TODO: Should be supported by GNU 4.3 -set(GNU43_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU43_CXX11 "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_decltype "${GNU43_CXX11}") set(_cmake_feature_test_cxx_default_function_template_args "${GNU43_CXX11}") set(_cmake_feature_test_cxx_long_long_type "${GNU43_CXX11}") @@ -91,8 +103,8 @@ set(_cmake_feature_test_cxx_right_angle_brackets "${GNU43_CXX11}") set(_cmake_feature_test_cxx_rvalue_references "${GNU43_CXX11}") set(_cmake_feature_test_cxx_static_assert "${GNU43_CXX11}") # TODO: Should be supported since GNU 3.4? -set(_cmake_feature_test_cxx_extern_templates "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_extern_templates "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") # TODO: Should be supported forever? -set(_cmake_feature_test_cxx_func_identifier "${_cmake_oldestSupported} && __cplusplus >= 201103L") -set(_cmake_feature_test_cxx_variadic_macros "${_cmake_oldestSupported} && __cplusplus >= 201103L") -set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus >= 199711L") +set(_cmake_feature_test_cxx_func_identifier "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") +set(_cmake_feature_test_cxx_variadic_macros "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") +set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus") diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 4129a38..eeada86 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -11,7 +11,7 @@ else() endif() endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) # Supported since 4.3 set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") @@ -20,10 +20,16 @@ endif() if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") +elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) # 4.3 supports 0x variants + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") endif() -if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) +if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") +elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") endif() @@ -32,21 +38,19 @@ set(CMAKE_CXX_STANDARD_DEFAULT 98) macro(cmake_record_cxx_compile_features) macro(_get_gcc_features std_version list) - record_compiler_features(CXX "-std=${std_version}" ${list}) + record_compiler_features(CXX "${std_version}" ${list}) endmacro() set(_result 0) - if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - _get_gcc_features(c++1y CMAKE_CXX14_COMPILE_FEATURES) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + _get_gcc_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) endif() - if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) if (_result EQUAL 0) - _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_gcc_features(c++98 CMAKE_CXX98_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake index 313ccbd..dfd7927 100644 --- a/Modules/Compiler/GNU-Fortran.cmake +++ b/Modules/Compiler/GNU-Fortran.cmake @@ -8,10 +8,5 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os") set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") -# We require updates to CMake C++ code to support preprocessing rules -# for Fortran. -set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) -set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) - # Fortran-specific feature flags. set(CMAKE_Fortran_MODDIR_FLAG -J) diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake index cc56b46..ad821ab 100644 --- a/Modules/Compiler/HP-Fortran.cmake +++ b/Modules/Compiler/HP-Fortran.cmake @@ -1,3 +1,6 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free") + +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake index 84f6182..9ebac5a 100644 --- a/Modules/Compiler/Intel-Fortran.cmake +++ b/Modules/Compiler/Intel-Fortran.cmake @@ -7,3 +7,6 @@ set(CMAKE_Fortran_MODDIR_FLAG "-module ") set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake index 264c23e..2866254 100644 --- a/Modules/Compiler/PGI-Fortran.cmake +++ b/Modules/Compiler/PGI-Fortran.cmake @@ -7,9 +7,4 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform") set(CMAKE_Fortran_FLAGS_INIT "${CMAKE_Fortran_FLAGS_INIT} -Mpreprocess -Kieee") set(CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT} -Mbounds") -# We require updates to CMake C++ code to support preprocessing rules -# for Fortran. -set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) -set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) - set(CMAKE_Fortran_MODDIR_FLAG "-module ") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index 18e75b9..e4db1e8 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -16,3 +16,6 @@ set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG") set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2 -DNDEBUG") set(CMAKE_Fortran_MODDIR_FLAG "-moddir=") set(CMAKE_Fortran_MODPATH_FLAG "-M") + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -F <SOURCE> -o <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index f1c9158..ae9df4e 100644 --- a/Modules/Compiler/XL-Fortran.cmake +++ b/Modules/Compiler/XL-Fortran.cmake @@ -12,6 +12,6 @@ set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D") # -qhalt=e = Halt on error messages (rather than just severe errors) set(CMAKE_Fortran_FLAGS_INIT "-qthreaded -qhalt=e") -# We require updates to CMake C++ code to support preprocessing rules for Fortran. +# xlf: 1501-214 (W) command option E reserved for future use - ignored set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 79bb064..741db81 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -1,189 +1,301 @@ -#.rst: -# ExternalData -# ------------ -# -# Manage data files stored outside source tree -# -# Use this module to unambiguously reference data files stored outside -# the source tree and fetch them at build time from arbitrary local and -# remote content-addressed locations. Functions provided by this module -# recognize arguments with the syntax ``DATA{<name>}`` as references to -# external data, replace them with full paths to local copies of those -# data, and create build rules to fetch and update the local copies. -# -# The ``DATA{}`` syntax is literal and the ``<name>`` is a full or relative path -# within the source tree. The source tree must contain either a real -# data file at ``<name>`` or a "content link" at ``<name><ext>`` containing a -# hash of the real file using a hash algorithm corresponding to ``<ext>``. -# For example, the argument ``DATA{img.png}`` may be satisfied by either a -# real ``img.png`` file in the current source directory or a ``img.png.md5`` -# file containing its MD5 sum. -# -# The ``ExternalData_Expand_Arguments`` function evaluates ``DATA{}`` -# references in its arguments and constructs a new list of arguments: -# -# .. code-block:: cmake -# -# ExternalData_Expand_Arguments( -# <target> # Name of data management target -# <outVar> # Output variable -# [args...] # Input arguments, DATA{} allowed -# ) -# -# It replaces each ``DATA{}`` reference in an argument with the full path of -# a real data file on disk that will exist after the ``<target>`` builds. -# -# The ``ExternalData_Add_Test`` function wraps around the CMake -# :command:`add_test` command but supports ``DATA{}`` references in -# its arguments: -# -# .. code-block:: cmake -# -# ExternalData_Add_Test( -# <target> # Name of data management target -# ... # Arguments of add_test(), DATA{} allowed -# ) -# -# It passes its arguments through ``ExternalData_Expand_Arguments`` and then -# invokes the :command:`add_test` command using the results. -# -# The ``ExternalData_Add_Target`` function creates a custom target to -# manage local instances of data files stored externally: -# -# .. code-block:: cmake -# -# ExternalData_Add_Target( -# <target> # Name of data management target -# ) -# -# It creates custom commands in the target as necessary to make data -# files available for each ``DATA{}`` reference previously evaluated by -# other functions provided by this module. A list of URL templates may -# be provided in the variable ``ExternalData_URL_TEMPLATES`` using the -# placeholders ``%(algo)`` and ``%(hash)`` in each template. Data fetch -# rules try each URL template in order by substituting the hash -# algorithm name for ``%(algo)`` and the hash value for ``%(hash)``. -# -# The following hash algorithms are supported:: -# -# %(algo) <ext> Description -# ------- ----- ----------- -# MD5 .md5 Message-Digest Algorithm 5, RFC 1321 -# SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174 -# SHA224 .sha224 US Secure Hash Algorithms, RFC 4634 -# SHA256 .sha256 US Secure Hash Algorithms, RFC 4634 -# SHA384 .sha384 US Secure Hash Algorithms, RFC 4634 -# SHA512 .sha512 US Secure Hash Algorithms, RFC 4634 -# -# Note that the hashes are used only for unique data identification and -# download verification. -# -# Example usage: -# -# .. code-block:: cmake -# -# include(ExternalData) -# set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)" -# "file:////host/share/%(algo)/%(hash)" -# "http://data.org/%(algo)/%(hash)") -# ExternalData_Add_Test(MyData -# NAME MyTest -# COMMAND MyExe DATA{MyInput.png} -# ) -# ExternalData_Add_Target(MyData) -# -# When test ``MyTest`` runs the ``DATA{MyInput.png}`` argument will be -# replaced by the full path to a real instance of the data file -# ``MyInput.png`` on disk. If the source tree contains a content link -# such as ``MyInput.png.md5`` then the ``MyData`` target creates a real -# ``MyInput.png`` in the build tree. -# -# The ``DATA{}`` syntax can be told to fetch a file series using the form -# ``DATA{<name>,:}``, where the ``:`` is literal. If the source tree -# contains a group of files or content links named like a series then a -# reference to one member adds rules to fetch all of them. Although all -# members of a series are fetched, only the file originally named by the -# ``DATA{}`` argument is substituted for it. The default configuration -# recognizes file series names ending with ``#.ext``, ``_#.ext``, ``.#.ext``, -# or ``-#.ext`` where ``#`` is a sequence of decimal digits and ``.ext`` is -# any single extension. Configure it with a regex that parses ``<number>`` -# and ``<suffix>`` parts from the end of ``<name>``:: -# -# ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$ -# -# For more complicated cases set:: -# -# ExternalData_SERIES_PARSE = regex with at least two () groups -# ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any -# ExternalData_SERIES_PARSE_NUMBER = <number> regex group number -# ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number -# -# Configure series number matching with a regex that matches the -# ``<number>`` part of series members named ``<prefix><number><suffix>``:: -# -# ExternalData_SERIES_MATCH = regex matching <number> in all series members -# -# Note that the ``<suffix>`` of a series does not include a hash-algorithm -# extension. -# -# The ``DATA{}`` syntax can alternatively match files associated with the -# named file and contained in the same directory. Associated files may -# be specified by options using the syntax -# ``DATA{<name>,<opt1>,<opt2>,...}``. Each option may specify one file by -# name or specify a regular expression to match file names using the -# syntax ``REGEX:<regex>``. For example, the arguments:: -# -# DATA{MyData/MyInput.mhd,MyInput.img} # File pair -# DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series -# -# will pass ``MyInput.mha`` and ``MyFrames00.png`` on the command line but -# ensure that the associated files are present next to them. -# -# The ``DATA{}`` syntax may reference a directory using a trailing slash and -# a list of associated files. The form ``DATA{<name>/,<opt1>,<opt2>,...}`` -# adds rules to fetch any files in the directory that match one of the -# associated file options. For example, the argument -# ``DATA{MyDataDir/,REGEX:.*}`` will pass the full path to a ``MyDataDir`` -# directory on the command line and ensure that the directory contains -# files corresponding to every file or content link in the ``MyDataDir`` -# source directory. -# -# The variable ``ExternalData_LINK_CONTENT`` may be set to the name of a -# supported hash algorithm to enable automatic conversion of real data -# files referenced by the ``DATA{}`` syntax into content links. For each -# such ``<file>`` a content link named ``<file><ext>`` is created. The -# original file is renamed to the form ``.ExternalData_<algo>_<hash>`` to -# stage it for future transmission to one of the locations in the list -# of URL templates (by means outside the scope of this module). The -# data fetch rule created for the content link will use the staged -# object if it cannot be found using any URL template. -# -# The variable ``ExternalData_OBJECT_STORES`` may be set to a list of local -# directories that store objects using the layout ``<dir>/%(algo)/%(hash)``. -# These directories will be searched first for a needed object. If the -# object is not available in any store then it will be fetched remotely -# using the URL templates and added to the first local store listed. If -# no stores are specified the default is a location inside the build -# tree. -# -# The variable ``ExternalData_SOURCE_ROOT`` may be set to the highest source -# directory containing any path named by a ``DATA{}`` reference. The -# default is ``CMAKE_SOURCE_DIR``. ``ExternalData_SOURCE_ROOT`` and -# ``CMAKE_SOURCE_DIR`` must refer to directories within a single source -# distribution (e.g. they come together in one tarball). -# -# The variable ``ExternalData_BINARY_ROOT`` may be set to the directory to -# hold the real data files named by expanded ``DATA{}`` references. The -# default is ``CMAKE_BINARY_DIR``. The directory layout will mirror that of -# content links under ``ExternalData_SOURCE_ROOT``. -# -# Variables ``ExternalData_TIMEOUT_INACTIVITY`` and -# ``ExternalData_TIMEOUT_ABSOLUTE`` set the download inactivity and absolute -# timeouts, in seconds. The defaults are 60 seconds and 300 seconds, -# respectively. Set either timeout to 0 seconds to disable enforcement. +#[=======================================================================[.rst: +ExternalData +------------ + +.. only:: html + + .. contents:: + +Manage data files stored outside source tree + +Introduction +^^^^^^^^^^^^ + +Use this module to unambiguously reference data files stored outside +the source tree and fetch them at build time from arbitrary local and +remote content-addressed locations. Functions provided by this module +recognize arguments with the syntax ``DATA{<name>}`` as references to +external data, replace them with full paths to local copies of those +data, and create build rules to fetch and update the local copies. + +For example: + +.. code-block:: cmake + + include(ExternalData) + set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)" + "file:////host/share/%(algo)/%(hash)" + "http://data.org/%(algo)/%(hash)") + ExternalData_Add_Test(MyData + NAME MyTest + COMMAND MyExe DATA{MyInput.png} + ) + ExternalData_Add_Target(MyData) + +When test ``MyTest`` runs the ``DATA{MyInput.png}`` argument will be +replaced by the full path to a real instance of the data file +``MyInput.png`` on disk. If the source tree contains a content link +such as ``MyInput.png.md5`` then the ``MyData`` target creates a real +``MyInput.png`` in the build tree. + +Module Functions +^^^^^^^^^^^^^^^^ + +.. command:: ExternalData_Expand_Arguments + + The ``ExternalData_Expand_Arguments`` function evaluates ``DATA{}`` + references in its arguments and constructs a new list of arguments:: + + ExternalData_Expand_Arguments( + <target> # Name of data management target + <outVar> # Output variable + [args...] # Input arguments, DATA{} allowed + ) + + It replaces each ``DATA{}`` reference in an argument with the full path of + a real data file on disk that will exist after the ``<target>`` builds. + +.. command:: ExternalData_Add_Test + + The ``ExternalData_Add_Test`` function wraps around the CMake + :command:`add_test` command but supports ``DATA{}`` references in + its arguments:: + + ExternalData_Add_Test( + <target> # Name of data management target + ... # Arguments of add_test(), DATA{} allowed + ) + + It passes its arguments through ``ExternalData_Expand_Arguments`` and then + invokes the :command:`add_test` command using the results. + +.. command:: ExternalData_Add_Target + + The ``ExternalData_Add_Target`` function creates a custom target to + manage local instances of data files stored externally:: + + ExternalData_Add_Target( + <target> # Name of data management target + ) + + It creates custom commands in the target as necessary to make data + files available for each ``DATA{}`` reference previously evaluated by + other functions provided by this module. + Data files may be fetched from one of the URL templates specified in + the ``ExternalData_URL_TEMPLATES`` variable, or may be found locally + in one of the paths specified in the ``ExternalData_OBJECT_STORES`` + variable. + +Module Variables +^^^^^^^^^^^^^^^^ + +The following variables configure behavior. They should be set before +calling any of the functions provided by this module. + +.. variable:: ExternalData_BINARY_ROOT + + The ``ExternalData_BINARY_ROOT`` variable may be set to the directory to + hold the real data files named by expanded ``DATA{}`` references. The + default is ``CMAKE_BINARY_DIR``. The directory layout will mirror that of + content links under ``ExternalData_SOURCE_ROOT``. + +.. variable:: ExternalData_CUSTOM_SCRIPT_<key> + + Specify a full path to a ``.cmake`` custom fetch script identified by + ``<key>`` in entries of the ``ExternalData_URL_TEMPLATES`` list. + See `Custom Fetch Scripts`_. + +.. variable:: ExternalData_LINK_CONTENT + + The ``ExternalData_LINK_CONTENT`` variable may be set to the name of a + supported hash algorithm to enable automatic conversion of real data + files referenced by the ``DATA{}`` syntax into content links. For each + such ``<file>`` a content link named ``<file><ext>`` is created. The + original file is renamed to the form ``.ExternalData_<algo>_<hash>`` to + stage it for future transmission to one of the locations in the list + of URL templates (by means outside the scope of this module). The + data fetch rule created for the content link will use the staged + object if it cannot be found using any URL template. + +.. variable:: ExternalData_OBJECT_STORES + + The ``ExternalData_OBJECT_STORES`` variable may be set to a list of local + directories that store objects using the layout ``<dir>/%(algo)/%(hash)``. + These directories will be searched first for a needed object. If the + object is not available in any store then it will be fetched remotely + using the URL templates and added to the first local store listed. If + no stores are specified the default is a location inside the build + tree. + +.. variable:: ExternalData_SERIES_PARSE + ExternalData_SERIES_PARSE_PREFIX + ExternalData_SERIES_PARSE_NUMBER + ExternalData_SERIES_PARSE_SUFFIX + ExternalData_SERIES_MATCH + + See `Referencing File Series`_. + +.. variable:: ExternalData_SOURCE_ROOT + + The ``ExternalData_SOURCE_ROOT`` variable may be set to the highest source + directory containing any path named by a ``DATA{}`` reference. The + default is ``CMAKE_SOURCE_DIR``. ``ExternalData_SOURCE_ROOT`` and + ``CMAKE_SOURCE_DIR`` must refer to directories within a single source + distribution (e.g. they come together in one tarball). + +.. variable:: ExternalData_TIMEOUT_ABSOLUTE + + The ``ExternalData_TIMEOUT_ABSOLUTE`` variable sets the download + absolute timeout, in seconds, with a default of ``300`` seconds. + Set to ``0`` to disable enforcement. + +.. variable:: ExternalData_TIMEOUT_INACTIVITY + + The ``ExternalData_TIMEOUT_INACTIVITY`` variable sets the download + inactivity timeout, in seconds, with a default of ``60`` seconds. + Set to ``0`` to disable enforcement. + +.. variable:: ExternalData_URL_TEMPLATES + + The ``ExternalData_URL_TEMPLATES`` may be set to provide a list of + of URL templates using the placeholders ``%(algo)`` and ``%(hash)`` + in each template. Data fetch rules try each URL template in order + by substituting the hash algorithm name for ``%(algo)`` and the hash + value for ``%(hash)``. + +Referencing Files +^^^^^^^^^^^^^^^^^ + +Referencing Single Files +"""""""""""""""""""""""" + +The ``DATA{}`` syntax is literal and the ``<name>`` is a full or relative path +within the source tree. The source tree must contain either a real +data file at ``<name>`` or a "content link" at ``<name><ext>`` containing a +hash of the real file using a hash algorithm corresponding to ``<ext>``. +For example, the argument ``DATA{img.png}`` may be satisfied by either a +real ``img.png`` file in the current source directory or a ``img.png.md5`` +file containing its MD5 sum. + +Referencing File Series +""""""""""""""""""""""" + +The ``DATA{}`` syntax can be told to fetch a file series using the form +``DATA{<name>,:}``, where the ``:`` is literal. If the source tree +contains a group of files or content links named like a series then a +reference to one member adds rules to fetch all of them. Although all +members of a series are fetched, only the file originally named by the +``DATA{}`` argument is substituted for it. The default configuration +recognizes file series names ending with ``#.ext``, ``_#.ext``, ``.#.ext``, +or ``-#.ext`` where ``#`` is a sequence of decimal digits and ``.ext`` is +any single extension. Configure it with a regex that parses ``<number>`` +and ``<suffix>`` parts from the end of ``<name>``:: + + ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$ + +For more complicated cases set:: + + ExternalData_SERIES_PARSE = regex with at least two () groups + ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any + ExternalData_SERIES_PARSE_NUMBER = <number> regex group number + ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number + +Configure series number matching with a regex that matches the +``<number>`` part of series members named ``<prefix><number><suffix>``:: + + ExternalData_SERIES_MATCH = regex matching <number> in all series members + +Note that the ``<suffix>`` of a series does not include a hash-algorithm +extension. + +Referencing Associated Files +"""""""""""""""""""""""""""" + +The ``DATA{}`` syntax can alternatively match files associated with the +named file and contained in the same directory. Associated files may +be specified by options using the syntax +``DATA{<name>,<opt1>,<opt2>,...}``. Each option may specify one file by +name or specify a regular expression to match file names using the +syntax ``REGEX:<regex>``. For example, the arguments:: + + DATA{MyData/MyInput.mhd,MyInput.img} # File pair + DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series + +will pass ``MyInput.mha`` and ``MyFrames00.png`` on the command line but +ensure that the associated files are present next to them. + +Referencing Directories +""""""""""""""""""""""" + +The ``DATA{}`` syntax may reference a directory using a trailing slash and +a list of associated files. The form ``DATA{<name>/,<opt1>,<opt2>,...}`` +adds rules to fetch any files in the directory that match one of the +associated file options. For example, the argument +``DATA{MyDataDir/,REGEX:.*}`` will pass the full path to a ``MyDataDir`` +directory on the command line and ensure that the directory contains +files corresponding to every file or content link in the ``MyDataDir`` +source directory. + +Hash Algorithms +^^^^^^^^^^^^^^^ + +The following hash algorithms are supported:: + + %(algo) <ext> Description + ------- ----- ----------- + MD5 .md5 Message-Digest Algorithm 5, RFC 1321 + SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174 + SHA224 .sha224 US Secure Hash Algorithms, RFC 4634 + SHA256 .sha256 US Secure Hash Algorithms, RFC 4634 + SHA384 .sha384 US Secure Hash Algorithms, RFC 4634 + SHA512 .sha512 US Secure Hash Algorithms, RFC 4634 + +Note that the hashes are used only for unique data identification and +download verification. + +.. _`ExternalData Custom Fetch Scripts`: + +Custom Fetch Scripts +^^^^^^^^^^^^^^^^^^^^ + +When a data file must be fetched from one of the URL templates +specified in the ``ExternalData_URL_TEMPLATES`` variable, it is +normally downloaded using the :command:`file(DOWNLOAD)` command. +One may specify usage of a custom fetch script by using a URL +template of the form ``ExternalDataCustomScript://<key>/<loc>``. +The ``<key>`` must be a C identifier, and the ``<loc>`` must +contain the ``%(algo)`` and ``%(hash)`` placeholders. +A variable corresponding to the key, ``ExternalData_CUSTOM_SCRIPT_<key>``, +must be set to the full path to a ``.cmake`` script file. The script +will be included to perform the actual fetch, and provided with +the following variables: + +.. variable:: ExternalData_CUSTOM_LOCATION + + When a custom fetch script is loaded, this variable is set to the + location part of the URL, which will contain the substituted hash + algorithm name and content hash value. + +.. variable:: ExternalData_CUSTOM_FILE + + When a custom fetch script is loaded, this variable is set to the + full path to a file in which the script must store the fetched + content. The name of the file is unspecified and should not be + interpreted in any way. + +The custom fetch script is expected to store fetched content in the +file or set a variable: + +.. variable:: ExternalData_CUSTOM_ERROR + + When a custom fetch script fails to fetch the requested content, + it must set this variable to a short one-line message describing + the reason for failure. + +#]=======================================================================] #============================================================================= -# Copyright 2010-2013 Kitware, Inc. +# Copyright 2010-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -209,6 +321,37 @@ function(ExternalData_add_target target) if(NOT ExternalData_OBJECT_STORES) set(ExternalData_OBJECT_STORES ${CMAKE_BINARY_DIR}/ExternalData/Objects) endif() + set(_ExternalData_CONFIG_CODE "") + + # Store custom script configuration. + foreach(url_template IN LISTS ExternalData_URL_TEMPLATES) + if("${url_template}" MATCHES "^ExternalDataCustomScript://([^/]*)/(.*)$") + set(key "${CMAKE_MATCH_1}") + if(key MATCHES "^[A-Za-z_][A-Za-z0-9_]*$") + if(ExternalData_CUSTOM_SCRIPT_${key}) + if(IS_ABSOLUTE "${ExternalData_CUSTOM_SCRIPT_${key}}") + string(CONCAT _ExternalData_CONFIG_CODE "${_ExternalData_CONFIG_CODE}\n" + "set(ExternalData_CUSTOM_SCRIPT_${key} \"${ExternalData_CUSTOM_SCRIPT_${key}}\")") + else() + message(FATAL_ERROR + "No ExternalData_CUSTOM_SCRIPT_${key} is not set to a full path:\n" + " ${ExternalData_CUSTOM_SCRIPT_${key}}") + endif() + else() + message(FATAL_ERROR + "No ExternalData_CUSTOM_SCRIPT_${key} is set for URL template:\n" + " ${url_template}") + endif() + else() + message(FATAL_ERROR + "Bad ExternalDataCustomScript key '${key}' in URL template:\n" + " ${url_template}\n" + "The key must be a valid C identifier.") + endif() + endif() + endforeach() + + # Store configuration for use by build-time script. set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake) configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY) @@ -715,6 +858,30 @@ function(_ExternalData_download_file url file err_var msg_var) set("${msg_var}" "${msg}" PARENT_SCOPE) endfunction() +function(_ExternalData_custom_fetch key loc file err_var msg_var) + if(NOT ExternalData_CUSTOM_SCRIPT_${key}) + set(err 1) + set(msg "No ExternalData_CUSTOM_SCRIPT_${key} set!") + elseif(NOT EXISTS "${ExternalData_CUSTOM_SCRIPT_${key}}") + set(err 1) + set(msg "No '${ExternalData_CUSTOM_SCRIPT_${key}}' exists!") + else() + set(ExternalData_CUSTOM_LOCATION "${loc}") + set(ExternalData_CUSTOM_FILE "${file}") + unset(ExternalData_CUSTOM_ERROR) + include("${ExternalData_CUSTOM_SCRIPT_${key}}") + if(DEFINED ExternalData_CUSTOM_ERROR) + set(err 1) + set(msg "${ExternalData_CUSTOM_ERROR}") + else() + set(err 0) + set(msg "no error") + endif() + endif() + set("${err_var}" "${err}" PARENT_SCOPE) + set("${msg_var}" "${msg}" PARENT_SCOPE) +endfunction() + function(_ExternalData_download_object name hash algo var_obj) # Search all object stores for an existing object. foreach(dir ${ExternalData_OBJECT_STORES}) @@ -738,7 +905,11 @@ function(_ExternalData_download_object name hash algo var_obj) string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}") string(REPLACE "%(algo)" "${algo}" url "${url_tmp}") message(STATUS "Fetching \"${url}\"") - _ExternalData_download_file("${url}" "${tmp}" err errMsg) + if(url MATCHES "^ExternalDataCustomScript://([A-Za-z_][A-Za-z0-9_]*)/(.*)$") + _ExternalData_custom_fetch("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "${tmp}" err errMsg) + else() + _ExternalData_download_file("${url}" "${tmp}" err errMsg) + endif() set(tried "${tried}\n ${url}") if(err) set(tried "${tried} (${errMsg})") diff --git a/Modules/ExternalData_config.cmake.in b/Modules/ExternalData_config.cmake.in index 0858f53..4434e4b 100644 --- a/Modules/ExternalData_config.cmake.in +++ b/Modules/ExternalData_config.cmake.in @@ -2,3 +2,4 @@ set(ExternalData_OBJECT_STORES "@ExternalData_OBJECT_STORES@") set(ExternalData_URL_TEMPLATES "@ExternalData_URL_TEMPLATES@") set(ExternalData_TIMEOUT_INACTIVITY "@ExternalData_TIMEOUT_INACTIVITY@") set(ExternalData_TIMEOUT_ABSOLUTE "@ExternalData_TIMEOUT_ABSOLUTE@") +@_ExternalData_CONFIG_CODE@ diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 8832950..52d41eb 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -1,187 +1,342 @@ -#.rst: -# ExternalProject -# --------------- -# -# Create custom targets to build projects in external trees -# -# The ``ExternalProject_Add`` function creates a custom target to drive -# download, update/patch, configure, build, install and test steps of an -# external project: -# -# .. code-block:: cmake -# -# ExternalProject_Add(<name> # Name for custom target -# [DEPENDS projects...] # Targets on which the project depends -# [PREFIX dir] # Root dir for entire project -# [LIST_SEPARATOR sep] # Sep to be replaced by ; in cmd lines -# [TMP_DIR dir] # Directory to store temporary files -# [STAMP_DIR dir] # Directory to store step timestamps -# [EXCLUDE_FROM_ALL 1] # The "all" target does not depend on this -# #--Download step-------------- -# [DOWNLOAD_NAME fname] # File name to store (if not end of URL) -# [DOWNLOAD_DIR dir] # Directory to store downloaded files -# [DOWNLOAD_COMMAND cmd...] # Command to download source tree -# [DOWNLOAD_NO_PROGRESS 1] # Disable download progress reports -# [CVS_REPOSITORY cvsroot] # CVSROOT of CVS repository -# [CVS_MODULE mod] # Module to checkout from CVS repo -# [CVS_TAG tag] # Tag to checkout from CVS repo -# [SVN_REPOSITORY url] # URL of Subversion repo -# [SVN_REVISION -r<rev>] # Revision to checkout from Subversion repo -# [SVN_USERNAME john ] # Username for Subversion checkout and update -# [SVN_PASSWORD doe ] # Password for Subversion checkout and update -# [SVN_TRUST_CERT 1 ] # Trust the Subversion server site certificate -# [GIT_REPOSITORY url] # URL of git repo -# [GIT_TAG tag] # Git branch name, commit id or tag -# [GIT_SUBMODULES modules...] # Git submodules that shall be updated, all if empty -# [HG_REPOSITORY url] # URL of mercurial repo -# [HG_TAG tag] # Mercurial branch name, commit id or tag -# [URL /.../src.tgz] # Full path or URL of source -# [URL_HASH ALGO=value] # Hash of file at URL -# [URL_MD5 md5] # Equivalent to URL_HASH MD5=md5 -# [TLS_VERIFY bool] # Should certificate for https be checked -# [TLS_CAINFO file] # Path to a certificate authority file -# [TIMEOUT seconds] # Time allowed for file download operations -# #--Update/Patch step---------- -# [UPDATE_COMMAND cmd...] # Source work-tree update command -# [PATCH_COMMAND cmd...] # Command to patch downloaded source -# #--Configure step------------- -# [SOURCE_DIR dir] # Source dir to be used for build -# [CONFIGURE_COMMAND cmd...] # Build tree configuration command -# [CMAKE_COMMAND /.../cmake] # Specify alternative cmake executable -# [CMAKE_GENERATOR gen] # Specify generator for native build -# [CMAKE_GENERATOR_PLATFORM p] # Generator-specific platform name -# [CMAKE_GENERATOR_TOOLSET t] # Generator-specific toolset name -# [CMAKE_ARGS args...] # Arguments to CMake command line -# [CMAKE_CACHE_ARGS args...] # Initial cache args with form -Dvar:string=on -# #--Build step----------------- -# [BINARY_DIR dir] # Specify build dir location -# [BUILD_COMMAND cmd...] # Command to drive the native build -# [BUILD_IN_SOURCE 1] # Use source dir for build dir -# [BUILD_ALWAYS 1] # No stamp file, build step always runs -# #--Install step--------------- -# [INSTALL_DIR dir] # Installation prefix -# [INSTALL_COMMAND cmd...] # Command to drive install after build -# #--Test step------------------ -# [TEST_BEFORE_INSTALL 1] # Add test step executed before install step -# [TEST_AFTER_INSTALL 1] # Add test step executed after install step -# [TEST_COMMAND cmd...] # Command to drive test -# #--Output logging------------- -# [LOG_DOWNLOAD 1] # Wrap download in script to log output -# [LOG_UPDATE 1] # Wrap update in script to log output -# [LOG_CONFIGURE 1] # Wrap configure in script to log output -# [LOG_BUILD 1] # Wrap build in script to log output -# [LOG_TEST 1] # Wrap test in script to log output -# [LOG_INSTALL 1] # Wrap install in script to log output -# #--Custom targets------------- -# [STEP_TARGETS st1 st2 ...] # Generate custom targets for these steps -# ) -# -# The ``*_DIR`` options specify directories for the project, with default -# directories computed as follows. If the ``PREFIX`` option is given to -# ``ExternalProject_Add()`` or the ``EP_PREFIX`` directory property is set, -# then an external project is built and installed under the specified prefix:: -# -# TMP_DIR = <prefix>/tmp -# STAMP_DIR = <prefix>/src/<name>-stamp -# DOWNLOAD_DIR = <prefix>/src -# SOURCE_DIR = <prefix>/src/<name> -# BINARY_DIR = <prefix>/src/<name>-build -# INSTALL_DIR = <prefix> -# -# Otherwise, if the ``EP_BASE`` directory property is set then components -# of an external project are stored under the specified base:: -# -# TMP_DIR = <base>/tmp/<name> -# STAMP_DIR = <base>/Stamp/<name> -# DOWNLOAD_DIR = <base>/Download/<name> -# SOURCE_DIR = <base>/Source/<name> -# BINARY_DIR = <base>/Build/<name> -# INSTALL_DIR = <base>/Install/<name> -# -# If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified then the -# default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are -# interpreted with respect to the build directory corresponding to the -# source directory in which ``ExternalProject_Add`` is invoked. -# -# If ``SOURCE_DIR`` is explicitly set to an existing directory the project -# will be built from it. Otherwise a download step must be specified -# using one of the ``DOWNLOAD_COMMAND``, ``CVS_*``, ``SVN_*``, or ``URL`` -# options. The ``URL`` option may refer locally to a directory or source -# tarball, or refer to a remote tarball (e.g. ``http://.../src.tgz``). -# -# The ``ExternalProject_Add_Step`` function adds a custom step to an -# external project: -# -# .. code-block:: cmake -# -# ExternalProject_Add_Step(<name> <step> # Names of project and custom step -# [COMMAND cmd...] # Command line invoked by this step -# [COMMENT "text..."] # Text printed when step executes -# [DEPENDEES steps...] # Steps on which this step depends -# [DEPENDERS steps...] # Steps that depend on this step -# [DEPENDS files...] # Files on which this step depends -# [ALWAYS 1] # No stamp file, step always runs -# [EXCLUDE_FROM_MAIN 1] # Main target does not depend on this step -# [WORKING_DIRECTORY dir] # Working directory for command -# [LOG 1] # Wrap step in script to log output -# ) -# -# The command line, comment, and working directory of every standard and -# custom step is processed to replace tokens ``<SOURCE_DIR>``, -# ``<BINARY_DIR>``, ``<INSTALL_DIR>``, and ``<TMP_DIR>`` with -# corresponding property values. -# -# Any builtin step that specifies a ``<step>_COMMAND cmd...`` or custom -# step that specifies a ``COMMAND cmd...`` may specify additional command -# lines using the form ``COMMAND cmd...``. At build time the commands -# will be executed in order and aborted if any one fails. For example:: -# -# ... BUILD_COMMAND make COMMAND echo done ... -# -# specifies to run ``make`` and then ``echo done`` during the build step. -# Whether the current working directory is preserved between commands is -# not defined. Behavior of shell operators like ``&&`` is not defined. -# -# The ``ExternalProject_Get_Property`` function retrieves external project -# target properties:: -# -# ExternalProject_Get_Property(<name> [prop1 [prop2 [...]]]) -# -# It stores property values in variables of the same name. Property -# names correspond to the keyword argument names of -# ``ExternalProject_Add``. -# -# The ``ExternalProject_Add_StepTargets`` function generates custom -# targets for the steps listed:: -# -# ExternalProject_Add_StepTargets(<name> [step1 [step2 [...]]]) -# -# If ``STEP_TARGETS`` is set then ``ExternalProject_Add_StepTargets`` is -# automatically called at the end of matching calls to -# ``ExternalProject_Add_Step``. Pass ``STEP_TARGETS`` explicitly to -# individual ``ExternalProject_Add`` calls, or implicitly to all -# ``ExternalProject_Add`` calls by setting the directory property -# ``EP_STEP_TARGETS``. -# -# If ``STEP_TARGETS`` is not set, clients may still manually call -# ``ExternalProject_Add_StepTargets`` after calling -# ``ExternalProject_Add`` or ``ExternalProject_Add_Step``. -# -# This functionality is provided to make it easy to drive the steps -# independently of each other by specifying targets on build command -# lines. For example, you may be submitting to a sub-project based -# dashboard, where you want to drive the configure portion of the build, -# then submit to the dashboard, followed by the build portion, followed -# by tests. If you invoke a custom target that depends on a step -# halfway through the step dependency chain, then all the previous steps -# will also run to ensure everything is up to date. -# -# For example, to drive configure, build and test steps independently -# for each ``ExternalProject_Add`` call in your project, write the following -# line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt`` -# file:: -# -# set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) +#[=======================================================================[.rst: +ExternalProject +--------------- + +Create custom targets to build projects in external trees + +.. command:: ExternalProject_Add + + The ``ExternalProject_Add`` function creates a custom target to drive + download, update/patch, configure, build, install and test steps of an + external project:: + + ExternalProject_Add(<name> [<option>...]) + + General options are: + + ``DEPENDS <projects>...`` + Targets on which the project depends + ``PREFIX <dir>`` + Root dir for entire project + ``LIST_SEPARATOR <sep>`` + Sep to be replaced by ; in cmd lines + ``TMP_DIR <dir>`` + Directory to store temporary files + ``STAMP_DIR <dir>`` + Directory to store step timestamps + ``EXCLUDE_FROM_ALL 1`` + The "all" target does not depend on this + + Download step options are: + + ``DOWNLOAD_NAME <fname>`` + File name to store (if not end of URL) + ``DOWNLOAD_DIR <dir>`` + Directory to store downloaded files + ``DOWNLOAD_COMMAND <cmd>...`` + Command to download source tree + ``DOWNLOAD_NO_PROGRESS 1`` + Disable download progress reports + ``CVS_REPOSITORY <cvsroot>`` + CVSROOT of CVS repository + ``CVS_MODULE <mod>`` + Module to checkout from CVS repo + ``CVS_TAG <tag>`` + Tag to checkout from CVS repo + ``SVN_REPOSITORY <url>`` + URL of Subversion repo + ``SVN_REVISION -r<rev>`` + Revision to checkout from Subversion repo + ``SVN_USERNAME <username>`` + Username for Subversion checkout and update + ``SVN_PASSWORD <password>`` + Password for Subversion checkout and update + ``SVN_TRUST_CERT 1`` + Trust the Subversion server site certificate + ``GIT_REPOSITORY <url>`` + URL of git repo + ``GIT_TAG <tag>`` + Git branch name, commit id or tag + ``GIT_SUBMODULES <module>...`` + Git submodules that shall be updated, all if empty + ``HG_REPOSITORY <url>`` + URL of mercurial repo + ``HG_TAG <tag>`` + Mercurial branch name, commit id or tag + ``URL /.../src.tgz`` + Full path or URL of source + ``URL_HASH ALGO=value`` + Hash of file at URL + ``URL_MD5 md5`` + Equivalent to URL_HASH MD5=md5 + ``TLS_VERIFY <bool>`` + Should certificate for https be checked + ``TLS_CAINFO <file>`` + Path to a certificate authority file + ``TIMEOUT <seconds>`` + Time allowed for file download operations + + Update/Patch step options are: + + ``UPDATE_COMMAND <cmd>...`` + Source work-tree update command + ``UPDATE_DISCONNECTED 1`` + Never update automatically from the remote repository + ``PATCH_COMMAND <cmd>...`` + Command to patch downloaded source + + Configure step options are: + + ``SOURCE_DIR <dir>`` + Source dir to be used for build + ``CONFIGURE_COMMAND <cmd>...`` + Build tree configuration command + ``CMAKE_COMMAND /.../cmake`` + Specify alternative cmake executable + ``CMAKE_GENERATOR <gen>`` + Specify generator for native build + ``CMAKE_GENERATOR_PLATFORM <platform>`` + Generator-specific platform name + ``CMAKE_GENERATOR_TOOLSET <toolset>`` + Generator-specific toolset name + ``CMAKE_ARGS <arg>...`` + Arguments to CMake command line. + These arguments are passed to CMake command line, and can contain + arguments other than cache values, see also + :manual:`CMake Options <cmake(1)>`. Arguments in the form + ``-Dvar:string=on`` are always passed to the command line, and + therefore cannot be changed by the user. + ``CMAKE_CACHE_ARGS <arg>...`` + Initial cache arguments, of the form ``-Dvar:string=on``. + These arguments are written in a pre-load a script that populates + CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to + overcome command line length limits. + These arguments are :command:`set` using the ``FORCE`` argument, + and therefore cannot be changed by the user. + ``CMAKE_CACHE_DEFAULT_ARGS <arg>...`` + Initial default cache arguments, of the form ``-Dvar:string=on``. + These arguments are written in a pre-load a script that populates + CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to + overcome command line length limits. + These arguments can be used as default value that will be set if no + previous value is found in the cache, and that the user can change + later. + + Build step options are: + + ``BINARY_DIR <dir>`` + Specify build dir location + ``BUILD_COMMAND <cmd>...`` + Command to drive the native build + ``BUILD_IN_SOURCE 1`` + Use source dir for build dir + ``BUILD_ALWAYS 1`` + No stamp file, build step always runs + ``BUILD_BYPRODUCTS <file>...`` + Files that will be generated by the build command but may or may + not have their modification time updated by subsequent builds. + + Install step options are: + + ``INSTALL_DIR <dir>`` + Installation prefix + ``INSTALL_COMMAND <cmd>...`` + Command to drive install after build + + Test step options are: + + ``TEST_BEFORE_INSTALL 1`` + Add test step executed before install step + ``TEST_AFTER_INSTALL 1`` + Add test step executed after install step + ``TEST_EXCLUDE_FROM_MAIN 1`` + Main target does not depend on the test step + ``TEST_COMMAND <cmd>...`` + Command to drive test + + Output logging options are: + + ``LOG_DOWNLOAD 1`` + Wrap download in script to log output + ``LOG_UPDATE 1`` + Wrap update in script to log output + ``LOG_CONFIGURE 1`` + Wrap configure in script to log output + ``LOG_BUILD 1`` + Wrap build in script to log output + ``LOG_TEST 1`` + Wrap test in script to log output + ``LOG_INSTALL 1`` + Wrap install in script to log output + + Other options are: + + ``STEP_TARGETS <step-target>...`` + Generate custom targets for these steps + ``INDEPENDENT_STEP_TARGETS <step-target>...`` + Generate custom targets for these steps that do not depend on other + external projects even if a dependency is set + + The ``*_DIR`` options specify directories for the project, with default + directories computed as follows. If the ``PREFIX`` option is given to + ``ExternalProject_Add()`` or the ``EP_PREFIX`` directory property is set, + then an external project is built and installed under the specified prefix:: + + TMP_DIR = <prefix>/tmp + STAMP_DIR = <prefix>/src/<name>-stamp + DOWNLOAD_DIR = <prefix>/src + SOURCE_DIR = <prefix>/src/<name> + BINARY_DIR = <prefix>/src/<name>-build + INSTALL_DIR = <prefix> + + Otherwise, if the ``EP_BASE`` directory property is set then components + of an external project are stored under the specified base:: + + TMP_DIR = <base>/tmp/<name> + STAMP_DIR = <base>/Stamp/<name> + DOWNLOAD_DIR = <base>/Download/<name> + SOURCE_DIR = <base>/Source/<name> + BINARY_DIR = <base>/Build/<name> + INSTALL_DIR = <base>/Install/<name> + + If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified then the + default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are + interpreted with respect to the build directory corresponding to the + source directory in which ``ExternalProject_Add`` is invoked. + + If ``SOURCE_DIR`` is explicitly set to an existing directory the project + will be built from it. Otherwise a download step must be specified + using one of the ``DOWNLOAD_COMMAND``, ``CVS_*``, ``SVN_*``, or ``URL`` + options. The ``URL`` option may refer locally to a directory or source + tarball, or refer to a remote tarball (e.g. ``http://.../src.tgz``). + + If ``UPDATE_DISCONNECTED`` is set, the update step is not executed + automatically when building the main target. The update step can still + be added as a step target and called manually. This is useful if you + want to allow to build the project when you are disconnected from the + network (you might still need the network for the download step). + This is disabled by default. + The directory property ``EP_UPDATE_DISCONNECTED`` can be used to change + the default value for all the external projects in the current + directory and its subdirectories. + +.. command:: ExternalProject_Add_Step + + The ``ExternalProject_Add_Step`` function adds a custom step to an + external project:: + + ExternalProject_Add_Step(<name> <step> [<option>...]) + + Options are: + + ``COMMAND <cmd>...`` + Command line invoked by this step + ``COMMENT "<text>..."`` + Text printed when step executes + ``DEPENDEES <step>...`` + Steps on which this step depends + ``DEPENDERS <step>...`` + Steps that depend on this step + ``DEPENDS <file>...`` + Files on which this step depends + ``BYPRODUCTS <file>...`` + Files that will be generated by this step but may or may not + have their modification time updated by subsequent builds. + ``ALWAYS 1`` + No stamp file, step always runs + ``EXCLUDE_FROM_MAIN 1`` + Main target does not depend on this step + ``WORKING_DIRECTORY <dir>`` + Working directory for command + ``LOG 1`` + Wrap step in script to log output + + The command line, comment, and working directory of every standard and + custom step is processed to replace tokens ``<SOURCE_DIR>``, + ``<BINARY_DIR>``, ``<INSTALL_DIR>``, and ``<TMP_DIR>`` with + corresponding property values. + +Any builtin step that specifies a ``<step>_COMMAND cmd...`` or custom +step that specifies a ``COMMAND cmd...`` may specify additional command +lines using the form ``COMMAND cmd...``. At build time the commands +will be executed in order and aborted if any one fails. For example:: + + ... BUILD_COMMAND make COMMAND echo done ... + +specifies to run ``make`` and then ``echo done`` during the build step. +Whether the current working directory is preserved between commands is +not defined. Behavior of shell operators like ``&&`` is not defined. + +.. command:: ExternalProject_Get_Property + + The ``ExternalProject_Get_Property`` function retrieves external project + target properties:: + + ExternalProject_Get_Property(<name> [prop1 [prop2 [...]]]) + + It stores property values in variables of the same name. Property + names correspond to the keyword argument names of + ``ExternalProject_Add``. + +.. command:: ExternalProject_Add_StepTargets + + The ``ExternalProject_Add_StepTargets`` function generates custom + targets for the steps listed:: + + ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] [step1 [step2 [...]]]) + +If ``NO_DEPENDS`` is set, the target will not depend on the +dependencies of the complete project. This is usually safe to use for +the download, update, and patch steps that do not require that all the +dependencies are updated and built. Using ``NO_DEPENDS`` for other +of the default steps might break parallel builds, so you should avoid, +it. For custom steps, you should consider whether or not the custom +commands requires that the dependencies are configured, built and +installed. + +If ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` is set then +``ExternalProject_Add_StepTargets`` is automatically called at the end +of matching calls to ``ExternalProject_Add_Step``. Pass +``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` explicitly to +individual ``ExternalProject_Add`` calls, or implicitly to all +``ExternalProject_Add`` calls by setting the directory properties +``EP_STEP_TARGETS`` and ``EP_INDEPENDENT_STEP_TARGETS``. The +``INDEPENDENT`` version of the argument and of the property will call +``ExternalProject_Add_StepTargets`` with the ``NO_DEPENDS`` argument. + +If ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` are not set, +clients may still manually call ``ExternalProject_Add_StepTargets`` +after calling ``ExternalProject_Add`` or ``ExternalProject_Add_Step``. + +This functionality is provided to make it easy to drive the steps +independently of each other by specifying targets on build command +lines. For example, you may be submitting to a sub-project based +dashboard, where you want to drive the configure portion of the build, +then submit to the dashboard, followed by the build portion, followed +by tests. If you invoke a custom target that depends on a step +halfway through the step dependency chain, then all the previous steps +will also run to ensure everything is up to date. + +For example, to drive configure, build and test steps independently +for each ``ExternalProject_Add`` call in your project, write the following +line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt`` +file:: + + set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) + +.. command:: ExternalProject_Add_StepDependencies + + The ``ExternalProject_Add_StepDependencies`` function add some + dependencies for some external project step:: + + ExternalProject_Add_StepDependencies(<name> <step> [target1 [target2 [...]]]) + + This function takes care to set both target and file level + dependencies, and will ensure that parallel builds will not break. + It should be used instead of :command:`add_dependencies()` when adding + a dependency for some of the step targets generated by + ``ExternalProject``. +#]=======================================================================] #============================================================================= # Copyright 2008-2013 Kitware, Inc. @@ -200,9 +355,9 @@ math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 16") file(STRINGS "${CMAKE_CURRENT_LIST_FILE}" lines LIMIT_COUNT ${_ep_documentation_line_count} - REGEX "^# ( \\[[A-Z0-9_]+ [^]]*\\] +#.*$|[A-Za-z0-9_]+\\()") + REGEX "^\\.\\. command:: [A-Za-z0-9_]+|^ ``[A-Z0-9_]+ .*``$") foreach(line IN LISTS lines) - if("${line}" MATCHES "^# ([A-Za-z0-9_]+)\\(") + if("${line}" MATCHES "^\\.\\. command:: ([A-Za-z0-9_]+)") if(_ep_func) set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") endif() @@ -210,8 +365,8 @@ foreach(line IN LISTS lines) #message("function [${_ep_func}]") set(_ep_keywords_${_ep_func} "^(") set(_ep_keyword_sep) - else() - string(REGEX REPLACE "^# \\[([A-Z0-9_]+) .*" "\\1" _ep_key "${line}") + elseif("${line}" MATCHES "^ ``([A-Z0-9_]+) .*``$") + set(_ep_key "${CMAKE_MATCH_1}") #message(" keyword [${_ep_key}]") set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}}${_ep_keyword_sep}${_ep_key}") @@ -290,10 +445,26 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED BRIEF_DOCS "List of ExternalProject steps that automatically get corresponding targets" FULL_DOCS + "These targets will be dependent on the main target dependencies" "See documentation of the ExternalProject_Add_StepTargets() function in the " "ExternalProject module." ) +define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED + BRIEF_DOCS + "List of ExternalProject steps that automatically get corresponding targets" + FULL_DOCS + "These targets will not be dependent on the main target dependencies" + "See documentation of the ExternalProject_Add_StepTargets() function in the " + "ExternalProject module." + ) + +define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED + BRIEF_DOCS "Never update automatically from the remote repo." + FULL_DOCS + "See documentation of the ExternalProject_Add() function in the " + "ExternalProject module." + ) function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_submodules src_name work_dir gitclone_infofile gitclone_stampfile) file(WRITE ${script_filename} @@ -910,17 +1081,20 @@ macro(_ep_replace_location_tags target_name) endmacro() -function(_ep_write_initial_cache target_name script_filename args) - # Write out values into an initial cache, that will be passed to CMake with -C +function(_ep_command_line_to_initial_cache var args force) set(script_initial_cache "") set(regex "^([^:]+):([^=]+)=(.*)$") set(setArg "") + set(forceArg "") + if(force) + set(forceArg "FORCE") + endif() foreach(line ${args}) if("${line}" MATCHES "^-D(.*)") set(line "${CMAKE_MATCH_1}") if(setArg) # This is required to build up lists in variables, or complete an entry - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") + set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") set(script_initial_cache "${script_initial_cache}\n${setArg}") set(accumulator "") set(setArg "") @@ -940,9 +1114,15 @@ function(_ep_write_initial_cache target_name script_filename args) endforeach() # Catch the final line of the args if(setArg) - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") + set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") set(script_initial_cache "${script_initial_cache}\n${setArg}") endif() + set(${var} ${script_initial_cache} PARENT_SCOPE) +endfunction() + + +function(_ep_write_initial_cache target_name script_filename script_initial_cache) + # Write out values into an initial cache, that will be passed to CMake with -C # Replace location tags. _ep_replace_location_tags(${target_name} script_initial_cache) # Write out the initial cache file to the location specified. @@ -1061,7 +1241,7 @@ function(_ep_write_log_script name step cmd_var) set(make "") set(code_cygpath_make "") - if("${command}" MATCHES "^\\$\\(MAKE\\)") + if(command MATCHES "^\\$\\(MAKE\\)") # GNU make recognizes the string "$(MAKE)" as recursive make, so # ensure that it appears directly in the makefile. string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}") @@ -1093,7 +1273,7 @@ endif() # Wrap multiple 'COMMAND' lines up into a second-level wrapper # script so all output can be sent to one log file. - if("${command}" MATCHES ";COMMAND;") + if(command MATCHES ";COMMAND;") set(code_execute_process " ${code_cygpath_make} execute_process(COMMAND \${command} RESULT_VARIABLE result) @@ -1140,10 +1320,10 @@ if(result) foreach(arg IN LISTS command) set(msg \"\${msg} '\${arg}'\") endforeach() - set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\") + set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\") message(FATAL_ERROR \"\${msg}\") else() - set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\") + set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\") message(STATUS \"\${msg}\") endif() ") @@ -1180,19 +1360,28 @@ endfunction() function(ExternalProject_Add_StepTargets name) set(steps ${ARGN}) - + if("${ARGV1}" STREQUAL "NO_DEPENDS") + set(no_deps 1) + list(REMOVE_AT steps 0) + endif() foreach(step ${steps}) + if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$") + message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds") + endif() _ep_get_step_stampfile(${name} ${step} stamp_file) add_custom_target(${name}-${step} DEPENDS ${stamp_file}) + set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1) set_property(TARGET ${name}-${step} PROPERTY LABELS ${name}) set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}") # Depend on other external projects (target-level). - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) - foreach(arg IN LISTS deps) - add_dependencies(${name}-${step} ${arg}) - endforeach() + if(NOT no_deps) + get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + foreach(arg IN LISTS deps) + add_dependencies(${name}-${step} ${arg}) + endforeach() + endif() endforeach() endfunction() @@ -1228,6 +1417,9 @@ function(ExternalProject_Add_Step name step) # Dependencies on files. get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS) + # Byproducts of the step. + get_property(byproducts TARGET ${name} PROPERTY _EP_${step}_BYPRODUCTS) + # Dependencies on steps. get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES) foreach(dependee IN LISTS dependees) @@ -1274,8 +1466,18 @@ function(ExternalProject_Add_Step name step) _ep_write_log_script(${name} ${step} command) endif() + if("${command}" STREQUAL "") + # Some generators (i.e. Xcode) will not generate a file level target + # if no command is set, and therefore the dependencies on this + # target will be broken. + # The empty command is replaced by an echo command here in order to + # avoid this issue. + set(command ${CMAKE_COMMAND} -E echo_append) + endif() + add_custom_command( OUTPUT ${stamp_file} + BYPRODUCTS ${byproducts} COMMENT ${comment} COMMAND ${command} COMMAND ${touch} @@ -1283,6 +1485,7 @@ function(ExternalProject_Add_Step name step) WORKING_DIRECTORY ${work_dir} VERBATIM ) + set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step}) # Add custom "step target"? get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS) @@ -1295,6 +1498,60 @@ function(ExternalProject_Add_Step name step) break() endif() endforeach() + + get_property(independent_step_targets TARGET ${name} PROPERTY _EP_INDEPENDENT_STEP_TARGETS) + if(NOT independent_step_targets) + get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS) + endif() + foreach(st ${independent_step_targets}) + if("${st}" STREQUAL "${step}") + ExternalProject_Add_StepTargets(${name} NO_DEPENDS ${step}) + break() + endif() + endforeach() +endfunction() + + +function(ExternalProject_Add_StepDependencies name step) + set(dependencies ${ARGN}) + + # Sanity checks on "name" and "step". + if(NOT TARGET ${name}) + message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.") + endif() + + get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT) + if(NOT is_ep) + message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.") + endif() + + get_property(steps TARGET ${name} PROPERTY _EP_STEPS) + list(FIND steps ${step} is_step) + if(NOT is_step) + message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".") + endif() + + if(TARGET ${name}-${step}) + get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP) + if(NOT is_ep_step) + message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add_StepTargets.") + endif() + endif() + + # Always add file-level dependency, but add target-level dependency + # only if the target exists for that step. + _ep_get_step_stampfile(${name} ${step} stamp_file) + foreach(dep ${dependencies}) + add_custom_command(APPEND + OUTPUT ${stamp_file} + DEPENDS ${dep}) + if(TARGET ${name}-${step}) + foreach(dep ${dependencies}) + add_dependencies(${name}-${step} ${dep}) + endforeach() + endif() + endforeach() + endfunction() @@ -1612,6 +1869,12 @@ function(_ep_add_update_command name) get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY) get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY) get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY ) + get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET) + if(update_disconnected_set) + get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED) + else() + get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED) + endif() set(work_dir) set(comment) @@ -1701,10 +1964,26 @@ Update to Mercurial >= 2.1.1. COMMENT ${comment} COMMAND ${cmd} ALWAYS ${always} + EXCLUDE_FROM_MAIN ${update_disconnected} WORKING_DIRECTORY ${work_dir} DEPENDEES download ${log} ) + + if(always AND update_disconnected) + _ep_get_step_stampfile(${name} skip-update skip-update_stamp_file) + string(REPLACE "Performing" "Skipping" comment "${comment}") + ExternalProject_Add_Step(${name} skip-update + COMMENT ${comment} + ALWAYS 1 + EXCLUDE_FROM_MAIN 1 + WORKING_DIRECTORY ${work_dir} + DEPENDEES download + ${log} + ) + set_property(SOURCE ${skip-update_stamp_file} PROPERTY SYMBOLIC 1) + endif() + endfunction() @@ -1757,11 +2036,20 @@ function(_ep_add_configure_command name) get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS) list(APPEND cmd ${cmake_args}) - # If there are any CMAKE_CACHE_ARGS, write an initial cache and use it + # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS, + # write an initial cache and use it get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS) - if(cmake_cache_args) + get_property(cmake_cache_default_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS) + + if(cmake_cache_args OR cmake_cache_default_args) set(_ep_cache_args_script "${tmp_dir}/${name}-cache.cmake") - _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${cmake_cache_args}") + if(cmake_cache_args) + _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1) + endif() + if(cmake_cache_default_args) + _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0) + endif() + _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}") list(APPEND cmd "-C${_ep_cache_args_script}") endif() @@ -1817,10 +2105,22 @@ function(_ep_add_configure_command name) set(log "") endif() + get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET) + if(update_disconnected_set) + get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED) + else() + get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED) + endif() + if(update_disconnected) + set(update_dep skip-update) + else() + set(update_dep update) + endif() + ExternalProject_Add_Step(${name} configure COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} - DEPENDEES update patch + DEPENDEES ${update_dep} patch DEPENDS ${file_deps} ${log} ) @@ -1851,8 +2151,11 @@ function(_ep_add_build_command name) set(always 0) endif() + get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS) + ExternalProject_Add_Step(${name} build COMMAND ${cmd} + BYPRODUCTS ${build_byproducts} WORKING_DIRECTORY ${binary_dir} DEPENDEES configure ALWAYS ${always} @@ -1892,12 +2195,13 @@ function(_ep_add_test_command name) get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL) get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL) + get_property(exclude TARGET ${name} PROPERTY _EP_TEST_EXCLUDE_FROM_MAIN) get_property(cmd_set TARGET ${name} PROPERTY _EP_TEST_COMMAND SET) # Only actually add the test step if one of the test related properties is # explicitly set. (i.e. the test step is omitted unless requested...) # - if(cmd_set OR before OR after) + if(cmd_set OR before OR after OR exclude) if(cmd_set) get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND) else() @@ -1905,9 +2209,21 @@ function(_ep_add_test_command name) endif() if(before) - set(dep_args DEPENDEES build DEPENDERS install) + set(dependees_args DEPENDEES build) + else() + set(dependees_args DEPENDEES install) + endif() + + if(exclude) + set(dependers_args "") + set(exclude_args EXCLUDE_FROM_MAIN 1) else() - set(dep_args DEPENDEES install) + if(before) + set(dependers_args DEPENDERS install) + else() + set(dependers_args "") + endif() + set(exclude_args "") endif() get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST) @@ -1920,7 +2236,9 @@ function(_ep_add_test_command name) ExternalProject_Add_Step(${name} test COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} - ${dep_args} + ${dependees_args} + ${dependers_args} + ${exclude_args} ${log} ) endif() diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index d837aeb..99293c1 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -321,7 +321,7 @@ macro(_Boost_FIND_LIBRARY var) # If Boost_LIBRARY_DIR is known then search only there. if(Boost_LIBRARY_DIR) - set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH) + set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) endif() endmacro() @@ -855,7 +855,7 @@ if(_Boost_CHANGE_LIBDIR AND NOT _Boost_LIBRARY_DIR_CHANGED) endif() if(Boost_LIBRARY_DIR) - set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH) + set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) else() set(_boost_LIBRARY_SEARCH_DIRS "") if(BOOST_LIBRARYDIR) diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index ecfc781..4f1f09a 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -1423,7 +1423,8 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER ) list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"") endif() - # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} + + # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} and CMAKE_${CUDA_C_OR_CXX}_FLAGS* set(config_specific_flags) set(flags) foreach(config ${CUDA_configuration_types}) @@ -1438,6 +1439,13 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>) endforeach() endforeach() + # Add CMAKE_${CUDA_C_OR_CXX}_FLAGS + set(important_host_flags) + _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS}) + foreach(f ${important_host_flags}) + list(APPEND flags -Xcompiler ${f}) + endforeach() + # Add our general CUDA_NVCC_FLAGS with the configuration specifig flags set(nvcc_flags ${CUDA_NVCC_FLAGS} ${config_specific_flags} ${nvcc_flags}) diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake index a21ca89..f94bd09 100644 --- a/Modules/FindCurses.cmake +++ b/Modules/FindCurses.cmake @@ -179,11 +179,6 @@ if(NOT DEFINED CURSES_HAVE_CURSES_H) endif() endif() -if (NOT CURSES_TINFO_HAS_CBREAK) - find_library(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}") - find_library(CURSES_EXTRA_LIBRARY cur_colr ) -endif() - find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}") find_library(CURSES_FORM_LIBRARY form ) diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake new file mode 100644 index 0000000..ef125c0 --- /dev/null +++ b/Modules/FindGSL.cmake @@ -0,0 +1,238 @@ +#.rst: +# FindGSL +# -------- +# +# Find the native GSL includes and libraries. +# +# The GNU Scientific Library (GSL) is a numerical library for C and C++ +# programmers. It is free software under the GNU General Public +# License. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# +# If GSL is found, this module defines the following :prop_tgt:`IMPORTED` +# targets:: +# +# GSL::gsl - The main GSL library. +# GSL::gslcblas - The CBLAS support library used by GSL. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module will set the following variables in your project:: +# +# GSL_FOUND - True if GSL found on the local system +# GSL_INCLUDE_DIRS - Location of GSL header files. +# GSL_LIBRARIES - The GSL libraries. +# GSL_VERSION - The version of the discovered GSL install. +# +# Hints +# ^^^^^ +# +# Set ``GSL_ROOT_DIR`` to a directory that contains a GSL installation. +# +# This script expects to find libraries at ``$GSL_ROOT_DIR/lib`` and the GSL +# headers at ``$GSL_ROOT_DIR/include/gsl``. The library directory may +# optionally provide Release and Debug folders. For Unix-like systems, this +# script will use ``$GSL_ROOT_DIR/bin/gsl-config`` (if found) to aid in the +# discovery GSL. +# +# Cache Variables +# ^^^^^^^^^^^^^^^ +# +# This module may set the following variables depending on platform and type +# of GSL installation discovered. These variables may optionally be set to +# help this module find the correct files:: +# +# GSL_CLBAS_LIBRARY - Location of the GSL CBLAS library. +# GSL_CBLAS_LIBRARY_DEBUG - Location of the debug GSL CBLAS library (if any). +# GSL_CONFIG_EXECUTABLE - Location of the ``gsl-config`` script (if any). +# GSL_LIBRARY - Location of the GSL library. +# GSL_LIBRARY_DEBUG - Location of the debug GSL library (if any). +# + +#============================================================================= +# Copyright 2014 Kelly Thompson <kgt@lanl.gov> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Include these modules to handle the QUIETLY and REQUIRED arguments. +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + +#============================================================================= +# If the user has provided ``GSL_ROOT_DIR``, use it! Choose items found +# at this location over system locations. +if( EXISTS "$ENV{GSL_ROOT_DIR}" ) + file( TO_CMAKE_PATH "$ENV{GSL_ROOT_DIR}" GSL_ROOT_DIR ) + set( GSL_ROOT_DIR "${GSL_ROOT_DIR}" CACHE PATH "Prefix for GSL installation." ) +endif() +if( NOT EXISTS "${GSL_ROOT_DIR}" ) + set( GSL_USE_PKGCONFIG ON ) +endif() + +#============================================================================= +# As a first try, use the PkgConfig module. This will work on many +# *NIX systems. See :module:`findpkgconfig` +# This will return ``GSL_INCLUDEDIR`` and ``GSL_LIBDIR`` used below. +if( GSL_USE_PKGCONFIG ) + find_package(PkgConfig) + pkg_check_modules( GSL QUIET gsl ) + + if( EXISTS "${GSL_INCLUDEDIR}" ) + get_filename_component( GSL_ROOT_DIR "${GSL_INCLUDEDIR}" DIRECTORY CACHE) + endif() +endif() + +#============================================================================= +# Set GSL_INCLUDE_DIRS and GSL_LIBRARIES. If we skipped the PkgConfig step, try +# to find the libraries at $GSL_ROOT_DIR (if provided) or in standard system +# locations. These find_library and find_path calls will prefer custom +# locations over standard locations (HINTS). If the requested file is not found +# at the HINTS location, standard system locations will be still be searched +# (/usr/lib64 (Redhat), lib/i386-linux-gnu (Debian)). + +find_path( GSL_INCLUDE_DIR + NAMES gsl/gsl_sf.h + HINTS ${GSL_ROOT_DIR}/include ${GSL_INCLUDEDIR} +) +find_library( GSL_LIBRARY + NAMES gsl + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Release Debug +) +find_library( GSL_CBLAS_LIBRARY + NAMES gslcblas cblas + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Release Debug +) +# Do we also have debug versions? +find_library( GSL_LIBRARY_DEBUG + NAMES gsl + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Debug +) +find_library( GSL_CBLAS_LIBRARY_DEBUG + NAMES gslcblas cblas + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Debug +) +set( GSL_INCLUDE_DIRS ${GSL_INCLUDE_DIR} ) +set( GSL_LIBRARIES ${GSL_LIBRARY} ${GSL_CBLAS_LIBRARY} ) + +# If we didn't use PkgConfig, try to find the version via gsl-config or by +# reading gsl_version.h. +if( NOT GSL_VERSION ) + # 1. If gsl-config exists, query for the version. + find_program( GSL_CONFIG_EXECUTABLE + NAMES gsl-config + HINTS "${GSL_ROOT_DIR}/bin" + ) + if( EXISTS "${GSL_CONFIG_EXECUTABLE}" ) + execute_process( + COMMAND "${GSL_CONFIG_EXECUTABLE}" --version + OUTPUT_VARIABLE GSL_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE ) + endif() + + # 2. If gsl-config is not available, try looking in gsl/gsl_version.h + if( NOT GSL_VERSION AND EXISTS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" ) + file( STRINGS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" gsl_version_h_contents REGEX "define GSL_VERSION" ) + string( REGEX REPLACE ".*([0-9].[0-9][0-9]).*" "\\1" GSL_VERSION ${gsl_version_h_contents} ) + endif() + + # might also try scraping the directory name for a regex match "gsl-X.X" +endif() + +#============================================================================= +# handle the QUIETLY and REQUIRED arguments and set GSL_FOUND to TRUE if all +# listed variables are TRUE +find_package_handle_standard_args( GSL + FOUND_VAR + GSL_FOUND + REQUIRED_VARS + GSL_INCLUDE_DIR + GSL_LIBRARY + GSL_CBLAS_LIBRARY + VERSION_VAR + GSL_VERSION + ) + +mark_as_advanced( GSL_ROOT_DIR GSL_VERSION GSL_LIBRARY GSL_INCLUDE_DIR + GSL_CBLAS_LIBRARY GSL_LIBRARY_DEBUG GSL_CBLAS_LIBRARY_DEBUG + GSL_USE_PKGCONFIG GSL_CONFIG ) + +#============================================================================= +# Register imported libraries: +# 1. If we can find a Windows .dll file (or if we can find both Debug and +# Release libraries), we will set appropriate target properties for these. +# 2. However, for most systems, we will only register the import location and +# include directory. + +# Look for dlls, or Release and Debug libraries. +if(WIN32) + string( REPLACE ".lib" ".dll" GSL_LIBRARY_DLL "${GSL_LIBRARY}" ) + string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DLL "${GSL_CBLAS_LIBRARY}" ) + string( REPLACE ".lib" ".dll" GSL_LIBRARY_DEBUG_DLL "${GSL_LIBRARY_DEBUG}" ) + string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DEBUG_DLL "${GSL_CBLAS_LIBRARY_DEBUG}" ) +endif() + +if( GSL_FOUND AND NOT TARGET GSL::gsl ) + if( EXISTS "${GSL_LIBRARY_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DLL}") + + # Windows systems with dll libraries. + add_library( GSL::gsl SHARED IMPORTED ) + add_library( GSL::gslcblas SHARED IMPORTED ) + + # Windows with dlls, but only Release libraries. + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION_RELEASE "${GSL_CBLAS_LIBRARY_DLL}" + IMPORTED_IMPLIB "${GSL_CBLAS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_CONFIGURATIONS Release + IMPORTED_LINK_INTERFACE_LANGUAGES "C" ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION_RELEASE "${GSL_LIBRARY_DLL}" + IMPORTED_IMPLIB "${GSL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_CONFIGURATIONS Release + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_LINK_LIBRARIES GSL::gslcblas ) + + # If we have both Debug and Release libraries + if( EXISTS "${GSL_LIBRARY_DEBUG_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DEBUG_DLL}") + set_property( TARGET GSL::gslcblas APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug ) + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG_DLL}" + IMPORTED_IMPLIB_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG}" ) + set_property( TARGET GSL::gsl APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION_DEBUG "${GSL_LIBRARY_DEBUG_DLL}" + IMPORTED_IMPLIB_DEBUG "${GSL_LIBRARY_DEBUG}" ) + endif() + + else() + + # For all other environments (ones without dll libraries), create + # the imported library targets. + add_library( GSL::gsl UNKNOWN IMPORTED ) + add_library( GSL::gslcblas UNKNOWN IMPORTED ) + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION "${GSL_CBLAS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION "${GSL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_LINK_LIBRARIES GSL::gslcblas ) + endif() +endif() diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index f972ad0..ac53c3f 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -50,6 +50,9 @@ # (by default use share/locale/). # If ALL is specified, the po files are processed when building the all traget. # It creates a custom target "pofiles". +# +# .. note:: +# If you wish to use the Gettext library (libintl), use :module:`FindIntl`. #============================================================================= # Copyright 2007-2009 Kitware, Inc. diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index 570538d..b4f7b4b 100644 --- a/Modules/FindGit.cmake +++ b/Modules/FindGit.cmake @@ -45,11 +45,15 @@ set(git_names git eg) if(WIN32) if(NOT CMAKE_GENERATOR MATCHES "MSYS") set(git_names git.cmd git eg.cmd eg) + # GitHub search path for Windows + set(github_path "$ENV{LOCALAPPDATA}/Github/PortableGit*/bin") + file(GLOB github_path "${github_path}") endif() endif() find_program(GIT_EXECUTABLE NAMES ${git_names} + PATHS ${github_path} PATH_SUFFIXES Git/cmd Git/bin DOC "git command line client" ) diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake new file mode 100644 index 0000000..cd2ec63 --- /dev/null +++ b/Modules/FindIntl.cmake @@ -0,0 +1,69 @@ +#.rst: +# FindIntl +# -------- +# +# Find the Gettext libintl headers and libraries. +# +# This module reports information about the Gettext libintl +# installation in several variables. General variables:: +# +# Intl_FOUND - true if the libintl headers and libraries were found +# Intl_INCLUDE_DIRS - the directory containing the libintl headers +# Intl_LIBRARIES - libintl libraries to be linked +# +# The following cache variables may also be set:: +# +# Intl_INCLUDE_DIR - the directory containing the libintl headers +# Intl_LIBRARY - the libintl library (if any) +# +# .. note:: +# On some platforms, such as Linux with GNU libc, the gettext +# functions are present in the C standard library and libintl +# is not required. ``Intl_LIBRARIES`` will be empty in this +# case. +# +# .. note:: +# If you wish to use the Gettext tools (``msgmerge``, +# ``msgfmt``, etc.), use :module:`FindGettext`. + + +# Written by Roger Leigh <rleigh@codelibre.net> + +#============================================================================= +# Copyright 2014 Roger Leigh <rleigh@codelibre.net> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Find include directory +find_path(Intl_INCLUDE_DIR + NAMES "libintl.h" + DOC "libintl include directory") +mark_as_advanced(Intl_INCLUDE_DIR) + +# Find all Intl libraries +find_library(Intl_LIBRARY "intl" + DOC "libintl libraries (if not in the C library)") +mark_as_advanced(Intl_LIBRARY) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl + FOUND_VAR Intl_FOUND + REQUIRED_VARS Intl_INCLUDE_DIR + FAIL_MESSAGE "Failed to find Gettext libintl") + +if(Intl_FOUND) + set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}") + if(Intl_LIBRARY) + set(Intl_LIBRARIES "${Intl_LIBRARY}") + else() + unset(Intl_LIBRARIES) + endif() +endif() diff --git a/Modules/FindJsonCpp.cmake b/Modules/FindJsonCpp.cmake new file mode 100644 index 0000000..cbb4fb3 --- /dev/null +++ b/Modules/FindJsonCpp.cmake @@ -0,0 +1,117 @@ +#[=======================================================================[.rst: +FindJsonCpp +----------- + +Find JsonCpp includes and library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +An :ref:`imported target <Imported targets>` named +``JsonCpp::JsonCpp`` is provided if JsonCpp has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``JsonCpp_FOUND`` + True if JsonCpp was found, false otherwise. +``JsonCpp_INCLUDE_DIRS`` + Include directories needed to include JsonCpp headers. +``JsonCpp_LIBRARIES`` + Libraries needed to link to JsonCpp. +``JsonCpp_VERSION_STRING`` + The version of JsonCpp found. + May not be set for JsonCpp versions prior to 1.0. +``JsonCpp_VERSION_MAJOR`` + The major version of JsonCpp. +``JsonCpp_VERSION_MINOR`` + The minor version of JsonCpp. +``JsonCpp_VERSION_PATCH`` + The patch version of JsonCpp. + +Cache Variables +^^^^^^^^^^^^^^^ + +This module uses the following cache variables: + +``JsonCpp_LIBRARY`` + The location of the JsonCpp library file. +``JsonCpp_INCLUDE_DIR`` + The location of the JsonCpp include directory containing ``json/json.h``. + +The cache variables should not be used by project code. +They may be set by end users to point at JsonCpp components. +#]=======================================================================] + +#============================================================================= +# Copyright 2014-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +#----------------------------------------------------------------------------- +find_library(JsonCpp_LIBRARY + NAMES jsoncpp + ) +mark_as_advanced(JsonCpp_LIBRARY) + +find_path(JsonCpp_INCLUDE_DIR + NAMES json/json.h + PATH_SUFFIXES jsoncpp + ) +mark_as_advanced(JsonCpp_INCLUDE_DIR) + +#----------------------------------------------------------------------------- +# Extract version number if possible. +set(_JsonCpp_H_REGEX "^#[ \t]*define[ \t]+JSONCPP_VERSION_STRING[ \t]+\"(([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*)\".*$") +if(JsonCpp_INCLUDE_DIR AND EXISTS "${JsonCpp_INCLUDE_DIR}/json/version.h") + file(STRINGS "${JsonCpp_INCLUDE_DIR}/json/version.h" _JsonCpp_H REGEX "${_JsonCpp_H_REGEX}") +else() + set(_JsonCpp_H "") +endif() +if(_JsonCpp_H MATCHES "${_JsonCpp_H_REGEX}") + set(JsonCpp_VERSION_STRING "${CMAKE_MATCH_1}") + set(JsonCpp_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(JsonCpp_VERSION_MINOR "${CMAKE_MATCH_3}") + set(JsonCpp_VERSION_PATCH "${CMAKE_MATCH_4}") +else() + set(JsonCpp_VERSION_STRING "") + set(JsonCpp_VERSION_MAJOR "") + set(JsonCpp_VERSION_MINOR "") + set(JsonCpp_VERSION_PATCH "") +endif() +unset(_JsonCpp_H_REGEX) +unset(_JsonCpp_H) + +#----------------------------------------------------------------------------- +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JsonCpp + FOUND_VAR JsonCpp_FOUND + REQUIRED_VARS JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR + VERSION_VAR JsonCpp_VERSION_STRING + ) +set(JSONCPP_FOUND ${JsonCpp_FOUND}) + +#----------------------------------------------------------------------------- +# Provide documented result variables and targets. +if(JsonCpp_FOUND) + set(JsonCpp_INCLUDE_DIRS ${JsonCpp_INCLUDE_DIR}) + set(JsonCpp_LIBRARIES ${JsonCpp_LIBRARY}) + if(NOT TARGET JsonCpp::JsonCpp) + add_library(JsonCpp::JsonCpp UNKNOWN IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES + IMPORTED_LOCATION "${JsonCpp_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${JsonCpp_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + ) + endif() +endif() diff --git a/Modules/FindLATEX.cmake b/Modules/FindLATEX.cmake index e353d38..ae83733 100644 --- a/Modules/FindLATEX.cmake +++ b/Modules/FindLATEX.cmake @@ -4,21 +4,54 @@ # # Find Latex # -# This module finds if Latex is installed and determines where the -# executables are. This code sets the following variables: +# This module finds an installed Latex and determines the location +# of the compiler. Additionally the module looks for Latex-related +# software like BibTeX. # -# :: +# This module sets the following result variables:: # +# LATEX_FOUND: whether found Latex and requested components +# LATEX_<component>_FOUND: whether found <component> # LATEX_COMPILER: path to the LaTeX compiler # PDFLATEX_COMPILER: path to the PdfLaTeX compiler +# XELATEX_COMPILER: path to the XeLaTeX compiler +# LUALATEX_COMPILER: path to the LuaLaTeX compiler # BIBTEX_COMPILER: path to the BibTeX compiler +# BIBER_COMPILER: path to the Biber compiler # MAKEINDEX_COMPILER: path to the MakeIndex compiler +# XINDY_COMPILER: path to the xindy compiler # DVIPS_CONVERTER: path to the DVIPS converter +# DVIPDF_CONVERTER: path to the DVIPDF converter # PS2PDF_CONVERTER: path to the PS2PDF converter +# PDFTOPS_CONVERTER: path to the pdftops converter # LATEX2HTML_CONVERTER: path to the LaTeX2Html converter +# HTLATEX_COMPILER: path to the htlatex compiler +# +# Possible components are:: +# +# PDFLATEX +# XELATEX +# LUALATEX +# BIBTEX +# BIBER +# MAKEINDEX +# XINDY +# DVIPS +# DVIPDF +# PS2PDF +# PDFTOPS +# LATEX2HTML +# HTLATEX +# +# Example Usages:: +# +# find_package(LATEX) +# find_package(LATEX COMPONENTS PDFLATEX) +# find_package(LATEX COMPONENTS BIBTEX PS2PDF) #============================================================================= -# Copyright 2002-2009 Kitware, Inc. +# Copyright 2002-2015 Kitware, Inc. +# Copyright 2014-2015 Christoph GrĂ¼ninger <foss@grueninger.de> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -31,9 +64,7 @@ # License text for the above reference.) if (WIN32) - # Try to find the MikTex binary path (look for its package manager). - find_path(MIKTEX_BINARY_PATH mpm.exe "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MiK\\MiKTeX\\CurrentVersion\\MiKTeX;Install Root]/miktex/bin" DOC @@ -42,7 +73,6 @@ if (WIN32) mark_as_advanced(MIKTEX_BINARY_PATH) # Try to find the GhostScript binary path (look for gswin32). - get_filename_component(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\8.00;GS_DLL]" PATH ) @@ -63,45 +93,124 @@ if (WIN32) DOC "Path to the GhostScript library directory." ) mark_as_advanced(GHOSTSCRIPT_LIBRARY_PATH) - endif () +# try to find Latex and the related programs find_program(LATEX_COMPILER NAMES latex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +# find pdflatex find_program(PDFLATEX_COMPILER NAMES pdflatex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (PDFLATEX_COMPILER) + set(LATEX_PDFLATEX_FOUND TRUE) +else() + set(LATEX_PDFLATEX_FOUND FALSE) +endif() +# find xelatex +find_program(XELATEX_COMPILER + NAMES xelatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (XELATEX_COMPILER) + set(LATEX_XELATEX_FOUND TRUE) +else() + set(LATEX_XELATEX_FOUND FALSE) +endif() + +# find lualatex +find_program(LUALATEX_COMPILER + NAMES lualatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (LUALATEX_COMPILER) + set(LATEX_LUALATEX_FOUND TRUE) +else() + set(LATEX_LUALATEX_FOUND FALSE) +endif() + +# find bibtex find_program(BIBTEX_COMPILER NAMES bibtex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (BIBTEX_COMPILER) + set(LATEX_BIBTEX_FOUND TRUE) +else() + set(LATEX_BIBTEX_FOUND FALSE) +endif() + +# find biber +find_program(BIBER_COMPILER + NAMES biber + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (BIBER_COMPILER) + set(LATEX_BIBER_FOUND TRUE) +else() + set(LATEX_BIBER_FOUND FALSE) +endif() +# find makeindex find_program(MAKEINDEX_COMPILER NAMES makeindex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (MAKEINDEX_COMPILER) + set(LATEX_MAKEINDEX_FOUND TRUE) +else() + set(LATEX_MAKEINDEX_FOUND FALSE) +endif() +# find xindy +find_program(XINDY_COMPILER + NAMES xindy + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (XINDY_COMPILER) + set(LATEX_XINDY_FOUND TRUE) +else() + set(LATEX_XINDY_FOUND FALSE) +endif() + +# find dvips find_program(DVIPS_CONVERTER NAMES dvips PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (DVIPS_CONVERTER) + set(LATEX_DVIPS_FOUND TRUE) +else() + set(LATEX_DVIPS_FOUND FALSE) +endif() +# find dvipdf find_program(DVIPDF_CONVERTER NAMES dvipdfm dvipdft dvipdf PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (DVIPDF_CONVERTER) + set(LATEX_DVIPDF_FOUND TRUE) +else() + set(LATEX_DVIPDF_FOUND FALSE) +endif() +# find ps2pdf if (WIN32) find_program(PS2PDF_CONVERTER NAMES ps2pdf14.bat ps2pdf14 ps2pdf @@ -113,21 +222,69 @@ else () NAMES ps2pdf14 ps2pdf ) endif () +if (PS2PDF_CONVERTER) + set(LATEX_PS2PDF_FOUND TRUE) +else() + set(LATEX_PS2PDF_FOUND FALSE) +endif() +# find pdftops +find_program(PDFTOPS_CONVERTER + NAMES pdftops + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (PDFTOPS_CONVERTER) + set(LATEX_PDFTOPS_FOUND TRUE) +else() + set(LATEX_PDFTOPS_FOUND FALSE) +endif() + +# find latex2html find_program(LATEX2HTML_CONVERTER NAMES latex2html PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (LATEX2HTML_CONVERTER) + set(LATEX_LATEX2HTML_FOUND TRUE) +else() + set(LATEX_LATEX2HTML_FOUND FALSE) +endif() + +# find htlatex +find_program(HTLATEX_COMPILER + NAMES htlatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (HTLATEX_COMPILER) + set(LATEX_HTLATEX_FOUND TRUE) +else() + set(LATEX_HTLATEX_FOUND FALSE) +endif() mark_as_advanced( LATEX_COMPILER PDFLATEX_COMPILER + XELATEX_COMPILER + LUALATEX_COMPILER BIBTEX_COMPILER + BIBER_COMPILER MAKEINDEX_COMPILER + XINDY_COMPILER DVIPS_CONVERTER DVIPDF_CONVERTER PS2PDF_CONVERTER + PDFTOPS_CONVERTER LATEX2HTML_CONVERTER + HTLATEX_COMPILER +) + +# handle variables for found Latex and its components +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(LATEX + REQUIRED_VARS LATEX_COMPILER + HANDLE_COMPONENTS ) diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 3be5e3c..545b077 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -160,7 +160,7 @@ set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95 # or if we know it matches the regular compiler. foreach (lang C CXX Fortran) foreach (id GNU Intel PGI XL) - if (NOT CMAKE_${lang}_COMPILER_ID OR "${CMAKE_${lang}_COMPILER_ID}" STREQUAL "${id}") + if (NOT CMAKE_${lang}_COMPILER_ID OR CMAKE_${lang}_COMPILER_ID STREQUAL id) list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES}) endif() unset(_MPI_${id}_${lang}_COMPILER_NAMES) # clean up the namespace here @@ -174,6 +174,13 @@ set(_MPI_EXEC_NAMES mpiexec mpirun lamexec srun) # Grab the path to MPI from the registry if we're on windows. set(_MPI_PREFIX_PATH) if(WIN32) + # MSMPI + file(TO_CMAKE_PATH "$ENV{MSMPI_BIN}" msmpi_bin_path) # The default path ends with a '\' and doesn't mix with ';' when appending. + list(APPEND _MPI_PREFIX_PATH "${msmpi_bin_path}") + unset(msmpi_bin_path) + list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin") + list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_INC}/..") # The SDK is installed separately from the runtime + # MPICH list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..") list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]") list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/") @@ -188,6 +195,21 @@ foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH}) endforeach() endforeach() +function (_mpi_check_compiler compiler options cmdvar resvar) + execute_process( + COMMAND "${compiler}" ${options} + OUTPUT_VARIABLE cmdline OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE cmdline ERROR_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE success) + # Intel MPI 5.0.1 will return a zero return code even when the + # argument to the MPI compiler wrapper is unknown. Attempt to + # catch this case. + if("${cmdline}" MATCHES "undefined reference") + set(success 255 ) + endif() + set(${cmdvar} "${cmdline}" PARENT_SCOPE) + set(${resvar} "${success}" PARENT_SCOPE) +endfunction() # # interrogate_mpi_compiler(lang try_libs) @@ -220,12 +242,7 @@ function (interrogate_mpi_compiler lang try_libs) if (MPI_${lang}_COMPILER) # Check whether the -showme:compile option works. This indicates that we have either OpenMPI # or a newer version of LAM-MPI, and implies that -showme:link will also work. - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -showme:compile - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) - + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) if (MPI_COMPILER_RETURN EQUAL 0) # If we appear to have -showme:compile, then we should # also have -showme:link. Try it. @@ -257,20 +274,12 @@ function (interrogate_mpi_compiler lang try_libs) # Older versions of LAM-MPI have "-showme". Try to find that. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -showme - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() # MVAPICH uses -compile-info and -link-info. Try them. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -compile-info - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) # If we have compile-info, also have link-info. if (MPI_COMPILER_RETURN EQUAL 0) @@ -290,11 +299,7 @@ function (interrogate_mpi_compiler lang try_libs) # MPICH just uses "-show". Try it. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -show - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() if (MPI_COMPILER_RETURN EQUAL 0) @@ -365,7 +370,7 @@ function (interrogate_mpi_compiler lang try_libs) endif() # Extract linker flags from the link command line - string(REGEX MATCHALL "(^| )-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}") + string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}") set(MPI_LINK_FLAGS_WORK) foreach(FLAG ${MPI_ALL_LINK_FLAGS}) if (MPI_LINK_FLAGS_WORK) @@ -423,16 +428,18 @@ function (interrogate_mpi_compiler lang try_libs) # Decide between 32-bit and 64-bit libraries for Microsoft's MPI if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - set(MS_MPI_ARCH_DIR amd64) + set(MS_MPI_ARCH_DIR x64) + set(MS_MPI_ARCH_DIR2 amd64) else() - set(MS_MPI_ARCH_DIR i386) + set(MS_MPI_ARCH_DIR x86) + set(MS_MPI_ARCH_DIR2 i386) endif() set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) find_library(MPI_LIB NAMES mpi mpich mpich2 msmpi HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} - PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR}) + PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} Lib/${MS_MPI_ARCH_DIR2}) set(MPI_LIBRARIES_WORK ${MPI_LIB}) # Right now, we only know about the extra libs for C++. diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index a83a6c3..a7eefa7 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -128,19 +128,6 @@ else() unset(_OPENGL_INCLUDE_PATH) unset(_OPENGL_LIB_PATH) - # On Unix OpenGL most certainly always requires X11. - # Feel free to tighten up these conditions if you don't - # think this is always true. - - if (OPENGL_gl_LIBRARY) - if(NOT X11_FOUND) - include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake) - endif() - if (X11_FOUND) - set (OPENGL_LIBRARIES ${X11_LIBRARIES}) - endif () - endif () - find_library(OPENGL_glu_LIBRARY NAMES GLU MesaGLU PATHS ${OPENGL_gl_LIBRARY} diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 340b417..bfbe01f 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -16,10 +16,12 @@ # # :: # -# OPENSSL_FOUND - system has the OpenSSL library -# OPENSSL_INCLUDE_DIR - the OpenSSL include directory -# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL -# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s) +# OPENSSL_FOUND - System has the OpenSSL library +# OPENSSL_INCLUDE_DIR - The OpenSSL include directory +# OPENSSL_CRYPTO_LIBRARY - The OpenSSL crypto library +# OPENSSL_SSL_LIBRARY - The OpenSSL SSL library +# OPENSSL_LIBRARIES - All OpenSSL libraries +# OPENSSL_VERSION - This is set to $major.$minor.$revision$patch (eg. 0.9.8s) #============================================================================= # Copyright 2006-2009 Kitware, Inc. @@ -153,6 +155,8 @@ if(WIN32 AND NOT CYGWIN) mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} ) set( OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} ) elseif(MINGW) # same player, for MinGW @@ -181,6 +185,8 @@ if(WIN32 AND NOT CYGWIN) ) mark_as_advanced(SSL_EAY LIB_EAY) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) unset(LIB_EAY_NAMES) unset(SSL_EAY_NAMES) @@ -207,6 +213,8 @@ if(WIN32 AND NOT CYGWIN) ) mark_as_advanced(SSL_EAY LIB_EAY) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) endif() else() @@ -275,9 +283,7 @@ function(from_hex HEX DEC) endfunction() if (OPENSSL_INCLUDE_DIR) - if (_OPENSSL_VERSION) - set(OPENSSL_VERSION "${_OPENSSL_VERSION}") - elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 6bcf1e7..2de1fb3 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -319,7 +319,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) endif () unset(_VERSION_HEAD) else () - if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION) set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") set(VERSION_OK FALSE) else () @@ -329,7 +329,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) unset(_VERSION_DOTS) else() # minimum version specified: - if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + if (${_NAME}_FIND_VERSION VERSION_GREATER VERSION) set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") set(VERSION_OK FALSE) else () diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index a79246a..11091b5 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -1321,7 +1321,7 @@ endif() if (NOT QT_VERSION_MAJOR EQUAL 4) set(VERSION_MSG "Found unsuitable Qt version \"${QTVERSION}\" from ${QT_QMAKE_EXECUTABLE}") - set(QT4_FOUND FALSE) + set(Qt4_FOUND FALSE) if(Qt4_FIND_REQUIRED) message( FATAL_ERROR "${VERSION_MSG}, this code requires Qt 4.x") else() diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake index d4e5dcd..869ba38 100644 --- a/Modules/FindUnixCommands.cmake +++ b/Modules/FindUnixCommands.cmake @@ -2,12 +2,13 @@ # FindUnixCommands # ---------------- # -# Find unix commands from cygwin +# Find Unix commands, including the ones from Cygwin # -# This module looks for some usual Unix commands. +# This module looks for the Unix commands bash, cp, gzip, mv, rm, and tar +# and stores the result in the variables BASH, CP, GZIP, MV, RM, and TAR. #============================================================================= -# Copyright 2001-2009 Kitware, Inc. +# Copyright 2001-2014 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -95,3 +96,8 @@ find_program(TAR mark_as_advanced( TAR ) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(UnixCommands + REQUIRED_VARS BASH CP GZIP MV RM TAR +) diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt index b6232ed..721a262 100644 --- a/Modules/FortranCInterface/CMakeLists.txt +++ b/Modules/FortranCInterface/CMakeLists.txt @@ -71,7 +71,7 @@ endif() # Generate C symbol sources. set(symbol_sources) -if(NOT "${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(PathScale|Cray)$") +if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(PathScale|Cray)$") # Provide mymodule_ and my_module_ init symbols because: # - PGI Fortran uses module init symbols # but not for: diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 9963517..712a41c 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -179,7 +179,7 @@ function(gp_append_unique list_var value) set(contains 0) foreach(item ${${list_var}}) - if("${item}" STREQUAL "${value}") + if(item STREQUAL "${value}") set(contains 1) break() endif() @@ -546,14 +546,14 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) if(NOT is_system) get_filename_component(original_path "${original_lower}" PATH) get_filename_component(path "${lower}" PATH) - if("${original_path}" STREQUAL "${path}") + if(original_path STREQUAL path) set(is_local 1) else() string(LENGTH "${original_path}/" original_length) string(LENGTH "${lower}" path_length) if(${path_length} GREATER ${original_length}) string(SUBSTRING "${lower}" 0 ${original_length} path) - if("${original_path}/" STREQUAL "${path}") + if("${original_path}/" STREQUAL path) set(is_embedded 1) endif() endif() @@ -642,7 +642,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # Try to choose the right tool by default. Caller can set gp_tool prior to # calling this function to force using a different tool. # - if("${gp_tool}" STREQUAL "") + if(NOT gp_tool) set(gp_tool "ldd") if(APPLE) @@ -666,45 +666,31 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa return() endif() - set(gp_tool_known 0) - - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(gp_cmd_args "") set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$") set(gp_regex_error "not found${eol_char}$") set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "otool") + elseif(gp_tool STREQUAL "otool") set(gp_cmd_args "-L") set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 3) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "dumpbin") + elseif(gp_tool STREQUAL "dumpbin") set(gp_cmd_args "/dependents") set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "objdump") + elseif(gp_tool STREQUAL "objdump") set(gp_cmd_args "-p") set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if(NOT gp_tool_known) + else() message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...") message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'") message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.") @@ -712,7 +698,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa endif() - if("${gp_tool}" STREQUAL "dumpbin") + if(gp_tool STREQUAL "dumpbin") # When running dumpbin, it also needs the "Common7/IDE" directory in the # PATH. It will already be in the PATH if being run from a Visual Studio # command prompt. Add it to the PATH here in case we are running from a @@ -727,7 +713,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(gp_found_cmd_dlls_dir 0) file(TO_CMAKE_PATH "$ENV{PATH}" env_path) foreach(gp_env_path_element ${env_path}) - if("${gp_env_path_element}" STREQUAL "${gp_cmd_dlls_dir}") + if(gp_env_path_element STREQUAL gp_cmd_dlls_dir) set(gp_found_cmd_dlls_dir 1) endif() endforeach() @@ -741,7 +727,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # # </setup-gp_tool-vars> - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(old_ld_env "$ENV{LD_LIBRARY_PATH}") set(new_ld_env "${exepath}") foreach(dir ${dirs}) @@ -763,7 +749,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa OUTPUT_VARIABLE gp_cmd_ov ) - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(ENV{LD_LIBRARY_PATH} "${old_ld_env}") endif() @@ -783,7 +769,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # check for install id and remove it from list, since otool -L can include a # reference to itself set(gp_install_id) - if("${gp_tool}" STREQUAL "otool") + if(gp_tool STREQUAL "otool") execute_process( COMMAND otool -D ${target} OUTPUT_VARIABLE gp_install_id_ov @@ -833,7 +819,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # set(add_item 1) - if("${item}" STREQUAL "${gp_install_id}") + if(item STREQUAL gp_install_id) set(add_item 0) endif() @@ -841,7 +827,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(type "") gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}") - if("${type}" STREQUAL "system") + if(type STREQUAL "system") set(add_item 0) endif() endif() diff --git a/Modules/Platform/Darwin-GNU-Fortran.cmake b/Modules/Platform/Darwin-GNU-Fortran.cmake index f4b509a..6724f9b 100644 --- a/Modules/Platform/Darwin-GNU-Fortran.cmake +++ b/Modules/Platform/Darwin-GNU-Fortran.cmake @@ -14,6 +14,8 @@ include(Platform/Darwin-GNU) __darwin_compiler_gnu(Fortran) +cmake_gnu_set_sysroot_flag(Fortran) +cmake_gnu_set_osx_deployment_target_flag(Fortran) set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ") diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake index 30acab8..e5c5d10 100644 --- a/Modules/Platform/HP-UX-HP-Fortran.cmake +++ b/Modules/Platform/HP-UX-HP-Fortran.cmake @@ -1,2 +1,5 @@ include(Platform/HP-UX-HP) __hpux_compiler_hp(Fortran) + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Platform/IRIX.cmake b/Modules/Platform/IRIX.cmake index 03e98cc..12b0f37 100644 --- a/Modules/Platform/IRIX.cmake +++ b/Modules/Platform/IRIX.cmake @@ -31,6 +31,14 @@ if(NOT CMAKE_COMPILER_IS_GNUCXX) ) endif() +if(NOT CMAKE_COMPILER_IS_GNUG77) + set (CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") + set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE + "<CMAKE_Fortran_COMPILER> <FLAGS> -S <SOURCE>" + "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>" + ) +endif() + # Initialize C link type selection flags. These flags are used when # building a shared library, shared module, or executable that links # to other libraries to select whether to use the static or shared diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake index a203826..e1279ef 100644 --- a/Modules/Platform/eCos.cmake +++ b/Modules/Platform/eCos.cmake @@ -28,7 +28,7 @@ include(Platform/UnixPaths) # eCos can be built only with gcc get_property(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE) -if(CMAKE_C_COMPILER AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC) +if(CMAKE_C_COMPILER AND NOT CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT _IN_TC) message(FATAL_ERROR "GNU gcc is required for eCos") endif() if(CMAKE_CXX_COMPILER AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC) diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 127012f..3a6acd8 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -398,7 +398,7 @@ function(add_jar _TARGET_NAME) ${CMAKE_JAVA_LIBRARY_OUTPUT_PATH} ) - if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";") else () set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":") diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 31ab48d..bab1b21 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -272,6 +272,8 @@ macro(SWIG_ADD_MODULE name language) if(WIN32 AND NOT CYGWIN) set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd") endif() + elseif ("${swig_lowercase_language}" STREQUAL "r") + set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") elseif ("${swig_lowercase_language}" STREQUAL "ruby") # In ruby you want: # require 'LIBRARY' diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index 8d72d0f..d61358f 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -11,6 +11,7 @@ # write_compiler_detection_header( # FILE <file> # PREFIX <prefix> +# [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>] # COMPILERS <compiler> [...] # FEATURES <feature> [...] # [VERSION <version>] @@ -21,6 +22,33 @@ # The ``write_compiler_detection_header`` function generates the # file ``<file>`` with macros which all have the prefix ``<prefix>``. # +# By default, all content is written directly to the ``<file>``. The +# ``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific +# content to be written to separate files. The separate files are then +# available in the ``<output_files_var>`` and may be consumed by the caller +# for installation for example. The ``OUTPUT_DIR`` specifies a relative +# path from the main ``<file>`` to the compiler-specific files. For example: +# +# .. code-block:: cmake +# +# write_compiler_detection_header( +# FILE climbingstats_compiler_detection.h +# PREFIX ClimbingStats +# OUTPUT_FILES_VAR support_files +# OUTPUT_DIR compilers +# COMPILERS GNU Clang +# FEATURES cxx_variadic_templates +# ) +# install(FILES +# ${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h +# DESTINATION include +# ) +# install(FILES +# ${support_files} +# DESTINATION include/compilers +# ) +# +# # ``VERSION`` may be used to specify the API version to be generated. # Future versions of CMake may introduce alternative APIs. A given # API is selected by any ``<version>`` value greater than or equal @@ -72,7 +100,7 @@ # write_compiler_detection_header( # FILE climbingstats_compiler_detection.h # PREFIX ClimbingStats -# COMPILERS GNU Clang +# COMPILERS GNU Clang AppleClang # FEATURES cxx_variadic_templates # ) # @@ -166,6 +194,7 @@ # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]`` +# ``cxx_thread_local`` ``<PREFIX>_THREAD_LOCAL`` ``thread_local`` # ============================= ================================ ===================== # # A use-case which arises with such deprecation macros is the deprecation @@ -220,7 +249,7 @@ function(write_compiler_detection_header message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.") endif() set(options) - set(oneValueArgs VERSION EPILOG PROLOG) + set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR) set(multiValueArgs COMPILERS FEATURES) cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -255,9 +284,39 @@ function(write_compiler_detection_header message(FATAL_ERROR "${err}") endif() + if(_WCD_OUTPUT_FILES_VAR) + if(NOT _WCD_OUTPUT_DIR) + message(FATAL_ERROR "If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.") + endif() + endif() + if(_WCD_OUTPUT_DIR) + if(NOT _WCD_OUTPUT_FILES_VAR) + message(FATAL_ERROR "If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.") + endif() + get_filename_component(main_file_dir ${file_arg} DIRECTORY) + if (NOT IS_ABSOLUTE ${main_file_dir}) + set(main_file_dir "${CMAKE_CURRENT_BINARY_DIR}/${main_file_dir}") + endif() + if (NOT IS_ABSOLUTE ${_WCD_OUTPUT_DIR}) + set(_WCD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_WCD_OUTPUT_DIR}") + endif() + get_filename_component(out_file_dir ${_WCD_OUTPUT_DIR} ABSOLUTE) + string(FIND ${out_file_dir} ${main_file_dir} idx) + if (NOT idx EQUAL 0) + message(FATAL_ERROR "The compiler-specific output directory must be within the same directory as the main file.") + endif() + + if (main_file_dir STREQUAL out_file_dir) + unset(_WCD_OUTPUT_DIR) + else() + string(REPLACE "${main_file_dir}/" "" _WCD_OUTPUT_DIR "${out_file_dir}/") + endif() + endif() + set(compilers GNU Clang + AppleClang ) set(_hex_compilers ADSP Borland Embarcadero SunPro) @@ -314,6 +373,14 @@ function(write_compiler_detection_header endforeach() list(REMOVE_DUPLICATES _langs) + if(_WCD_OUTPUT_FILES_VAR) + get_filename_component(main_file_name ${file_arg} NAME) + set(compiler_file_content_ +"#ifndef ${prefix_arg}_COMPILER_DETECTION_H +# error This file may only be included from ${main_file_name} +#endif\n") + endif() + foreach(_lang ${_langs}) get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES) @@ -340,7 +407,19 @@ function(write_compiler_detection_header foreach(compiler ${_WCD_COMPILERS}) _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features}) set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n") - set(file_content "${file_content} + + if(_WCD_OUTPUT_FILES_VAR) + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}.h") + set(file_content "${file_content}\n# include \"${compile_file_name}\"\n") + endif() + + if(_WCD_OUTPUT_FILES_VAR) + set(compiler_file_content compiler_file_content_${compiler}) + else() + set(compiler_file_content file_content) + endif() + + set(${compiler_file_content} "${${compiler_file_content}} # if !(${_cmake_oldestSupported_${compiler}}) # error Unsupported compiler version # endif\n") @@ -354,7 +433,7 @@ function(write_compiler_detection_header set(MACRO_HEX) endif() string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY) - set(file_content "${file_content}${VERSION_BLOCK}\n") + set(${compiler_file_content} "${${compiler_file_content}}${VERSION_BLOCK}\n") set(PREFIX) set(MACRO_DEC) set(MACRO_HEX) @@ -370,7 +449,7 @@ function(write_compiler_detection_header set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n") set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n") endif() - set(file_content "${file_content}${_define_item}") + set(${compiler_file_content} "${${compiler_file_content}}${_define_item}") endforeach() endforeach() if(pp_if STREQUAL "elif") @@ -436,7 +515,7 @@ function(write_compiler_detection_header set(file_content "${file_content} # if ${def_name} # define ${def_value} alignas(X) -# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang # define ${def_value} __attribute__ ((__aligned__(X))) # else # define ${def_value} @@ -448,7 +527,7 @@ function(write_compiler_detection_header set(file_content "${file_content} # if ${def_name} # define ${def_value} alignof(X) -# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang # define ${def_value} __alignof__(X) # endif \n") @@ -495,6 +574,20 @@ function(write_compiler_detection_header # endif \n") endif() + if (feature STREQUAL cxx_thread_local) + set(def_value "${prefix_arg}_THREAD_LOCAL") + set(file_content "${file_content} +# if ${def_name} +# define ${def_value} thread_local +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang +# define ${def_value} __thread +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __declspec(thread) +# else +// ${def_value} not defined for this configuration. +# endif +\n") + endif() if (feature STREQUAL cxx_attribute_deprecated) set(def_name ${prefix_arg}_${feature_PP}) set(def_value "${prefix_arg}_DEPRECATED") @@ -522,6 +615,22 @@ function(write_compiler_detection_header endforeach() + if(_WCD_OUTPUT_FILES_VAR) + foreach(compiler ${_WCD_COMPILERS}) + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}") + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}${compiler_file_content_${compiler}}") + + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}.h") + set(full_path "${main_file_dir}/${compile_file_name}") + list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path}) + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${full_path}" + @ONLY + ) + endforeach() + set(${_WCD_OUTPUT_FILES_VAR} ${${_WCD_OUTPUT_FILES_VAR}} PARENT_SCOPE) + endif() + if (_WCD_EPILOG) set(file_content "${file_content}\n${_WCD_EPILOG}\n") endif() |