diff options
67 files changed, 991 insertions, 50 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d3c424b..bdc160d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES) # Allow the user to enable/disable all system utility library options by # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}. - set(UTILITIES BZIP2 CURL EXPAT FORM LIBARCHIVE LIBLZMA ZLIB) + set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA ZLIB) foreach(util ${UTILITIES}) if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util} AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES) @@ -104,6 +104,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES) CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma" "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON) option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}") + option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}") # Mention to the user what system libraries are being used. foreach(util ${UTILITIES}) @@ -373,8 +374,24 @@ macro (CMAKE_BUILD_UTILITIES) #--------------------------------------------------------------------- # Build jsoncpp library. - add_subdirectory(Utilities/cmjsoncpp) - CMAKE_SET_TARGET_FOLDER(cmjsoncpp "Utilities/3rdParty") + if(CMAKE_USE_SYSTEM_JSONCPP) + if(EXISTS ${CMAKE_ROOT}/Modules/FindJsonCpp.cmake) + find_package(JsonCpp) + elseif(NOT CMAKE_VERSION VERSION_LESS 3.0) + include(${CMake_SOURCE_DIR}/Modules/FindJsonCpp.cmake) + else() + message(FATAL_ERROR "CMAKE_USE_SYSTEM_JSONCPP requires CMake >= 3.0") + endif() + if(NOT JsonCpp_FOUND) + message(FATAL_ERROR + "CMAKE_USE_SYSTEM_JSONCPP is ON but a JsonCpp is not found!") + endif() + set(CMAKE_JSONCPP_LIBRARIES JsonCpp::JsonCpp) + else() + set(CMAKE_JSONCPP_LIBRARIES cmjsoncpp) + add_subdirectory(Utilities/cmjsoncpp) + CMAKE_SET_TARGET_FOLDER(cmjsoncpp "Utilities/3rdParty") + endif() #--------------------------------------------------------------------- # Build XMLRPC library for CMake and CTest. diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index d9b0b78..2b83ed9 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -37,3 +37,16 @@ timed-out submission before attempting to re-submit. The RETRY_COUNT option specifies how many times to retry a timed-out submission. + +Submit to CDash Upload API +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]) + +This second signature is used to upload files to CDash via the CDash +file upload API. The api first sends a request to upload to CDash along +with a content hash of the file. If CDash does not already have the file, +then it is uploaded. Along with the file, a CDash type string is specified +to tell CDash which handler to use to process the data. diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 0a0ca23..db56010 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -63,6 +63,7 @@ All Modules /module/CPack /module/CPackWIX /module/CTest + /module/CTestCoverageCollectGCOV /module/CTestScriptMode /module/CTestUseLaunchers /module/Dart diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index af2c348..c342dbe 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -181,6 +181,7 @@ Variables that Describe the System /variable/CMAKE_SYSTEM_VERSION /variable/CYGWIN /variable/ENV + /variable/MINGW /variable/MSVC10 /variable/MSVC11 /variable/MSVC12 diff --git a/Help/module/CTestCoverageCollectGCOV.rst b/Help/module/CTestCoverageCollectGCOV.rst new file mode 100644 index 0000000..4c5deca --- /dev/null +++ b/Help/module/CTestCoverageCollectGCOV.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CTestCoverageCollectGCOV.cmake diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst new file mode 100644 index 0000000..521d417 --- /dev/null +++ b/Help/variable/MINGW.rst @@ -0,0 +1,6 @@ +MINGW +----- + +True when using MinGW + +Set to true when the compiler is some version of MinGW. diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake new file mode 100644 index 0000000..f6616e0 --- /dev/null +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -0,0 +1,138 @@ +#.rst: +# CTestCoverageCollectGCOV +# ------------------------ +# +# This module provides the function ``ctest_coverage_collect_gcov``. +# The function will run gcov on the .gcda files in a binary tree and then +# package all of the .gcov files into a tar file with a data.json that +# contains the source and build directories for CDash to use in parsing +# the coverage data. In addtion the Labels.json files for targets that +# have coverage information are also put in the tar file for CDash to +# asign the correct labels. This file can be sent to a CDash server for +# display with the +# :command:`ctest_submit(CDASH_UPLOAD)` command. +# +# .. command:: cdash_coverage_collect_gcov +# +# :: +# +# ctest_coverage_collect_gcov(TARBALL <tarfile> +# [SOURCE <source_dir>][BUILD <build_dir>] +# [GCOV_COMMAND <gcov_command>] +# ) +# +# Run gcov and package a tar file for CDash. The options are: +# +# ``TARBALL <tarfile>`` +# Specify the location of the ``.tar`` file to be created for later +# upload to CDash. Relative paths will be interpreted with respect +# to the top-level build directory. +# +# ``SOURCE <source_dir>`` +# Specify the top-level source directory for the build. +# Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`. +# +# ``BUILD <build_dir>`` +# Specify the top-level build directory for the build. +# Default is the value of :variable:`CTEST_BINARY_DIRECTORY`. +# +# ``GCOV_COMMAND <gcov_command>`` +# Specify the full path to the ``gcov`` command on the machine. +# Default is the value of :variable:`CTEST_COVERAGE_COMMAND`. + +#============================================================================= +# 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.) +include(CMakeParseArguments) +function(ctest_coverage_collect_gcov) + set(options "") + set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND) + set(multiValueArgs "") + cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}" + "${multiValueArgs}" "" ${ARGN} ) + if(NOT DEFINED GCOV_TARBALL) + message(FATAL_ERROR + "TARBALL must be specified. for ctest_coverage_collect_gcov") + endif() + if(NOT DEFINED GCOV_SOURCE) + set(source_dir "${CTEST_SOURCE_DIRECTORY}") + else() + set(source_dir "${GCOV_SOURCE}") + endif() + if(NOT DEFINED GCOV_BUILD) + set(binary_dir "${CTEST_BINARY_DIRECTORY}") + else() + set(binary_dir "${GCOV_BUILD}") + endif() + if(NOT DEFINED GCOV_GCOV_COMMAND) + set(gcov_command "${CTEST_COVERAGE_COMMAND}") + else() + set(gcov_command "${GCOV_GCOV_COMMAND}") + endif() + # run gcov on each gcda file in the binary tree + set(gcda_files) + set(label_files) + # look for gcda files in the target directories + # could do a glob from the top of the binary tree but + # this will be faster and only look where the files will be + file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs) + foreach(target_dir ${target_dirs}) + file(GLOB_RECURSE gfiles RELATIVE ${binary_dir} "${target_dir}/*.gcda") + list(LENGTH gfiles len) + # if we have gcda files then also grab the labels file for that target + if(${len} GREATER 0) + file(GLOB_RECURSE lfiles RELATIVE ${binary_dir} + "${target_dir}/Labels.json") + list(APPEND gcda_files ${gfiles}) + list(APPEND label_files ${lfiles}) + endif() + endforeach() + # return early if no coverage files were found + list(LENGTH gcda_files len) + if(len EQUAL 0) + message("ctest_coverage_collect_gcov: No .gcda files found, " + "ignoring coverage request.") + return() + endif() + # setup the dir for the coverage files + set(coverage_dir "${binary_dir}/Testing/CoverageInfo") + file(MAKE_DIRECTORY "${coverage_dir}") + # call gcov on each .gcda file + foreach (gcda_file ${gcda_files}) + # get the directory of the gcda file + get_filename_component(gcda_file ${binary_dir}/${gcda_file} ABSOLUTE) + get_filename_component(gcov_dir ${gcda_file} DIRECTORY) + # run gcov, this will produce the .gcov file in the current + # working directory + execute_process(COMMAND + ${gcov_command} -b -o ${gcov_dir} ${gcda_file} + OUTPUT_VARIABLE out + WORKING_DIRECTORY ${coverage_dir}) + endforeach() + # create json file with project information + file(WRITE ${coverage_dir}/data.json + "{ + \"Source\": \"${source_dir}\", + \"Binary\": \"${binary_dir}\" +}") + # collect the gcov files + set(gcov_files) + file(GLOB_RECURSE gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov") + # tar up the coverage info with the same date so that the md5 + # sum will be the same for the tar file independent of file time + # stamps + execute_process(COMMAND + ${CMAKE_COMMAND} -E tar cvfj ${GCOV_TARBALL} + "--mtime=1970-01-01 0:0:0 UTC" ${gcov_files} + ${coverage_dir}/data.json ${label_files} + WORKING_DIRECTORY ${binary_dir}) +endfunction() diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake index 3036057..fa97a94 100644 --- a/Modules/Compiler/GNU-C.cmake +++ b/Modules/Compiler/GNU-C.cmake @@ -1,10 +1,15 @@ include(Compiler/GNU) __compiler_gnu(C) -if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") +elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89") +endif() +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") endif() @@ -12,7 +17,7 @@ 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.4) +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() @@ -29,8 +34,10 @@ macro(cmake_record_c_compile_features) endmacro() set(_result 0) - if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) _get_gcc_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) + endif() + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) if (_result EQUAL 0) _get_gcc_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) endif() diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index 9016db8..3eea9db 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -40,7 +40,7 @@ # [FATAL_ON_MISSING_REQUIRED_PACKAGES] # [DESCRIPTION "Found packages:"] # WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND -# | ENABLED_FEATURES | DISABLED_FEATURES] +# | ENABLED_FEATURES | DISABLED_FEATURES) # ) # # @@ -265,7 +265,7 @@ # Does the same as SET_PACKAGE_INFO(<name> <description> <url> ) #============================================================================= -# Copyright 2007-2009 Kitware, Inc. +# Copyright 2007-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 435b654..c04cf9a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -503,7 +503,7 @@ target_link_libraries(CMakeLib cmsys ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES} ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES} ${CMAKE_CURL_LIBRARIES} - cmjsoncpp + ${CMAKE_JSONCPP_LIBRARIES} ) # On Apple we need CoreFoundation @@ -537,6 +537,7 @@ set(CTEST_SRCS cmCTest.cxx CTest/cmCTestConfigureHandler.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx + CTest/cmCTestCurl.cxx CTest/cmParseMumpsCoverage.cxx CTest/cmParseCacheCoverage.cxx CTest/cmParseGTMCoverage.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4536390..25cde98 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 1) -set(CMake_VERSION_PATCH 20150121) +set(CMake_VERSION_PATCH 20150123) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx new file mode 100644 index 0000000..b0d26cc --- /dev/null +++ b/Source/CTest/cmCTestCurl.cxx @@ -0,0 +1,271 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-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. +============================================================================*/ +#include "cmCTestCurl.h" + +#include "cmSystemTools.h" +#include "cmCTest.h" + +cmCTestCurl::cmCTestCurl(cmCTest* ctest) +{ + this->CTest = ctest; + this->SetProxyType(); + this->UseHttp10 = false; + // In windows, this will init the winsock stuff + ::curl_global_init(CURL_GLOBAL_ALL); + // default is to verify https + this->VerifyPeerOff = false; + this->VerifyHostOff = false; + this->TimeOutSeconds = 0; +} + +namespace +{ +static size_t +curlWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, + void *data) +{ + int realsize = (int)(size * nmemb); + + std::vector<char> *vec + = static_cast<std::vector<char>* >(data); + const char* chPtr = static_cast<char*>(ptr); + vec->insert(vec->end(), chPtr, chPtr + realsize); + return realsize; +} + +static size_t +curlDebugCallback(CURL *, curl_infotype, char *chPtr, + size_t size, void *data) +{ + std::vector<char> *vec + = static_cast<std::vector<char>* >(data); + vec->insert(vec->end(), chPtr, chPtr + size); + + return size; +} + +} + +void cmCTestCurl::SetCurlOptions(std::vector<std::string> const& args) +{ + for( std::vector<std::string>::const_iterator i = args.begin(); + i != args.end(); ++i) + { + if(*i == "CURLOPT_SSL_VERIFYPEER_OFF") + { + this->VerifyPeerOff = true; + } + if(*i == "CURLOPT_SSL_VERIFYHOST_OFF") + { + this->VerifyHostOff = true; + } + } +} + +bool cmCTestCurl::InitCurl() +{ + this->Curl = curl_easy_init(); + if(!this->Curl) + { + return false; + } + if(this->VerifyPeerOff) + { + curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYPEER, 0); + } + if(this->VerifyHostOff) + { + curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYHOST, 0); + } + if(this->HTTPProxy.size()) + { + curl_easy_setopt(this->Curl, CURLOPT_PROXY, this->HTTPProxy.c_str()); + curl_easy_setopt(this->Curl, CURLOPT_PROXYTYPE, this->HTTPProxyType); + if (this->HTTPProxyAuth.size() > 0) + { + curl_easy_setopt(this->Curl, CURLOPT_PROXYUSERPWD, + this->HTTPProxyAuth.c_str()); + } + } + if(this->UseHttp10) + { + curl_easy_setopt(this->Curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + } + // enable HTTP ERROR parsing + curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + return true; +} + + +bool cmCTestCurl::UploadFile(std::string const& local_file, + std::string const& url, + std::string const& fields, + std::string& response) +{ + response = ""; + if(!this->InitCurl()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed"); + return false; + } + /* enable uploading */ + curl_easy_setopt(this->Curl, CURLOPT_UPLOAD, 1); + // if there is little to no activity for too long stop submitting + if(this->TimeOutSeconds) + { + ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_LIMIT, 1); + ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_TIME, + this->TimeOutSeconds); + } + /* HTTP PUT please */ + ::curl_easy_setopt(this->Curl, CURLOPT_PUT, 1); + ::curl_easy_setopt(this->Curl, CURLOPT_VERBOSE, 1); + + FILE* ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); + if(!ftpfile) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Could not open file for upload: " << local_file << "\n"); + return false; + } + // set the url + std::string upload_url = url; + upload_url += "?"; + upload_url += fields; + ::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str()); + // now specify which file to upload + ::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile); + unsigned long filelen = cmSystemTools::FileLength(local_file); + // and give the size of the upload (optional) + ::curl_easy_setopt(this->Curl, CURLOPT_INFILESIZE, + static_cast<long>(filelen)); + ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION, + curlWriteMemoryCallback); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, + curlDebugCallback); + std::vector<char> responseData; + std::vector<char> debugData; + ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData); + ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + // Now run off and do what you've been told! + ::curl_easy_perform(this->Curl); + ::fclose(ftpfile); + ::curl_global_cleanup(); + + if ( responseData.size() > 0 ) + { + response = std::string(responseData.begin(), responseData.end()); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Curl response: [" << response << "]\n"); + } + std::string curlDebug; + if ( debugData.size() > 0 ) + { + curlDebug = std::string(debugData.begin(), debugData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + } + if(response.size() == 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "No response from server.\n" << + curlDebug); + return false; + } + return true; +} + +bool cmCTestCurl::HttpRequest(std::string const& url, + std::string const& fields, + std::string& response) +{ + response = ""; + cmCTestLog(this->CTest, DEBUG, "HttpRequest\n" + << "url: " << url << "\n" + << "fields " << fields << "\n"); + if(!this->InitCurl()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed"); + return false; + } + curl_easy_setopt(this->Curl, CURLOPT_POST, 1); + curl_easy_setopt(this->Curl, CURLOPT_POSTFIELDS, fields.c_str()); + ::curl_easy_setopt(this->Curl, CURLOPT_URL, url.c_str()); + ::curl_easy_setopt(this->Curl, CURLOPT_FOLLOWLOCATION, 1); + //set response options + ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION, + curlWriteMemoryCallback); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, + curlDebugCallback); + std::vector<char> responseData; + std::vector<char> debugData; + ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData); + ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + + CURLcode res = ::curl_easy_perform(this->Curl); + + ::curl_easy_cleanup(this->Curl); + ::curl_global_cleanup(); + if ( responseData.size() > 0 ) + { + response = std::string(responseData.begin(), responseData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl response: [" << response << "]\n"); + } + if ( debugData.size() > 0 ) + { + std::string curlDebug = std::string(debugData.begin(), debugData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + } + cmCTestLog(this->CTest, DEBUG, "Curl res: " << res << "\n"); + return (res == 0); +} + +void cmCTestCurl::SetProxyType() +{ + if ( cmSystemTools::GetEnv("HTTP_PROXY") ) + { + this->HTTPProxy = cmSystemTools::GetEnv("HTTP_PROXY"); + if ( cmSystemTools::GetEnv("HTTP_PROXY_PORT") ) + { + this->HTTPProxy += ":"; + this->HTTPProxy += cmSystemTools::GetEnv("HTTP_PROXY_PORT"); + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_TYPE") ) + { + // this is the default + this->HTTPProxyType = CURLPROXY_HTTP; + std::string type = cmSystemTools::GetEnv("HTTP_PROXY_TYPE"); + // HTTP/SOCKS4/SOCKS5 + if ( type == "HTTP" ) + { + this->HTTPProxyType = CURLPROXY_HTTP; + } + else if ( type == "SOCKS4" ) + { + this->HTTPProxyType = CURLPROXY_SOCKS4; + } + else if ( type == "SOCKS5" ) + { + this->HTTPProxyType = CURLPROXY_SOCKS5; + } + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_USER") ) + { + this->HTTPProxyAuth = cmSystemTools::GetEnv("HTTP_PROXY_USER"); + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_PASSWD") ) + { + this->HTTPProxyAuth += ":"; + this->HTTPProxyAuth += cmSystemTools::GetEnv("HTTP_PROXY_PASSWD"); + } + } +} diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h new file mode 100644 index 0000000..5bb8b41 --- /dev/null +++ b/Source/CTest/cmCTestCurl.h @@ -0,0 +1,52 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-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. +============================================================================*/ +#ifndef cmCTestCurl_h +#define cmCTestCurl_h + +#include "cmStandardIncludes.h" + +#include "cm_curl.h" + +class cmCTest; + +class cmCTestCurl +{ +public: + cmCTestCurl(cmCTest*); + bool UploadFile(std::string const& url, + std::string const& file, + std::string const& fields, + std::string& response); + bool HttpRequest(std::string const& url, + std::string const& fields, + std::string& response); + // currently only supports CURLOPT_SSL_VERIFYPEER_OFF + // and CURLOPT_SSL_VERIFYHOST_OFF + void SetCurlOptions(std::vector<std::string> const& args); + void SetUseHttp10On() { this->UseHttp10 = true;} + void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s;} +protected: + void SetProxyType(); + bool InitCurl(); +private: + cmCTest* CTest; + CURL* Curl; + std::string HTTPProxyAuth; + std::string HTTPProxy; + curl_proxytype HTTPProxyType; + bool VerifyHostOff; + bool VerifyPeerOff; + bool UseHttp10; + int TimeOutSeconds; +}; + +#endif diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 4005a63..cc3514f 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -27,7 +27,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() = this->Makefile->GetDefinition("CTEST_TRIGGER_SITE"); bool ctestDropSiteCDash = this->Makefile->IsOn("CTEST_DROP_SITE_CDASH"); - + const char* ctestProjectName + = this->Makefile->GetDefinition("CTEST_PROJECT_NAME"); if ( !ctestDropMethod ) { ctestDropMethod = "http"; @@ -43,7 +44,7 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() // error: CDash requires CTEST_DROP_LOCATION definition // in CTestConfig.cmake } - + this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName); this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod); this->CTest->SetCTestConfiguration("DropSite", ctestDropSite); this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation); @@ -144,44 +145,75 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() static_cast<cmCTestSubmitHandler*>(handler)->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF"); + if (this->CDashUpload) + { + static_cast<cmCTestSubmitHandler*>(handler)-> + SetOption("CDashUploadFile", this->CDashUploadFile.c_str()); + static_cast<cmCTestSubmitHandler*>(handler)-> + SetOption("CDashUploadType", this->CDashUploadType.c_str()); + } return handler; } +//---------------------------------------------------------------------------- +bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD"; + return this->cmCTestHandlerCommand::InitialPass(args, status); +} //---------------------------------------------------------------------------- bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) { - // Look for arguments specific to this command. - if(arg == "PARTS") + if (this->CDashUpload) { - this->ArgumentDoing = ArgumentDoingParts; - this->PartsMentioned = true; - return true; - } + if(arg == "CDASH_UPLOAD") + { + this->ArgumentDoing = ArgumentDoingCDashUpload; + return true; + } - if(arg == "FILES") - { - this->ArgumentDoing = ArgumentDoingFiles; - this->FilesMentioned = true; - return true; + if(arg == "CDASH_UPLOAD_TYPE") + { + this->ArgumentDoing = ArgumentDoingCDashUploadType; + return true; + } } - - if(arg == "RETRY_COUNT") + else { - this->ArgumentDoing = ArgumentDoingRetryCount; - return true; - } + // Look for arguments specific to this command. + if(arg == "PARTS") + { + this->ArgumentDoing = ArgumentDoingParts; + this->PartsMentioned = true; + return true; + } - if(arg == "RETRY_DELAY") - { - this->ArgumentDoing = ArgumentDoingRetryDelay; - return true; - } + if(arg == "FILES") + { + this->ArgumentDoing = ArgumentDoingFiles; + this->FilesMentioned = true; + return true; + } - if(arg == "INTERNAL_TEST_CHECKSUM") - { - this->InternalTest = true; - return true; + if(arg == "RETRY_COUNT") + { + this->ArgumentDoing = ArgumentDoingRetryCount; + return true; + } + + if(arg == "RETRY_DELAY") + { + this->ArgumentDoing = ArgumentDoingRetryDelay; + return true; + } + + if(arg == "INTERNAL_TEST_CHECKSUM") + { + this->InternalTest = true; + return true; + } } // Look for other arguments. @@ -240,6 +272,20 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) return true; } + if(this->ArgumentDoing == ArgumentDoingCDashUpload) + { + this->ArgumentDoing = ArgumentDoingNone; + this->CDashUploadFile = arg; + return true; + } + + if(this->ArgumentDoing == ArgumentDoingCDashUploadType) + { + this->ArgumentDoing = ArgumentDoingNone; + this->CDashUploadType = arg; + return true; + } + // Look for other arguments. return this->Superclass::CheckArgumentValue(arg); } diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 3673fbd..19e8eaf 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -32,6 +32,7 @@ public: this->InternalTest = false; this->RetryCount = ""; this->RetryDelay = ""; + this->CDashUpload = false; } /** @@ -45,6 +46,9 @@ public: return ni; } + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + /** * The name of the command as specified in CMakeList.txt. */ @@ -64,6 +68,8 @@ protected: ArgumentDoingFiles, ArgumentDoingRetryDelay, ArgumentDoingRetryCount, + ArgumentDoingCDashUpload, + ArgumentDoingCDashUploadType, ArgumentDoingLast2 }; @@ -74,6 +80,9 @@ protected: cmCTest::SetOfStrings Files; std::string RetryCount; std::string RetryDelay; + bool CDashUpload; + std::string CDashUploadFile; + std::string CDashUploadType; }; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index bc6fb31..11e3343 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -10,7 +10,8 @@ See the License for more information. ============================================================================*/ #include "cmCTestSubmitHandler.h" - +#include "cmCTestScriptHandler.h" +#include "cmake.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmGeneratedFileStream.h" @@ -23,8 +24,10 @@ // For XML-RPC submission #include "cm_xmlrpc.h" +#include <cm_jsoncpp_reader.h> // For curl submission #include "cm_curl.h" +#include "cmCTestCurl.h" #include <sys/stat.h> @@ -1055,9 +1058,171 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(std::string const&, } #endif +void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod, + std::string& url) +{ + dropMethod = this->CTest->GetCTestConfiguration("DropMethod"); + url = dropMethod; + url += "://"; + if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) + { + url += this->CTest->GetCTestConfiguration("DropSiteUser"); + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetCTestConfiguration("DropSiteUser").c_str()); + if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 ) + { + url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); + cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); + } + url += "@"; + } + url += this->CTest->GetCTestConfiguration("DropSite") + + this->CTest->GetCTestConfiguration("DropLocation"); +} + + +int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, + std::string const& typeString) +{ + if (file.empty()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Upload file not specified\n"); + return -1; + } + if (!cmSystemTools::FileExists(file)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Upload file not found: '" << file << "'\n"); + return -1; + } + cmCTestCurl curl(this->CTest); + std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); + std::vector<std::string> args; + cmSystemTools::ExpandListArgument(curlopt, args); + curl.SetCurlOptions(args); + curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); + std::string dropMethod; + std::string url; + this->ConstructCDashURL(dropMethod, url); + std::string::size_type pos = url.find("submit.php?"); + url = url.substr(0, pos+10); + if ( ! (dropMethod == "http" || dropMethod == "https" ) ) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Only http and https are supported for CDASH_UPLOAD\n"); + return -1; + } + char md5sum[33]; + md5sum[32] = 0; + cmSystemTools::ComputeFileMD5(file, md5sum); + // 1. request the buildid and check to see if the file + // has already been uploaded + // TODO I added support for subproject. You would need to add + // a "&subproject=subprojectname" to the first POST. + cmCTestScriptHandler* ch = + static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); + cmake* cm = ch->GetCMake(); + const char* subproject = cm->GetProperty("SubProject", cmProperty::GLOBAL); + // TODO: Encode values for a URL instead of trusting caller. + std::ostringstream str; + str << "project=" + << this->CTest->GetCTestConfiguration("ProjectName") << "&"; + if(subproject) + { + str << "subproject=" << subproject << "&"; + } + str << "stamp=" << this->CTest->GetCurrentTag() << "-" + << this->CTest->GetTestModelString() << "&" + << "model=" << this->CTest->GetTestModelString() << "&" + << "build=" << this->CTest->GetCTestConfiguration("BuildName") << "&" + << "site=" << this->CTest->GetCTestConfiguration("Site") << "&" + << "track=" << this->CTest->GetTestModelString() << "&" + << "starttime=" << (int)cmSystemTools::GetTime() << "&" + << "endtime=" << (int)cmSystemTools::GetTime() << "&" + << "datafilesmd5[0]=" << md5sum << "&" + << "type=" << typeString; + std::string fields = str.str(); + cmCTestLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:" + << url << "\nfile: " << file << "\n"); + std::string response; + if(!curl.HttpRequest(url, fields, response)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error in HttpRequest\n" << response); + return -1; + } + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Request upload response: [" << response << "]\n"); + Json::Value json; + Json::Reader reader; + if(!reader.parse(response, json)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error parsing json string [" << response << "]\n" + << reader.getFormattedErrorMessages() << "\n"); + return -1; + } + if(json["status"].asInt() != 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad status returned from CDash: " + << json["status"].asInt()); + return -1; + } + if(json["datafilesmd5"].isArray()) + { + int datares = json["datafilesmd5"][0].asInt(); + if(datares == 1) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "File already exists on CDash, skip upload " + << file << "\n"); + return 0; + } + } + else + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "bad datafilesmd5 value in response " + << response << "\n"); + return -1; + } + + std::string upload_as = cmSystemTools::GetFilenameName(file); + std::ostringstream fstr; + fstr << "type=" << typeString << "&" + << "md5=" << md5sum << "&" + << "filename=" << upload_as << "&" + << "buildid=" << json["buildid"].asString(); + if(!curl.UploadFile(file, url, fstr.str(), response)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error uploading to CDash. " + << file << " " << url << " " << fstr.str()); + return -1; + } + if(!reader.parse(response, json)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error parsing json string [" << response << "]\n" + << reader.getFormattedErrorMessages() << "\n"); + return -1; + } + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Upload file response: [" << response << "]\n"); + return 0; +} + //---------------------------------------------------------------------------- int cmCTestSubmitHandler::ProcessHandler() { + const char* cdashUploadFile = this->GetOption("CDashUploadFile"); + const char* cdashUploadType = this->GetOption("CDashUploadType"); + if(cdashUploadFile && cdashUploadType) + { + return this->HandleCDashUploadFile(cdashUploadFile, cdashUploadType); + } std::string iscdash = this->CTest->GetCTestConfiguration("IsCDash"); // cdash does not need to trigger so just return true if(!iscdash.empty()) diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index accabd1..f9cd894 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -41,6 +41,11 @@ public: /** Specify a set of files to submit. */ void SelectFiles(cmCTest::SetOfStrings const& files); + // handle the cdash file upload protocol + int HandleCDashUploadFile(std::string const& file, std::string const& type); + + void ConstructCDashURL(std::string& dropMethod, std::string& url); + private: void SetLogFile(std::ostream* ost) { this->LogFile = ost; } diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in index 45425ff..37055d6 100644 --- a/Source/kwsys/FStream.hxx.in +++ b/Source/kwsys/FStream.hxx.in @@ -18,6 +18,11 @@ namespace @KWSYS_NAMESPACE@ { #if defined(_MSC_VER) && _MSC_VER >= 1400 +# if defined(_NOEXCEPT) +# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT +# else +# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT +# endif template<typename CharType,typename Traits> class basic_filebuf : public std::basic_filebuf<CharType,Traits> { @@ -85,7 +90,7 @@ namespace @KWSYS_NAMESPACE@ return buf_; } - ~basic_ifstream() + ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { buf_->close(); delete buf_; @@ -147,7 +152,7 @@ class basic_ofstream : public std::basic_ostream<CharType,Traits> { return buf_.get(); } - ~basic_ofstream() + ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { buf_->close(); delete buf_; @@ -160,6 +165,7 @@ class basic_ofstream : public std::basic_ostream<CharType,Traits> typedef basic_ifstream<char> ifstream; typedef basic_ofstream<char> ofstream; +# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT #else using @KWSYS_NAMESPACE@_ios_namespace::ofstream; using @KWSYS_NAMESPACE@_ios_namespace::ifstream; diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index ef71f26..c2965ea 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -340,7 +340,11 @@ kwsysProcess* kwsysProcess_New(void) osv.dwOSVersionInfoSize = sizeof(osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif GetVersionEx(&osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx @@ -2382,7 +2386,11 @@ static kwsysProcess_List* kwsysProcess_List_New(void) osv.dwOSVersionInfoSize = sizeof(osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif GetVersionEx(&osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 3d5e728..9c7ceee 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -5069,7 +5069,11 @@ bool SystemInformationImplementation::QueryOSInformation() osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif bOsVersionInfoEx = GetVersionExW ((OSVERSIONINFOW*)&osvi); if (!bOsVersionInfoEx) diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index c2b6097..2708211 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -4732,7 +4732,11 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi); if (!bOsVersionInfoEx) diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt index 5cd0836..aacf4c1 100644 --- a/Tests/CompileFeatures/CMakeLists.txt +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -63,6 +63,14 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5) + # The cxx_raw_string_literals feature happens to work in some distributions + # of GNU 4.4, but it is first documented as available with GNU 4.5. + list(REMOVE_ITEM CXX_non_features + cxx_raw_string_literals + ) +endif() +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) # The cxx_constexpr feature happens to work (for *this* testcase) with # GNU 4.5, but it is first documented as available with GNU 4.6. @@ -103,8 +111,9 @@ foreach(lang CXX C) try_compile(${feature}_works "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test" "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}" - COMPILE_DEFINITIONS "-DTEST=${CMAKE_CURRENT_SOURCE_DIR}/${feature}.${${lang}_ext}" + COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}" CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}" + "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE OUTPUT ) if (${feature}_works) diff --git a/Tests/CompileFeatures/feature_test.c b/Tests/CompileFeatures/feature_test.c new file mode 100644 index 0000000..4147f1f --- /dev/null +++ b/Tests/CompileFeatures/feature_test.c @@ -0,0 +1,10 @@ + +#define STRINGIFY_IMPL(X) #X +#define STRINGIFY(X) STRINGIFY_IMPL(X) + +#include STRINGIFY(TEST) + +int main(void) +{ + return 0; +} diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index b5e46c0..78c4a6a 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt @@ -71,7 +71,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") add_executable(C_undefined c_undefined.c) - set_property(TARGET C_undefined PROPERTY CXX_STANDARD 90) + set_property(TARGET C_undefined PROPERTY C_STANDARD 90) target_compile_options(C_undefined PRIVATE -Werror=undef) endif() diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp index 82b2191..192094c 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/main.cpp +++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp @@ -4,6 +4,10 @@ #define PREFIX TEST #include "compile_tests.h" +#ifdef TEST_COMPILER_C_STATIC_ASSERT +#error Expect no C features defined +#endif + int main() { return 0; diff --git a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp index ca29823..1635091 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp +++ b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp @@ -4,6 +4,10 @@ #define PREFIX MULTI #include "compile_tests.h" +#ifdef MULTI_COMPILER_C_STATIC_ASSERT +#error Expect no C features defined +#endif + int main() { return 0; diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt new file mode 100644 index 0000000..48177e2 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadFILES/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "FILES". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt new file mode 100644 index 0000000..77df44f --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt @@ -0,0 +1 @@ +Only http and https are supported for CDASH_UPLOAD diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt new file mode 100644 index 0000000..af95b5c --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt @@ -0,0 +1 @@ +Upload file not specified diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt new file mode 100644 index 0000000..497ead2 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadPARTS/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "PARTS". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt new file mode 100644 index 0000000..8c4e6b1 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "RETRY_COUNT". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt new file mode 100644 index 0000000..6c56399 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "RETRY_DELAY". diff --git a/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in b/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in index f0e1653..378a85a 100644 --- a/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in +++ b/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in @@ -3,3 +3,4 @@ set(CTEST_PROJECT_NAME "CTestSubmit@CASE_NAME@") # Intentionally leave out other upload-related CTestConfig.cmake settings # so that any ctest_submit calls fail with an error message. set(CTEST_DROP_METHOD "@CASE_DROP_METHOD@") +set(CTEST_DROP_SITE "@CASE_DROP_SITE@") diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt new file mode 100644 index 0000000..b451315 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt @@ -0,0 +1,4 @@ +Missing arguments for submit via cp: +.* + Problems when submitting via CP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-cp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt new file mode 100644 index 0000000..fa6e004 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt @@ -0,0 +1 @@ +Submit files \(using cp\) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt new file mode 100644 index 0000000..a622fac --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via FTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-ftp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt new file mode 100644 index 0000000..345bb62 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using ftp\) + Using FTP submit method + Drop site: ftp:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt new file mode 100644 index 0000000..6870d2e --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via HTTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-http/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt new file mode 100644 index 0000000..c7f35c5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using http\) + Using HTTP submit method + Drop site:http:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt new file mode 100644 index 0000000..a3c0cd5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via HTTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-https/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt new file mode 100644 index 0000000..19f8234 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using https\) + Using HTTP submit method + Drop site:https:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt new file mode 100644 index 0000000..42b8f50 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt @@ -0,0 +1,2 @@ + Problems when submitting via SCP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-scp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt new file mode 100644 index 0000000..ec2ce92 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt @@ -0,0 +1 @@ +Submit files \(using scp\) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt new file mode 100644 index 0000000..020b615 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt @@ -0,0 +1,2 @@ + (Problems when submitting via XML-RPC|Submission method "xmlrpc" not compiled into CTest!) +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt new file mode 100644 index 0000000..ed2acb5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt @@ -0,0 +1 @@ +Submit files \(using xmlrpc\) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt new file mode 100644 index 0000000..dfa7e33 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/PARTSCDashUpload/test.cmake:[0-9]+ \(ctest_submit\): + Part name "CDASH_UPLOAD" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt new file mode 100644 index 0000000..42becaf --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType/test.cmake:[0-9]+ \(ctest_submit\): + Part name "CDASH_UPLOAD_TYPE" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake b/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake index 6f18563..797365d 100644 --- a/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake @@ -2,6 +2,7 @@ include(RunCMake) # Default case parameters. set(CASE_DROP_METHOD "http") +set(CASE_DROP_SITE "-no-site-") set(CASE_CTEST_SUBMIT_ARGS "") function(run_ctest CASE_NAME) @@ -32,6 +33,19 @@ run_ctest_submit(BadArg bad-arg) run_ctest_submit(BadPARTS PARTS bad-part) run_ctest_submit(BadFILES FILES bad-file) run_ctest_submit(RepeatRETURN_VALUE RETURN_VALUE res RETURN_VALUE res) +run_ctest_submit(PARTSCDashUpload PARTS Configure CDASH_UPLOAD) +run_ctest_submit(PARTSCDashUploadType PARTS Configure CDASH_UPLOAD_TYPE) +run_ctest_submit(CDashUploadPARTS CDASH_UPLOAD bad-upload PARTS) +run_ctest_submit(CDashUploadFILES CDASH_UPLOAD bad-upload FILES) +run_ctest_submit(CDashUploadRETRY_COUNT CDASH_UPLOAD bad-upload RETRY_COUNT) +run_ctest_submit(CDashUploadRETRY_DELAY CDASH_UPLOAD bad-upload RETRY_DELAY) +run_ctest_submit(CDashUploadNone CDASH_UPLOAD) + +function(run_ctest_CDashUploadFTP) + set(CASE_DROP_METHOD ftp) + run_ctest_submit(CDashUploadFTP CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE}) +endfunction() +run_ctest_CDashUploadFTP() #----------------------------------------------------------------------------- # Test failed drops by various protocols @@ -40,4 +54,9 @@ function(run_ctest_submit_FailDrop CASE_DROP_METHOD) run_ctest(FailDrop-${CASE_DROP_METHOD}) endfunction() -# TODO: call run_ctest_submit_FailDrop() for each submission protocol +run_ctest_submit_FailDrop(cp) +run_ctest_submit_FailDrop(ftp) +run_ctest_submit_FailDrop(http) +run_ctest_submit_FailDrop(https) +run_ctest_submit_FailDrop(scp) +run_ctest_submit_FailDrop(xmlrpc) diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in index b883284..0cb6809 100644 --- a/Utilities/cmThirdParty.h.in +++ b/Utilities/cmThirdParty.h.in @@ -20,6 +20,7 @@ #cmakedefine CMAKE_USE_SYSTEM_LIBARCHIVE #cmakedefine CMAKE_USE_SYSTEM_LIBLZMA #cmakedefine CMAKE_USE_SYSTEM_FORM +#cmakedefine CMAKE_USE_SYSTEM_JSONCPP #cmakedefine CTEST_USE_XMLRPC #endif diff --git a/Utilities/cm_jsoncpp_reader.h b/Utilities/cm_jsoncpp_reader.h index d7cb50e..22f2d81 100644 --- a/Utilities/cm_jsoncpp_reader.h +++ b/Utilities/cm_jsoncpp_reader.h @@ -13,6 +13,11 @@ #define cm_jsoncpp_reader_h /* Use the jsoncpp library configured for CMake. */ -#include <cmjsoncpp/include/json/reader.h> +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/reader.h> +#else +# include <cmjsoncpp/include/json/reader.h> +#endif #endif diff --git a/Utilities/cm_jsoncpp_value.h b/Utilities/cm_jsoncpp_value.h index 15e1088..b4cf620 100644 --- a/Utilities/cm_jsoncpp_value.h +++ b/Utilities/cm_jsoncpp_value.h @@ -13,6 +13,11 @@ #define cm_jsoncpp_value_h /* Use the jsoncpp library configured for CMake. */ -#include <cmjsoncpp/include/json/value.h> +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/value.h> +#else +# include <cmjsoncpp/include/json/value.h> +#endif #endif diff --git a/Utilities/cm_jsoncpp_writer.h b/Utilities/cm_jsoncpp_writer.h index c410369..c99a0d0 100644 --- a/Utilities/cm_jsoncpp_writer.h +++ b/Utilities/cm_jsoncpp_writer.h @@ -13,6 +13,11 @@ #define cm_jsoncpp_writer_h /* Use the jsoncpp library configured for CMake. */ -#include <cmjsoncpp/include/json/writer.h> +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/writer.h> +#else +# include <cmjsoncpp/include/json/writer.h> +#endif #endif diff --git a/Utilities/cmcurl/README-CMake.txt b/Utilities/cmcurl/README-CMake.txt new file mode 100644 index 0000000..3f053d8 --- /dev/null +++ b/Utilities/cmcurl/README-CMake.txt @@ -0,0 +1,66 @@ +The Utilities/cmcurl directory contains a reduced distribution +of the curl source tree with only the library source code and +CMake build system. It is not a submodule; the actual content is part +of our source tree and changes can be made and committed directly. + +We update from upstream using Git's "subtree" merge strategy. A +special branch contains commits of upstream curl snapshots and +nothing else. No Git ref points explicitly to the head of this +branch, but it is merged into our history. + +Update curl from upstream as follows. Create a local branch to +explicitly reference the upstream snapshot branch head: + + git branch curl-upstream 3fe5d9bf + +Use a temporary directory to checkout the branch: + + mkdir curl-tmp + cd curl-tmp + git init + git pull .. curl-upstream + rm -rf * + +Now place the (reduced) curl content in this directory. See +instructions shown by + + git log 3fe5d9bf + +for help extracting the content from the upstream repo. Then run +the following commands to commit the new version. Substitute the +appropriate date and version number: + + git add --all + + GIT_AUTHOR_NAME='Curl Upstream' \ + GIT_AUTHOR_EMAIL='curl-library@cool.haxx.se' \ + GIT_AUTHOR_DATE='Wed Sep 10 08:07:58 2014 +0200' \ + git commit -m 'curl 7.38.0 (reduced)' && + git commit --amend + +Edit the commit message to describe the procedure used to obtain the +content. Then push the changes back up to the main local repository: + + git push .. HEAD:curl-upstream + cd .. + rm -rf curl-tmp + +Create a topic in the main repository on which to perform the update: + + git checkout -b update-curl master + +Merge the curl-upstream branch as a subtree: + + git merge -s recursive -X subtree=Utilities/cmcurl \ + curl-upstream + +If there are conflicts, resolve them and commit. Build and test the +tree. Commit any additional changes needed to succeed. + +Finally, run + + git rev-parse --short=8 curl-upstream + +to get the commit from which the curl-upstream branch must be started +on the next update. Edit the "git branch curl-upstream" line above to +record it, and commit this file. |