diff options
23 files changed, 273 insertions, 54 deletions
diff --git a/Help/cpack_gen/dmg.rst b/Help/cpack_gen/dmg.rst index 35320c2..cede0f2 100644 --- a/Help/cpack_gen/dmg.rst +++ b/Help/cpack_gen/dmg.rst @@ -54,10 +54,12 @@ on macOS: Directory where license and menu files for different languages are stored. Setting this causes CPack to look for a ``<language>.menu.txt`` and - ``<language>.license.txt`` file for every language defined in - ``CPACK_DMG_SLA_LANGUAGES``. If both this variable and + ``<language>.license.txt`` or ``<language>.license.rtf`` file for every + language defined in ``CPACK_DMG_SLA_LANGUAGES``. If both this variable and ``CPACK_RESOURCE_FILE_LICENSE`` are set, CPack will only look for the menu - files and use the same license file for all languages. + files and use the same license file for all languages. If both + ``<language>.license.txt`` and ``<language>.license.rtf`` exist, the ``.txt`` + file will be used. .. variable:: CPACK_DMG_SLA_LANGUAGES diff --git a/Help/release/dev/cpack-dmg-rtf-for-sla.rst b/Help/release/dev/cpack-dmg-rtf-for-sla.rst new file mode 100644 index 0000000..5941796 --- /dev/null +++ b/Help/release/dev/cpack-dmg-rtf-for-sla.rst @@ -0,0 +1,8 @@ +cpack-dmg-rtf-for-sla +--------------------- + +* The :cpack_gen:`CPack DragNDrop Generator` learned to handle + RTF formatted license files. When :variable:`CPACK_DMG_SLA_DIR` + variable is set, <language>.license.rtf is considered, but + only as a fallback when the plaintext (.txt) file is not found + in order to maintain backwards compatibility. diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 3b46ca5..f6f6320 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -458,12 +458,13 @@ if(NOT DEFINED CPACK_PACKAGE_VERSION) endif() _cpack_set_default(CPACK_PACKAGE_VENDOR "Humanity") +set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY "${CMAKE_PROJECT_NAME} built using CMake") if(CMAKE_PROJECT_DESCRIPTION) _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CMAKE_PROJECT_DESCRIPTION}") else() _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY - "${CMAKE_PROJECT_NAME} built using CMake") + "${CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY}") endif() if(CMAKE_PROJECT_HOMEPAGE_URL) _cpack_set_default(CPACK_PACKAGE_HOMEPAGE_URL diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake index a337926..997cc8d 100644 --- a/Modules/CheckLanguage.cmake +++ b/Modules/CheckLanguage.cmake @@ -63,12 +63,18 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" else() set(_D_CMAKE_GENERATOR_INSTANCE "") endif() + if(CMAKE_GENERATOR MATCHES "^(Xcode$|Green Hills MULTI$|Visual Studio)") + set(_D_CMAKE_MAKE_PROGRAM "") + else() + set(_D_CMAKE_MAKE_PROGRAM "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}") + endif() execute_process( WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang} COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR} -A "${CMAKE_GENERATOR_PLATFORM}" -T "${CMAKE_GENERATOR_TOOLSET}" ${_D_CMAKE_GENERATOR_INSTANCE} + ${_D_CMAKE_MAKE_PROGRAM} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE result diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake index e015a98..53cab1a 100644 --- a/Modules/FindGTest.cmake +++ b/Modules/FindGTest.cmake @@ -240,4 +240,15 @@ if(GTEST_FOUND) __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "RELEASE") __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "DEBUG") endif() + + # Add targets mapping the same library names as defined in + # GTest's CMake package config. + if(NOT TARGET GTest::gtest) + add_library(GTest::gtest INTERFACE IMPORTED) + target_link_libraries(GTest::gtest INTERFACE GTest::GTest) + endif() + if(NOT TARGET GTest::gtest_main) + add_library(GTest::gtest_main INTERFACE IMPORTED) + target_link_libraries(GTest::gtest_main INTERFACE GTest::Main) + endif() endif() diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index c74c324..14bb104 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -540,7 +540,8 @@ function(cpack_deb_prepare_package_vars) # Ok, description has set. According to the `Debian Policy Manual`_ the frist # line is a pacakge summary. Try to get it as well... # See also: https://www.debian.org/doc/debian-policy/ch-controlfields.html#description - elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY) + elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY AND + NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY STREQUAL CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY) # Merge summary w/ the detailed description string(PREPEND CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n") endif() diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 33cacf1..cb6ae43 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -436,7 +436,7 @@ macro(QT4_CREATE_TRANSLATION _qm_files) if(_my_sources) # make a .pro file to call lupdate on, so we don't make our commands too # long for some systems - get_filename_component(_ts_name ${_ts_file} NAME_WE) + get_filename_component(_ts_name ${_ts_file} NAME) set(_ts_pro ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lupdate.pro) set(_pro_srcs) foreach(_pro_src ${_my_sources}) @@ -463,13 +463,15 @@ endmacro() macro(QT4_ADD_TRANSLATION _qm_files) foreach (_current_FILE ${ARGN}) get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE) - get_filename_component(qm ${_abs_FILE} NAME_WE) - get_property(output_location SOURCE ${_abs_FILE} PROPERTY OUTPUT_LOCATION) + get_filename_component(qm ${_abs_FILE} NAME) + # everything before the last dot has to be considered the file name (including other dots) + string(REGEX REPLACE "\\.[^.]*$" "" FILE_NAME ${qm}) + get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION) if(output_location) file(MAKE_DIRECTORY "${output_location}") - set(qm "${output_location}/${qm}.qm") + set(qm "${output_location}/${FILE_NAME}.qm") else() - set(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm") + set(qm "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.qm") endif() add_custom_command(OUTPUT ${qm} diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 103129a..844ac9a 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 16) -set(CMake_VERSION_PATCH 20200124) +set(CMake_VERSION_PATCH 20200127) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 3516235..fe7abf4 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -138,11 +138,16 @@ int cmCPackDragNDropGenerator::InitializeInternal() } for (auto const& language : languages) { std::string license = slaDirectory + "/" + language + ".license.txt"; - if (!singleLicense && !cmSystemTools::FileExists(license)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Missing license file " << language << ".license.txt" - << std::endl); - return 0; + std::string license_rtf = slaDirectory + "/" + language + ".license.rtf"; + if (!singleLicense) { + if (!cmSystemTools::FileExists(license) && + !cmSystemTools::FileExists(license_rtf)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Missing license file " + << language << ".license.txt" + << " / " << language << ".license.rtf" << std::endl); + return 0; + } } std::string menu = slaDirectory + "/" + language + ".menu.txt"; if (!cmSystemTools::FileExists(menu)) { @@ -793,13 +798,29 @@ bool cmCPackDragNDropGenerator::WriteLicense( licenseLanguage = "English"; } + // License file + std::string license_format = "TEXT"; + std::string actual_license; + if (!licenseFile.empty()) { + if (cmHasLiteralSuffix(licenseFile, ".rtf")) { + license_format = "RTF "; + } + actual_license = licenseFile; + } else { + std::string license_wo_ext = + slaDirectory + "/" + licenseLanguage + ".license"; + if (cmSystemTools::FileExists(license_wo_ext + ".txt")) { + actual_license = license_wo_ext + ".txt"; + } else { + license_format = "RTF "; + actual_license = license_wo_ext + ".rtf"; + } + } + // License header - outputStream << "data 'TEXT' (" << licenseNumber << ", \"" << licenseLanguage - << "\") {\n"; + outputStream << "data '" << license_format << "' (" << licenseNumber + << ", \"" << licenseLanguage << "\") {\n"; // License body - std::string actual_license = !licenseFile.empty() - ? licenseFile - : (slaDirectory + "/" + licenseLanguage + ".license.txt"); cmsys::ifstream license_ifs; license_ifs.open(actual_license.c_str()); if (license_ifs.is_open()) { @@ -878,8 +899,9 @@ bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line, std::string* error) { const size_t max_line_length = 512; - for (size_t i = 0; i < line.size(); i += max_line_length) { - size_t line_length = max_line_length; + size_t line_length = max_line_length; + for (size_t i = 0; i < line.size(); i += line_length) { + line_length = max_line_length; if (i + line_length > line.size()) { line_length = line.size() - i; } else { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d1a3454..261413a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1969,7 +1969,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName, case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: case cmStateEnums::UNKNOWN_LIBRARY: - dep = target->GetLocation(config); + dep = target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact, + /*realname=*/true); return true; case cmStateEnums::OBJECT_LIBRARY: // An object library has no single file on which to depend. diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index dbdde48..1420f7c 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -683,9 +683,15 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop( if (!this->IsNMake() && !this->IsWatcomWMake() && !this->BorlandMakeCurlyHack) { // turn off RCS and SCCS automatic stuff from gmake - makefileStream - << "# Remove some rules from gmake that .SUFFIXES does not remove.\n" - << "SUFFIXES =\n\n"; + constexpr const char* vcs_rules[] = { + "%,v", "RCS/%", "RCS/%,v", "SCCS/s.%", "s.%", + }; + for (auto vcs_rule : vcs_rules) { + std::vector<std::string> vcs_depend; + vcs_depend.emplace_back(vcs_rule); + this->WriteMakeRule(makefileStream, "Disable VCS-based implicit rules.", + "%", vcs_depend, no_commands, false); + } } // Add a fake suffix to keep HP happy. Must be max 32 chars for SGI make. std::vector<std::string> depends; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index fd94bc9..6761c64 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -6,6 +6,7 @@ #include <set> #include <cm/memory> +#include <cm/vector> #include "windows.h" @@ -2811,6 +2812,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( case csproj: this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName, "CSharp"); + cm::erase_if(targetDefines, [](std::string const& def) { + return def.find('=') != std::string::npos; + }); break; } clOptions.AddDefines(targetDefines); diff --git a/Tests/CMakeLib/testCMExtAlgorithm.cxx b/Tests/CMakeLib/testCMExtAlgorithm.cxx index c731b72..b8319c3 100644 --- a/Tests/CMakeLib/testCMExtAlgorithm.cxx +++ b/Tests/CMakeLib/testCMExtAlgorithm.cxx @@ -1,5 +1,6 @@ #include <iostream> #include <memory> +#include <type_traits> #include <utility> #include <vector> diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 196fea3..53d56bf 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -566,3 +566,11 @@ add_custom_command( ) add_custom_target(depends_on_in_rel_source_path ALL DEPENDS "depends_on_in_rel_source_path.txt") + +add_library(mac_fw SHARED mac_fw.c) +set_target_properties(mac_fw PROPERTIES + FRAMEWORK 1 + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib + ) +add_custom_command(OUTPUT mac_fw.txt COMMAND ${CMAKE_COMMAND} -E touch mac_fw.txt DEPENDS mac_fw) +add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt) diff --git a/Tests/CustomCommand/mac_fw.c b/Tests/CustomCommand/mac_fw.c new file mode 100644 index 0000000..cb35b44 --- /dev/null +++ b/Tests/CustomCommand/mac_fw.c @@ -0,0 +1,4 @@ +int mac_fw(void) +{ + return 0; +} diff --git a/Tests/FindGTest/Test/CMakeLists.txt b/Tests/FindGTest/Test/CMakeLists.txt index b65b9d2..6537238 100644 --- a/Tests/FindGTest/Test/CMakeLists.txt +++ b/Tests/FindGTest/Test/CMakeLists.txt @@ -8,6 +8,10 @@ add_executable(test_gtest_tgt main.cxx) target_link_libraries(test_gtest_tgt GTest::Main) add_test(NAME test_gtest_tgt COMMAND test_gtest_tgt) +add_executable(test_gtest_tgt_upstream main.cxx) +target_link_libraries(test_gtest_tgt_upstream GTest::gtest_main) +add_test(NAME test_gtest_tgt_upstream COMMAND test_gtest_tgt_upstream) + add_executable(test_gtest_var main.cxx) target_include_directories(test_gtest_var PRIVATE ${GTEST_INCLUDE_DIRS}) target_link_libraries(test_gtest_var PRIVATE ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index 0fb0cc4..3be1fd0 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -38,7 +38,7 @@ run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_B run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT") run_cpack_test_subtests( DEB_DESCRIPTION - "CPACK_DEBIAN_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION_FILE;CPACK_NO_PACKAGE_DESCRIPTION" + "CPACK_DEBIAN_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION;CPACK_COMPONENT_COMP_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION_FILE;CPACK_NO_PACKAGE_DESCRIPTION" "DEB.DEB_DESCRIPTION" false "MONOLITHIC;COMPONENT" diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake index a8e2e7a..bfe2059 100644 --- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake @@ -58,6 +58,8 @@ if(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_PACKAGE_DESCRIPTION_FILE" AND PACKAGI string(APPEND _expected_description "\n ." ) elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_NO_PACKAGE_DESCRIPTION") set(_expected_description [[ Description: This is the summary line]]) +elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_COMPONENT_COMP_DESCRIPTION") + set(_expected_description [[ Description: One line description]]) endif() foreach(_file_no RANGE 1 ${EXPECTED_FILES_COUNT}) diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake index ce3f651..893eb01 100644 --- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake +++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake @@ -34,6 +34,16 @@ elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_PACKAGE_DESCRIPTION") set(CPACK_PACKAGE_DESCRIPTION "${_description}") endif() +elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_COMPONENT_COMP_DESCRIPTION") + # NOTE Documented fallback variable without CPACK_PACKAGE_DESCRIPTION_SUMMARY + if(PACKAGING_TYPE STREQUAL "COMPONENT") + set(CPACK_COMPONENT_SATU_DESCRIPTION "One line description") + set(CPACK_COMPONENT_DUA_DESCRIPTION "One line description") + else() + set(CPACK_PACKAGE_DESCRIPTION "One line description") + endif() + unset(CPACK_PACKAGE_DESCRIPTION_SUMMARY) + elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_PACKAGE_DESCRIPTION_FILE") # NOTE Getting the description from the file set(_file "${CMAKE_CURRENT_BINARY_DIR}/description.txt") diff --git a/Tests/RunCMake/CPack/tests/PER_COMPONENT_FIELDS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/PER_COMPONENT_FIELDS/VerifyResult.cmake index c47b40e..b4bdb61 100644 --- a/Tests/RunCMake/CPack/tests/PER_COMPONENT_FIELDS/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/tests/PER_COMPONENT_FIELDS/VerifyResult.cmake @@ -8,9 +8,6 @@ endfunction() if(GENERATOR_TYPE STREQUAL "DEB") set(name_ "Package") set(group_ "Section") - # NOTE For a Debian package the first line of the `Description` - # field is generated by CMake and gonna be ignored - set(ignore_rest_cond_ ".*\n") elseif(GENERATOR_TYPE STREQUAL "RPM") set(name_ "Name") set(group_ "Group") @@ -36,6 +33,6 @@ if(GENERATOR_TYPE STREQUAL "RPM") endif() # check package description -checkPackageInfo_("description" "${FOUND_FILE_1}" ".*Description${whitespaces_}:${ignore_rest_cond_}${whitespaces_}Description for pkg_1") -checkPackageInfo_("description" "${FOUND_FILE_2}" ".*Description${whitespaces_}:${ignore_rest_cond_}${whitespaces_}Description for pkg_2") -checkPackageInfo_("description" "${FOUND_FILE_3}" ".*Description${whitespaces_}:${ignore_rest_cond_}${whitespaces_}Description for pkg_3") +checkPackageInfo_("description" "${FOUND_FILE_1}" ".*Description${whitespaces_}:${whitespaces_}Description for pkg_1") +checkPackageInfo_("description" "${FOUND_FILE_2}" ".*Description${whitespaces_}:${whitespaces_}Description for pkg_2") +checkPackageInfo_("description" "${FOUND_FILE_3}" ".*Description${whitespaces_}:${whitespaces_}Description for pkg_3") diff --git a/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake index 152bf9c..631abac 100644 --- a/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake +++ b/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake @@ -27,15 +27,15 @@ foreach(line IN LISTS lines) elseif(inDebug AND (line MATCHES "^ *<DefineConstants>.*MY_FOO_DEFINE.*</DefineConstants> *$") AND (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$") AND - (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$") AND - (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$")) + (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$")) AND + (NOT (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$")) ) set(debugOK TRUE) elseif(inRelease AND (line MATCHES "^ *<DefineConstants>.*MY_FOO_DEFINE.*</DefineConstants> *$") AND (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$") AND - (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$") AND - (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$")) + (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$")) AND + (NOT (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$")) ) set(releaseOK TRUE) endif() diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm index 609860c..44e61f4 100644 --- a/Utilities/std/cmext/algorithm +++ b/Utilities/std/cmext/algorithm @@ -10,43 +10,154 @@ #include <iterator> #include <memory> #include <utility> -#include <vector> #include <cm/type_traits> #include <cmext/iterator> +#if defined(__SUNPRO_CC) && defined(__sparc) +# include <list> +# include <vector> +#else +# include <cmext/type_traits> +#endif + namespace cm { -template <typename T> -void append(std::vector<std::unique_ptr<T>>& v, - std::vector<std::unique_ptr<T>>&& r) +#if defined(__SUNPRO_CC) && defined(__sparc) +// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile +// templates with constraints. +// So, on this platform, use only simple templates. +# define APPEND_TWO(C1, C2) \ + template <typename T, typename U> \ + void append(C1<std::unique_ptr<T>>& v, C2<std::unique_ptr<U>>&& r) \ + { \ + std::transform( \ + r.begin(), r.end(), std::back_inserter(v), \ + [](std::unique_ptr<U>& item) { return std::move(item); }); \ + r.clear(); \ + } \ + \ + template <typename T, typename U> \ + void append(C1<T*>& v, C2<std::unique_ptr<U>> const& r) \ + { \ + std::transform( \ + r.begin(), r.end(), std::back_inserter(v), \ + [](const std::unique_ptr<U>& item) { return item.get(); }); \ + } + +# define APPEND_ONE(C) \ + template <typename T, typename InputIt, \ + cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = \ + 0> \ + void append(C<T>& v, InputIt first, InputIt last) \ + { \ + v.insert(v.end(), first, last); \ + } \ + \ + template <typename T, typename Range, \ + cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0> \ + void append(C<T>& v, Range const& r) \ + { \ + v.insert(v.end(), r.begin(), r.end()); \ + } + +# define APPEND(C) \ + APPEND_TWO(C, C) \ + APPEND_ONE(C) + +# define APPEND_MIX(C1, C2) \ + APPEND_TWO(C1, C2) \ + APPEND_TWO(C2, C1) + +// For now, manage only support for std::vector and std::list. +// Other sequential container support can be added if needed. +APPEND(std::vector) +APPEND(std::list) +APPEND_MIX(std::vector, std::list) + +# undef APPEND +# undef APPEND_MIX +# undef APPEND_TWO +# undef APPEND_ONE + +#else + +template < + typename Container1, typename Container2, + cm::enable_if_t< + cm::is_sequence_container<Container1>::value && + cm::is_unique_ptr<typename Container1::value_type>::value && + cm::is_unique_ptr<typename Container2::value_type>::value && + std::is_convertible<typename Container2::value_type::pointer, + typename Container1::value_type::pointer>::value, + int> = 0> +void append(Container1& v, Container2&& r) { - std::transform(r.begin(), r.end(), std::back_inserter(v), - [](std::unique_ptr<T>& item) { return std::move(item); }); + std::transform( + r.begin(), r.end(), std::back_inserter(v), + [](typename Container2::value_type& item) { return std::move(item); }); r.clear(); } -template <typename T> -void append(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r) +template <typename Container1, typename Container2, + cm::enable_if_t< + cm::is_sequence_container<Container1>::value && + std::is_pointer<typename Container1::value_type>::value && + cm::is_unique_ptr<typename Container2::value_type>::value && + std::is_convertible<typename Container2::value_type::pointer, + typename Container1::value_type>::value, + int> = 0> +# if defined(__SUNPRO_CC) +void append(Container1& v, Container2 const& r, detail::overload_selector<0>) +# else +void append(Container1& v, Container2 const& r) +# endif { - std::transform(r.begin(), r.end(), std::back_inserter(v), - [](const std::unique_ptr<T>& item) { return item.get(); }); + std::transform( + r.begin(), r.end(), std::back_inserter(v), + [](const typename Container2::value_type& item) { return item.get(); }); } -template <typename T, typename InputIt, - cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0> -void append(std::vector<T>& v, InputIt first, InputIt last) +template < + typename Container, typename InputIt, + cm::enable_if_t< + cm::is_sequence_container<Container>::value && + cm::is_input_iterator<InputIt>::value && + std::is_convertible<typename std::iterator_traits<InputIt>::value_type, + typename Container::value_type>::value, + int> = 0> +void append(Container& v, InputIt first, InputIt last) { v.insert(v.end(), first, last); } -template <typename T, typename Range, - cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0> -void append(std::vector<T>& v, Range const& r) +template <typename Container, typename Range, + cm::enable_if_t< + cm::is_sequence_container<Container>::value && + cm::is_input_range<Range>::value && + !cm::is_unique_ptr<typename Container::value_type>::value && + !cm::is_unique_ptr<typename Range::value_type>::value && + std::is_convertible<typename Range::value_type, + typename Container::value_type>::value, + int> = 0> +# if defined(__SUNPRO_CC) +void append(Container& v, Range const& r, detail::overload_selector<1>) +# else +void append(Container& v, Range const& r) +# endif { v.insert(v.end(), r.begin(), r.end()); } +# if defined(__SUNPRO_CC) +template <typename T, typename U> +void append(T& v, U const& r) +{ + cm::append(v, r, detail::overload_selector<1>{}); +} +# endif +#endif + } // namespace cm #endif diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits index da6550d..00984cb 100644 --- a/Utilities/std/cmext/type_traits +++ b/Utilities/std/cmext/type_traits @@ -10,6 +10,24 @@ namespace cm { +#if defined(__SUNPRO_CC) +// Oracle DeveloperStudio C++ compiler do not support overloaded templates with +// same signature but different constraints over template arguments +// (i.e. meta-programming). +// As a work-around, use a structure to avoid templates with same signature. +namespace detail { +template <int N> +struct overload_selector : overload_selector<N - 1> +{ +}; + +template <> +struct overload_selector<0> +{ +}; +} +#endif + // type traits for managed pointer types template <typename> struct is_unique_ptr : std::false_type |