diff options
53 files changed, 752 insertions, 94 deletions
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index 6830b59..a7d9708 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -56,10 +56,16 @@ Submit to CDash Upload API :: - ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]) + ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>] + [RETRY_COUNT <count>] + [RETRY_DELAY <delay>] + [QUIET]) 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. + +This signature accepts the ``RETRY_COUNT``, ``RETRY_DELAY``, and ``QUIET`` +options as described above. diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 864d1dc..4af8626 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -44,6 +44,7 @@ Properties of Global Scope /prop_gbl/TARGET_MESSAGES /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS /prop_gbl/USE_FOLDERS + /prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME .. _`Directory Properties`: @@ -236,6 +237,7 @@ Properties on Targets /prop_tgt/MACOSX_BUNDLE /prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST /prop_tgt/MACOSX_RPATH + /prop_tgt/MANUALLY_ADDED_DEPENDENCIES /prop_tgt/MAP_IMPORTED_CONFIG_CONFIG /prop_tgt/NAME /prop_tgt/NO_SONAME @@ -362,8 +364,11 @@ Properties on Source Files /prop_sf/SKIP_AUTORCC /prop_sf/SKIP_AUTOUIC /prop_sf/SYMBOLIC + /prop_sf/VS_COPY_TO_OUT_DIR /prop_sf/VS_DEPLOYMENT_CONTENT /prop_sf/VS_DEPLOYMENT_LOCATION + /prop_sf/VS_INCLUDE_IN_VSIX + /prop_sf/VS_RESOURCE_GENERATOR /prop_sf/VS_SHADER_ENTRYPOINT /prop_sf/VS_SHADER_FLAGS /prop_sf/VS_SHADER_MODEL diff --git a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst new file mode 100644 index 0000000..9a6086e --- /dev/null +++ b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst @@ -0,0 +1,24 @@ +XCODE_EMIT_EFFECTIVE_PLATFORM_NAME +---------------------------------- + +Control emission of ``EFFECTIVE_PLATFORM_NAME`` by the Xcode generator. + +It is required for building the same target with multiple SDKs. A +common use case is the parallel use of ``iphoneos`` and +``iphonesimulator`` SDKs. + +Three different states possible that control when the Xcode generator +emits the ``EFFECTIVE_PLATFORM_NAME`` variable: + +- If set to ``ON`` it will always be emitted +- If set to ``OFF`` it will never be emitted +- If unset (the default) it will only be emitted when the project was + configured for an embedded Xcode SDK like iOS, tvOS, watchOS or any + of the simulators. + +.. note:: + + When this behavior is enable for generated Xcode projects, the + ``EFFECTIVE_PLATFORM_NAME`` variable will leak into + :manual:`Generator expressions <cmake-generator-expressions(7)>` + like ``TARGET_FILE`` and will render those mostly unusable. diff --git a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst new file mode 100644 index 0000000..16c8d83 --- /dev/null +++ b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst @@ -0,0 +1,6 @@ +VS_COPY_TO_OUT_DIR +------------------ + +Sets the ``<CopyToOutputDirectory>`` tag for a source file in a +Visual Studio project file. Valid values are ``Never``, ``Always`` +and ``PreserveNewest``. diff --git a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst new file mode 100644 index 0000000..30f471d --- /dev/null +++ b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst @@ -0,0 +1,6 @@ +VS_INCLUDE_IN_VSIX +------------------ + +Boolean property to specify if the file should be included within a VSIX +extension package. This is needed for development of Visual Studio +extensions. diff --git a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst new file mode 100644 index 0000000..97e5aac --- /dev/null +++ b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst @@ -0,0 +1,8 @@ +VS_RESOURCE_GENERATOR +--------------------- + +This property allows to specify the resource generator to be used +on this file. It defaults to ``PublicResXFileCodeGenerator`` if +not set. + +This property only applies to C# projects. diff --git a/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst new file mode 100644 index 0000000..c12ea14 --- /dev/null +++ b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst @@ -0,0 +1,8 @@ +MANUALLY_ADDED_DEPENDENCIES +--------------------------- + +Get manually added dependencies to other top-level targets. + +This read-only property can be used to query all dependencies that +were added for this target with the :command:`add_dependencies` +command. diff --git a/Help/release/dev/cdash_upload_retry.rst b/Help/release/dev/cdash_upload_retry.rst new file mode 100644 index 0000000..2ceb42b --- /dev/null +++ b/Help/release/dev/cdash_upload_retry.rst @@ -0,0 +1,5 @@ +cdash-upload-retry +----------------------- + +* The ``CDASH_UPLOAD`` signature of :command:`ctest_submit` was taught to honor + the ``RETRY_COUNT``, ``RETRY_DELAY``, and ``QUIET`` options. diff --git a/Help/release/dev/cpack-ifw-package-options.rst b/Help/release/dev/cpack-ifw-package-options.rst new file mode 100644 index 0000000..1fec324 --- /dev/null +++ b/Help/release/dev/cpack-ifw-package-options.rst @@ -0,0 +1,7 @@ +cpack-ifw-package-options +------------------------- + +* The :module:`CPackIFW` module gained new :variable:`CPACK_IFW_PACKAGE_WATERMARK`, :variable:`CPACK_IFW_PACKAGE_BANNER`, + :variable:`CPACK_IFW_PACKAGE_BACKGROUND`, :variable:`CPACK_IFW_PACKAGE_WIZARD_STYLE`, :variable:`CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH`, + :variable:`CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT` and :variable:`CPACK_IFW_PACKAGE_TITLE_COLOR` + variables to customize a QtIFW installer look. diff --git a/Help/release/dev/manually-added-dependencies.rst b/Help/release/dev/manually-added-dependencies.rst new file mode 100644 index 0000000..6c486da --- /dev/null +++ b/Help/release/dev/manually-added-dependencies.rst @@ -0,0 +1,6 @@ +manually-added-dependencies +--------------------------- + +* The target property :prop_tgt:`MANUALLY_ADDED_DEPENDENCIES` has + been added. It is read-only and could be used to retrieve + dependencies that have been added with :command:`add_dependencies`. diff --git a/Help/release/dev/vs-advanced-source-properties.rst b/Help/release/dev/vs-advanced-source-properties.rst new file mode 100644 index 0000000..dd391e0 --- /dev/null +++ b/Help/release/dev/vs-advanced-source-properties.rst @@ -0,0 +1,12 @@ +vs-advanced-source-properties +----------------------------- + +* The :ref:`Visual Studio Generators` for VS 2010 and above + learned some more source file properties: + + - :prop_sf:`VS_RESOURCE_GENERATOR` (C# only): allows setting the resource + generator + - :prop_sf:`VS_COPY_TO_OUT_DIR`: parameter to set if file should be copied + to output directory (values: ``Never``, ``Always``, ``PreserveNewest``) + - :prop_sf:`VS_INCLUDE_IN_VSIX`: boolean property to include file include + Visual Studio extension package diff --git a/Help/release/dev/vs-csharp-support.rst b/Help/release/dev/vs-csharp-support.rst index 26d8574..46b235a 100644 --- a/Help/release/dev/vs-csharp-support.rst +++ b/Help/release/dev/vs-csharp-support.rst @@ -19,7 +19,16 @@ vs-native-csharp-support that specifically targets C# contains ``CSharp`` as a part of their names. -* More finetuning of C# targets can be done using target - properties. Specifically the Visual Studio related target +* More finetuning of C# targets can be done using target and source + file properties. Specifically the Visual Studio related target properties (``VS_*``) are worth a look (for setting toolset versions, root namespaces, assembly icons, ...). + +* **Auto-"linking"** in .csproj files: In C#/.NET development with + Visual Studio there is a number of visual editors used which + generate code. Both the generated files and the ones edited + with the UI are connected in the ``.csproj`` file using + ``<DependentUpon>`` tags. If CMake finds within a C# project + any source file with extension ``.Designer.cs`` or ``.xaml.cs``, + it checks sibling files with extension ``.xaml``, ``.settings``, + ``.resx`` or ``.cs`` and establishes the dependency connection. diff --git a/Help/release/dev/xcode-effective-platform-name.rst b/Help/release/dev/xcode-effective-platform-name.rst new file mode 100644 index 0000000..e337ca0 --- /dev/null +++ b/Help/release/dev/xcode-effective-platform-name.rst @@ -0,0 +1,8 @@ +xcode-effective-platform-name +----------------------------- + +* The Xcode generator can now control emission of the + ``EFFECTIVE_PLATFORM_NAME`` variable through the + :prop_gbl:`XCODE_EMIT_EFFECTIVE_PLATFORM_NAME` global property. + This is useful when building with multiple SDKs like macosx and + iphoneos in parallel. diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index b3ab055..ae595fb 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -76,6 +76,34 @@ # # Filename for a logo is used as QWizard::LogoPixmap. # +# .. variable:: CPACK_IFW_PACKAGE_WATERMARK +# +# Filename for a watermark is used as QWizard::WatermarkPixmap. +# +# .. variable:: CPACK_IFW_PACKAGE_BANNER +# +# Filename for a banner is used as QWizard::BannerPixmap. +# +# .. variable:: CPACK_IFW_PACKAGE_BACKGROUND +# +# Filename for an image used as QWizard::BackgroundPixmap (only used by MacStyle). +# +# .. variable:: CPACK_IFW_PACKAGE_WIZARD_STYLE +# +# Wizard style to be used ("Modern", "Mac", "Aero" or "Classic"). +# +# .. variable:: CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH +# +# Default width of the wizard in pixels. Setting a banner image will override this. +# +# .. variable:: CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT +# +# Default height of the wizard in pixels. Setting a watermark image will override this. +# +# .. variable:: CPACK_IFW_PACKAGE_TITLE_COLOR +# +# Color of the titles and subtitles (takes an HTML color code, such as "#88FF33"). +# # .. variable:: CPACK_IFW_PACKAGE_START_MENU_DIRECTORY # # Name of the default program group for the product in the Windows Start menu. diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index a0f731c..458c114 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -889,7 +889,7 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p if("${hash}" MATCHES "${_ep_hash_regex}") set(ALGO "${CMAKE_MATCH_1}") - set(EXPECT_VALUE "${CMAKE_MATCH_2}") + string(TOLOWER "${CMAKE_MATCH_2}" EXPECT_VALUE) else() set(ALGO "") set(EXPECT_VALUE "") diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake index 5be0428..c777970 100644 --- a/Modules/FindLua.cmake +++ b/Modules/FindLua.cmake @@ -172,6 +172,13 @@ if (LUA_LIBRARY) if (UNIX AND NOT APPLE AND NOT BEOS) find_library(LUA_MATH_LIBRARY m) set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}") + + # include dl library for statically-linked Lua library + get_filename_component(LUA_LIB_EXT ${LUA_LIBRARY} EXT) + if(LUA_LIB_EXT STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX) + list(APPEND LUA_LIBRARIES ${CMAKE_DL_LIBS}) + endif() + # For Windows and Mac, don't need to explicitly include the math library else () set(LUA_LIBRARIES "${LUA_LIBRARY}") diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake index 8755d4f..cf2785a 100644 --- a/Modules/Platform/Android-Common.cmake +++ b/Modules/Platform/Android-Common.cmake @@ -149,4 +149,13 @@ macro(__android_compiler_common lang) if("x${lang}" STREQUAL "xCXX") __android_stl(CXX) endif() + + # <ndk>/build/core/definitions.mk appends the sysroot's include directory + # explicitly at the end of the command-line include path so that it + # precedes the toolchain's builtin include directories. This is + # necessary so that Android API-version-specific headers are preferred + # over those in the toolchain's `include-fixed` directory (which cannot + # possibly match all versions). + list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include") + list(REMOVE_ITEM CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include") endmacro() diff --git a/Modules/Platform/Android/ndk-stl-c++.cmake b/Modules/Platform/Android/ndk-stl-c++.cmake index b27015d..a12411c 100644 --- a/Modules/Platform/Android/ndk-stl-c++.cmake +++ b/Modules/Platform/Android/ndk-stl-c++.cmake @@ -6,16 +6,15 @@ macro(__android_stl_cxx lang filename) if(EXISTS "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include/cstddef") # r12 and below __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include" 1) + __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/android/support/include" 0) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++abi/libcxxabi/include" 1) else() # r13 and above __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/include" 1) + __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/android/support/include" 0) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++abi/include" 1) endif() - # Add a secondary include directory if it exists. - __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/android/support/include" 0) - # Add the library file. __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1) endmacro() diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 0279d1c..0478918 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -439,7 +439,7 @@ macro(QT4_CREATE_TRANSLATION _qm_files) get_filename_component(_abs_include "${_pro_include}" ABSOLUTE) string(APPEND _pro_includes " \\\n \"${_abs_include}\"") endforeach() - file(WRITE ${_ts_pro} "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n") + file(GENERATE OUTPUT ${_ts_pro} CONTENT "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n") endif() add_custom_command(OUTPUT ${_ts_file} COMMAND Qt4::lupdate diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ce72bba..8e6ca1a 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 7) -set(CMake_VERSION_PATCH 20170119) +set(CMake_VERSION_PATCH 20170124) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 9ca7750..d8bafee 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -60,6 +60,16 @@ bool cmCPackIFWInstaller::IsVersionEqual(const char* version) return Generator ? Generator->IsVersionEqual(version) : false; } +void cmCPackIFWInstaller::printSkippedOptionWarning( + const std::string& optionName, const std::string& optionValue) +{ + cmCPackLogger( + cmCPackLog::LOG_WARNING, "Option " + << optionName << " is set to \"" << optionValue + << "\" but will be skipped because the specified file does not exist." + << std::endl); +} + void cmCPackIFWInstaller::ConfigureFromOptions() { // Name; @@ -110,7 +120,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() if (cmSystemTools::FileExists(option)) { InstallerApplicationIcon = option; } else { - // TODO: implement warning + printSkippedOptionWarning("CPACK_IFW_PACKAGE_ICON", option); } } @@ -119,7 +129,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() if (cmSystemTools::FileExists(option)) { InstallerWindowIcon = option; } else { - // TODO: implement warning + printSkippedOptionWarning("CPACK_IFW_PACKAGE_WINDOW_ICON", option); } } @@ -128,10 +138,69 @@ void cmCPackIFWInstaller::ConfigureFromOptions() if (cmSystemTools::FileExists(option)) { Logo = option; } else { - // TODO: implement warning + printSkippedOptionWarning("CPACK_IFW_PACKAGE_LOGO", option); + } + } + + // Watermark + if (const char* option = GetOption("CPACK_IFW_PACKAGE_WATERMARK")) { + if (cmSystemTools::FileExists(option)) { + Watermark = option; + } else { + printSkippedOptionWarning("CPACK_IFW_PACKAGE_WATERMARK", option); } } + // Banner + if (const char* option = GetOption("CPACK_IFW_PACKAGE_BANNER")) { + if (cmSystemTools::FileExists(option)) { + Banner = option; + } else { + printSkippedOptionWarning("CPACK_IFW_PACKAGE_BANNER", option); + } + } + + // Background + if (const char* option = GetOption("CPACK_IFW_PACKAGE_BACKGROUND")) { + if (cmSystemTools::FileExists(option)) { + Background = option; + } else { + printSkippedOptionWarning("CPACK_IFW_PACKAGE_BACKGROUND", option); + } + } + + // WizardStyle + if (const char* option = GetOption("CPACK_IFW_PACKAGE_WIZARD_STYLE")) { + if (WizardStyle.compare("Modern") == 0 && + WizardStyle.compare("Aero") == 0 && WizardStyle.compare("Mac") == 0 && + WizardStyle.compare("Classic") == 0) { + cmCPackLogger( + cmCPackLog::LOG_WARNING, + "Option CPACK_IFW_PACKAGE_WIZARD_STYLE has unknown value \"" + << option << "\". Expected values are: Modern, Aero, Mac, Classic." + << std::endl); + } + + WizardStyle = option; + } + + // WizardDefaultWidth + if (const char* option = + GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH")) { + WizardDefaultWidth = option; + } + + // WizardDefaultHeight + if (const char* option = + GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT")) { + WizardDefaultHeight = option; + } + + // TitleColor + if (const char* option = GetOption("CPACK_IFW_PACKAGE_TITLE_COLOR")) { + TitleColor = option; + } + // Start menu if (const char* optIFW_START_MENU_DIR = this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) { @@ -313,6 +382,50 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout.Element("Logo", name); } + // Banner + if (!Banner.empty()) { + std::string name = cmSystemTools::GetFilenameName(Banner); + std::string path = Directory + "/config/" + name; + cmsys::SystemTools::CopyFileIfDifferent(Banner.data(), path.data()); + xout.Element("Banner", name); + } + + // Watermark + if (!Watermark.empty()) { + std::string name = cmSystemTools::GetFilenameName(Watermark); + std::string path = Directory + "/config/" + name; + cmsys::SystemTools::CopyFileIfDifferent(Watermark.data(), path.data()); + xout.Element("Watermark", name); + } + + // Background + if (!Background.empty()) { + std::string name = cmSystemTools::GetFilenameName(Background); + std::string path = Directory + "/config/" + name; + cmsys::SystemTools::CopyFileIfDifferent(Background.data(), path.data()); + xout.Element("Background", name); + } + + // WizardStyle + if (!WizardStyle.empty()) { + xout.Element("WizardStyle", WizardStyle); + } + + // WizardDefaultWidth + if (!WizardDefaultWidth.empty()) { + xout.Element("WizardDefaultWidth", WizardDefaultWidth); + } + + // WizardDefaultHeight + if (!WizardDefaultHeight.empty()) { + xout.Element("WizardDefaultHeight", WizardDefaultHeight); + } + + // TitleColor + if (!TitleColor.empty()) { + xout.Element("TitleColor", TitleColor); + } + // Start menu if (!IsVersionLess("2.0")) { xout.Element("StartMenuDir", StartMenuDir); diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h index eba9bec..4ec3e70 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.h +++ b/Source/CPack/IFW/cmCPackIFWInstaller.h @@ -60,6 +60,27 @@ public: /// Filename for a logo std::string Logo; + /// Filename for a watermark + std::string Watermark; + + /// Filename for a banner + std::string Banner; + + /// Filename for a background + std::string Background; + + /// Wizard style name + std::string WizardStyle; + + /// Wizard width + std::string WizardDefaultWidth; + + /// Wizard height + std::string WizardDefaultHeight; + + /// Title color + std::string TitleColor; + /// Name of the default program group in the Windows Start menu std::string StartMenuDir; @@ -110,6 +131,10 @@ public: protected: void WriteGeneratedByToStrim(cmXMLWriter& xout); + +private: + void printSkippedOptionWarning(const std::string& optionName, + const std::string& optionValue); }; #endif // cmCPackIFWInstaller_h diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index 9a90f54..ab1412d 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -19,6 +19,7 @@ cmCTestCurl::cmCTestCurl(cmCTest* ctest) // default is to verify https this->VerifyPeerOff = false; this->VerifyHostOff = false; + this->Quiet = false; this->TimeOutSeconds = 0; this->Curl = curl_easy_init(); } @@ -96,6 +97,13 @@ bool cmCTestCurl::InitCurl() } // enable HTTP ERROR parsing curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 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); + } + return true; } @@ -110,12 +118,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file, } /* 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); @@ -157,13 +160,14 @@ bool cmCTestCurl::UploadFile(std::string const& local_file, if (!responseData.empty()) { response = std::string(responseData.begin(), responseData.end()); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Curl response: [" - << response << "]\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Curl response: [" << response << "]\n", this->Quiet); } std::string curlDebug; if (!debugData.empty()) { curlDebug = std::string(debugData.begin(), debugData.end()); - cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + cmCTestOptionalLog(this->CTest, DEBUG, + "Curl debug: [" << curlDebug << "]\n", this->Quiet); } if (response.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "No response from server.\n" @@ -177,9 +181,10 @@ 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"); + cmCTestOptionalLog(this->CTest, DEBUG, "HttpRequest\n" + << "url: " << url << "\n" + << "fields " << fields << "\n", + this->Quiet); if (!this->InitCurl()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed"); return false; @@ -202,13 +207,16 @@ bool cmCTestCurl::HttpRequest(std::string const& url, if (!responseData.empty()) { response = std::string(responseData.begin(), responseData.end()); - cmCTestLog(this->CTest, DEBUG, "Curl response: [" << response << "]\n"); + cmCTestOptionalLog(this->CTest, DEBUG, + "Curl response: [" << response << "]\n", this->Quiet); } if (!debugData.empty()) { std::string curlDebug = std::string(debugData.begin(), debugData.end()); - cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + cmCTestOptionalLog(this->CTest, DEBUG, + "Curl debug: [" << curlDebug << "]\n", this->Quiet); } - cmCTestLog(this->CTest, DEBUG, "Curl res: " << res << "\n"); + cmCTestOptionalLog(this->CTest, DEBUG, "Curl res: " << res << "\n", + this->Quiet); return (res == 0); } diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h index 17fbcff..cdce393 100644 --- a/Source/CTest/cmCTestCurl.h +++ b/Source/CTest/cmCTestCurl.h @@ -25,6 +25,7 @@ public: void SetCurlOptions(std::vector<std::string> const& args); void SetUseHttp10On() { this->UseHttp10 = true; } void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s; } + void SetQuiet(bool b) { this->Quiet = b; } std::string Escape(std::string const& source); protected: @@ -40,6 +41,7 @@ private: bool VerifyHostOff; bool VerifyPeerOff; bool UseHttp10; + bool Quiet; int TimeOutSeconds; }; diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 14b875f..5cf4ddc 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -157,6 +157,7 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) { if (this->CDashUpload) { + // Arguments specific to the CDASH_UPLOAD signature. if (arg == "CDASH_UPLOAD") { this->ArgumentDoing = ArgumentDoingCDashUpload; return true; @@ -167,7 +168,7 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) return true; } } else { - // Look for arguments specific to this command. + // Arguments that cannot be used with CDASH_UPLOAD. if (arg == "PARTS") { this->ArgumentDoing = ArgumentDoingParts; this->PartsMentioned = true; @@ -179,21 +180,21 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) this->FilesMentioned = true; return true; } + } + // Arguments used by both modes. + if (arg == "RETRY_COUNT") { + this->ArgumentDoing = ArgumentDoingRetryCount; + return true; + } - if (arg == "RETRY_COUNT") { - this->ArgumentDoing = ArgumentDoingRetryCount; - return true; - } - - if (arg == "RETRY_DELAY") { - this->ArgumentDoing = ArgumentDoingRetryDelay; - return true; - } + if (arg == "RETRY_DELAY") { + this->ArgumentDoing = ArgumentDoingRetryDelay; + return true; + } - if (arg == "INTERNAL_TEST_CHECKSUM") { - this->InternalTest = true; - return true; - } + if (arg == "INTERNAL_TEST_CHECKSUM") { + this->InternalTest = true; + return true; } // Look for other arguments. diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 79c3663..5e5119d 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -1007,6 +1007,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, return -1; } cmCTestCurl curl(this->CTest); + curl.SetQuiet(this->Quiet); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); std::vector<std::string> args; cmSystemTools::ExpandListArgument(curlopt, args); @@ -1022,6 +1023,30 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, "Only http and https are supported for CDASH_UPLOAD\n"); return -1; } + bool internalTest = cmSystemTools::IsOn(this->GetOption("InternalTest")); + + // Get RETRY_COUNT and RETRY_DELAY values if they were set. + std::string retryDelayString = this->GetOption("RetryDelay") == CM_NULLPTR + ? "" + : this->GetOption("RetryDelay"); + std::string retryCountString = this->GetOption("RetryCount") == CM_NULLPTR + ? "" + : this->GetOption("RetryCount"); + unsigned long retryDelay = 0; + if (retryDelayString != "") { + if (!cmSystemTools::StringToULong(retryDelayString.c_str(), &retryDelay)) { + cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " + << retryDelayString << std::endl); + } + } + unsigned long retryCount = 0; + if (retryCountString != "") { + if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) { + cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " + << retryCountString << std::endl); + } + } + char md5sum[33]; md5sum[32] = 0; cmSystemTools::ComputeFileMD5(file, md5sum); @@ -1058,7 +1083,33 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << "\nfile: " << file << "\n", this->Quiet); std::string response; - if (!curl.HttpRequest(url, fields, response)) { + + bool requestSucceeded = curl.HttpRequest(url, fields, response); + if (!internalTest && !requestSucceeded) { + // If request failed, wait and retry. + for (unsigned long i = 0; i < retryCount; i++) { + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Request failed, waiting " << retryDelay + << " seconds...\n", + this->Quiet); + + double stop = cmSystemTools::GetTime() + static_cast<double>(retryDelay); + while (cmSystemTools::GetTime() < stop) { + cmSystemTools::Delay(100); + } + + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Retry request: Attempt " + << (i + 1) << " of " << retryCount << std::endl, + this->Quiet); + + requestSucceeded = curl.HttpRequest(url, fields, response); + if (requestSucceeded) { + break; + } + } + } + if (!internalTest && !requestSucceeded) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in HttpRequest\n" << response); return -1; @@ -1068,30 +1119,32 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, this->Quiet); Json::Value json; Json::Reader reader; - if (!reader.parse(response, json)) { + if (!internalTest && !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) { + if (!internalTest && 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) { - cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "File already exists on CDash, skip upload " << file - << "\n", - this->Quiet); - return 0; + if (!internalTest) { + if (json["datafilesmd5"].isArray()) { + int datares = json["datafilesmd5"][0].asInt(); + if (datares == 1) { + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "File already exists on CDash, skip upload " + << file << "\n", + this->Quiet); + return 0; + } + } else { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "bad datafilesmd5 value in response " << response << "\n"); + return -1; } - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "bad datafilesmd5 value in response " << response << "\n"); - return -1; } std::string upload_as = cmSystemTools::GetFilenameName(file); @@ -1100,7 +1153,40 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << "md5=" << md5sum << "&" << "filename=" << curl.Escape(upload_as) << "&" << "buildid=" << json["buildid"].asString(); - if (!curl.UploadFile(file, url, fstr.str(), response)) { + + bool uploadSucceeded = false; + if (!internalTest) { + uploadSucceeded = curl.UploadFile(file, url, fstr.str(), response); + } + + if (!uploadSucceeded) { + // If upload failed, wait and retry. + for (unsigned long i = 0; i < retryCount; i++) { + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Upload failed, waiting " << retryDelay + << " seconds...\n", + this->Quiet); + + double stop = cmSystemTools::GetTime() + static_cast<double>(retryDelay); + while (cmSystemTools::GetTime() < stop) { + cmSystemTools::Delay(100); + } + + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Retry upload: Attempt " + << (i + 1) << " of " << retryCount << std::endl, + this->Quiet); + + if (!internalTest) { + uploadSucceeded = curl.UploadFile(file, url, fstr.str(), response); + } + if (uploadSucceeded) { + break; + } + } + } + + if (!uploadSucceeded) { cmCTestLog(this->CTest, ERROR_MESSAGE, "error uploading to CDash. " << file << " " << url << " " << fstr.str()); return -1; diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index daf4bd1..6284ac9 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -46,7 +46,7 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames, QString AddCacheEntry::name() const { - return this->Name->text(); + return this->Name->text().trimmed(); } QVariant AddCacheEntry::value() const diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b6db0d6..dcf3764 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4419,9 +4419,10 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // The generator may add the configuration's subdirectory. if (!conf.empty()) { - bool iosPlatform = this->Makefile->PlatformIsAppleIos(); + bool useEPN = + this->GlobalGenerator->UseEffectivePlatformName(this->Makefile); std::string suffix = - usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : ""; + usesDefaultOutputDir && useEPN ? "${EFFECTIVE_PLATFORM_NAME}" : ""; this->LocalGenerator->GetGlobalGenerator()->AppendDirectoryForConfig( "/", conf, suffix, out); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2808051..f118250 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2342,8 +2342,8 @@ void cmGlobalGenerator::AddGlobalTarget_Install( singleLine.push_back(cmd); if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') { std::string cfgArg = "-DBUILD_TYPE="; - bool iosPlatform = mf->PlatformIsAppleIos(); - if (iosPlatform) { + bool useEPN = this->UseEffectivePlatformName(mf); + if (useEPN) { cfgArg += "$(CONFIGURATION)"; singleLine.push_back(cfgArg); cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 88ef8da..18e3730 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -333,6 +333,10 @@ public: virtual bool UseFolderProperty() const; + /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is + relevant for mixed macOS and iOS builds. */ + virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; } + std::string GetSharedLibFlagsForLanguage(std::string const& lang) const; /** Generate an <output>.rule file path for a given command output. */ diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 96535eb..d448315 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -22,6 +22,7 @@ #include "cmOutputConverter.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" +#include "cmState.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -3544,6 +3545,19 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const return true; } +bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const +{ + const char* epnValue = + this->GetCMakeInstance()->GetState()->GetGlobalProperty( + "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); + + if (!epnValue) { + return mf->PlatformIsAppleIos(); + } + + return cmSystemTools::IsOn(epnValue); +} + void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 42c39aa..1aaf9c7 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -86,6 +86,8 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ bool IsMultiConfig() const CM_OVERRIDE; + bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE; + bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE; void AppendFlag(std::string& flags, std::string const& flag); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index a635bf4..9efc13b 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2015,7 +2015,8 @@ void cmSystemTools::FindCMakeResources(const char* argv0) // Install tree has // - "<prefix><CMAKE_BIN_DIR>/cmake" // - "<prefix><CMAKE_DATA_DIR>" - if (cmHasSuffix(exe_dir, CMAKE_BIN_DIR)) { + const std::string actual_case = cmSystemTools::GetActualCaseForPath(exe_dir); + if (cmHasSuffix(actual_case, CMAKE_BIN_DIR)) { std::string const prefix = exe_dir.substr(0, exe_dir.size() - strlen(CMAKE_BIN_DIR)); cmSystemToolsCMakeRoot = prefix + CMAKE_DATA_DIR; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9261ca8..d825e5c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -852,6 +852,12 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) this->Makefile->GetBacktrace())) { return; } + if (prop == "MANUALLY_ADDED_DEPENDENCIES") { + std::ostringstream e; + e << "MANUALLY_ADDED_DEPENDENCIES property is read-only\n"; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } if (prop == "NAME") { std::ostringstream e; e << "NAME property is read-only\n"; @@ -1168,6 +1174,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const MAKE_STATIC_PROP(COMPILE_OPTIONS); MAKE_STATIC_PROP(COMPILE_DEFINITIONS); MAKE_STATIC_PROP(IMPORTED); + MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES); MAKE_STATIC_PROP(NAME); MAKE_STATIC_PROP(BINARY_DIR); MAKE_STATIC_PROP(SOURCE_DIR); @@ -1181,6 +1188,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const specialProps.insert(propCOMPILE_OPTIONS); specialProps.insert(propCOMPILE_DEFINITIONS); specialProps.insert(propIMPORTED); + specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES); specialProps.insert(propNAME); specialProps.insert(propBINARY_DIR); specialProps.insert(propSOURCE_DIR); @@ -1236,6 +1244,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const output = cmJoin(this->Internal->CompileDefinitionsEntries, ";"); return output.c_str(); } + if (prop == propMANUALLY_ADDED_DEPENDENCIES) { + if (this->Utilities.empty()) { + return CM_NULLPTR; + } + + static std::string output; + output = cmJoin(this->Utilities, ";"); + return output.c_str(); + } if (prop == propIMPORTED) { return this->IsImported() ? "TRUE" : "FALSE"; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 89380eb..2e6c19b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -610,30 +610,91 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() this->GeneratorTarget->GetResxSources(resxObjs, ""); if (!resxObjs.empty()) { this->WriteString("<ItemGroup>\n", 1); + std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + this->ConvertToWindowsSlash(srcDir); for (std::vector<cmSourceFile const*>::const_iterator oi = resxObjs.begin(); oi != resxObjs.end(); ++oi) { std::string obj = (*oi)->GetFullPath(); this->WriteString("<EmbeddedResource Include=\"", 2); this->ConvertToWindowsSlash(obj); + bool useRelativePath = false; + if (csproj == this->ProjectType && this->InSourceBuild) { + // If we do an in-source build and the resource file is in a + // subdirectory + // of the .csproj file, we have to use relative pathnames, otherwise + // visual studio does not show the file in the IDE. Sorry. + if (obj.find(srcDir) == 0) { + obj = this->ConvertPath(obj, true); + this->ConvertToWindowsSlash(obj); + useRelativePath = true; + } + } (*this->BuildFileStream) << obj << "\">\n"; - this->WriteString("<DependentUpon>", 3); - std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; - (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; - - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { - this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); - if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || - // Handle variant of VS_GLOBAL_<variable> for RootNamespace. - this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { - (*this->BuildFileStream) << "$(RootNamespace)."; + if (csproj != this->ProjectType) { + this->WriteString("<DependentUpon>", 3); + std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; + (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; + + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); + if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || + // Handle variant of VS_GLOBAL_<variable> for RootNamespace. + this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { + (*this->BuildFileStream) << "$(RootNamespace)."; + } + (*this->BuildFileStream) << "%(Filename)"; + (*this->BuildFileStream) << ".resources"; + (*this->BuildFileStream) << "</LogicalName>\n"; + } + } else { + std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + this->ConvertToWindowsSlash(binDir); + // If the resource was NOT added using a relative path (which should + // be the default), we have to provide a link here + if (!useRelativePath) { + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } + // Determine if this is a generated resource from a .Designer.cs file + std::string designerResource = + cmSystemTools::GetFilenamePath((*oi)->GetFullPath()) + "/" + + cmSystemTools::GetFilenameWithoutLastExtension( + (*oi)->GetFullPath()) + + ".Designer.cs"; + if (cmsys::SystemTools::FileExists(designerResource)) { + std::string generator = "PublicResXFileCodeGenerator"; + if (const char* g = (*oi)->GetProperty("VS_RESOURCE_GENERATOR")) { + generator = g; + } + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(generator) + << "</Generator>\n"; + if (designerResource.find(srcDir) == 0) { + designerResource = designerResource.substr(srcDir.length() + 1); + } else if (designerResource.find(binDir) == 0) { + designerResource = designerResource.substr(binDir.length() + 1); + } else { + designerResource = + cmsys::SystemTools::GetFilenameName(designerResource); + } + this->ConvertToWindowsSlash(designerResource); + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << designerResource << "</LastGenOutput>\n"; } - (*this->BuildFileStream) << "%(Filename)"; - (*this->BuildFileStream) << ".resources"; - (*this->BuildFileStream) << "</LogicalName>\n"; } this->WriteString("</EmbeddedResource>\n", 2); @@ -661,6 +722,24 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() } this->WriteSource(xamlType, *oi, ">\n"); + if (csproj == this->ProjectType && !this->InSourceBuild) { + // add <Link> tag to written XAML source if necessary + const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + const std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->ConvertToWindowsSlash(link); + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } this->WriteString("<SubType>Designer</SubType>\n", 3); this->WriteString("</", 2); (*this->BuildFileStream) << xamlType << ">\n"; @@ -1348,7 +1427,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) std::string shaderEntryPoint; std::string shaderModel; std::string shaderAdditionalFlags; + std::string settingsGenerator; + std::string settingsLastGenOutput; std::string sourceLink; + std::string subType; + std::string copyToOutDir; + std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); if (csproj == this->ProjectType) { // EVERY extra source file must have a <Link>, otherwise it might not @@ -1405,6 +1489,28 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) tool = "XML"; } else if (ext == "natvis") { tool = "Natvis"; + } else if (ext == "settings") { + // remove path to current source dir (if files are in current source dir) + if (!sourceLink.empty()) { + settingsLastGenOutput = sourceLink; + } else { + settingsLastGenOutput = sf->GetFullPath(); + } + std::size_t pos = settingsLastGenOutput.find(".settings"); + settingsLastGenOutput.replace(pos, 9, ".Designer.cs"); + settingsGenerator = "SettingsSingleFileGenerator"; + toolHasSettings = true; + } else if (ext == "vsixmanifest") { + subType = "Designer"; + } + if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { + copyToOutDir = c; + toolHasSettings = true; + } + if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) { + includeInVsix = "True"; + tool = "Content"; + toolHasSettings = true; } if (this->NsightTegra) { @@ -1495,10 +1601,35 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) (*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags) << "</AdditionalOptions>\n"; } + if (!settingsGenerator.empty()) { + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsGenerator) + << "</Generator>\n"; + } + if (!settingsLastGenOutput.empty()) { + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsLastGenOutput) + << "</LastGenOutput>\n"; + } if (!sourceLink.empty()) { this->WriteString("<Link>", 3); (*this->BuildFileStream) << cmVS10EscapeXML(sourceLink) << "</Link>\n"; } + if (!subType.empty()) { + this->WriteString("<SubType>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(subType) << "</SubType>\n"; + } + if (!copyToOutDir.empty()) { + this->WriteString("<CopyToOutputDirectory>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(copyToOutDir) + << "</CopyToOutputDirectory>\n"; + } + if (!includeInVsix.empty()) { + this->WriteString("<IncludeInVSIX>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(includeInVsix) + << "</IncludeInVSIX>\n"; + } + this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } else { @@ -1540,12 +1671,6 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, this->GlobalGenerator->PathTooLong(this->GeneratorTarget, sf, sourceRel); } } - if (csproj == this->ProjectType && this->InSourceBuild) { - std::string srcdir = this->Makefile->GetCurrentSourceDirectory(); - if (sourceFile.find(srcdir) != std::string::npos) { - sourceFile = sourceFile.substr(srcdir.size() + 1); - } - } this->ConvertToWindowsSlash(sourceFile); this->WriteString("<", 2); (*this->BuildFileStream) << tool << " Include=\"" @@ -1815,9 +1940,43 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( sourceFileTags["Link"] = link; } } - // - // NOTE: in future commits additional props will be added! - // + // check if file is a generated .Designer.cs or .xaml.cs file + // to add additional necessary tags + const std::string fileExtension = + cmsys::SystemTools::GetFilenameExtension(f); + if (fileExtension == ".Designer.cs" || fileExtension == ".xaml.cs") { + f = f.substr(0, f.length() - fileExtension.length()); + if (sourceFileTags.find("Link") == sourceFileTags.end() && + !this->InSourceBuild) { + // add link fallback + sourceFileTags["Link"] = + cmsys::SystemTools::GetFilenameName(f) + fileExtension; + } + std::vector<std::string> extensions; + extensions.push_back(".resx"); + extensions.push_back(".settings"); + extensions.push_back(".xaml"); + extensions.push_back(".cs"); + std::string dependencyExtension; + for (std::vector<std::string>::iterator i = extensions.begin(); + i != extensions.end(); ++i) { + if (cmsys::SystemTools::FileExists(f + *i)) { + dependencyExtension = *i; + // There should never be more than one match. Otherwise + // one cannot tell on which match the file depends. + break; + } + } + if (dependencyExtension == ".resx") { + sourceFileTags["DesignTime"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } else if (dependencyExtension == ".settings") { + sourceFileTags["DesignTimeSharedInput"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } + sourceFileTags["DependentUpon"] = + cmsys::SystemTools::GetFilenameName(f) + dependencyExtension; + } // write source file specific tags if (!sourceFileTags.empty()) { hasFlags = true; @@ -1825,7 +1984,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( firstString = ""; for (CsPropMap::const_iterator i = sourceFileTags.begin(); i != sourceFileTags.end(); ++i) { - this->WriteString("<", 2); + this->WriteString("<", 3); (*this->BuildFileStream) << i->first << ">" << cmVS10EscapeXML(i->second) << "</" << i->first << ">\n"; diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 60912c2..f51a107 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -166,3 +166,24 @@ if(NOT XCODE_VERSION VERSION_LESS 6) unset(RunCMake_TEST_NO_CLEAN) unset(RunCMake_TEST_OPTIONS) endif() + +if(NOT XCODE_VERSION VERSION_LESS 5) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeMultiplatform-build) + set(RunCMake_TEST_NO_CLEAN 1) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeMultiplatform) + + # build ios before macos + run_cmake_command(XcodeMultiplatform-iphonesimulator-build ${CMAKE_COMMAND} --build . -- -sdk iphonesimulator) + run_cmake_command(XcodeMultiplatform-iphonesimulator-install ${CMAKE_COMMAND} --build . --target install -- -sdk iphonesimulator DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_iphonesimulator) + + run_cmake_command(XcodeMultiplatform-macosx-build ${CMAKE_COMMAND} --build . -- -sdk macosx) + run_cmake_command(XcodeMultiplatform-macosx-install ${CMAKE_COMMAND} --build . --target install -- -sdk macosx DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_macosx) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake b/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake new file mode 100644 index 0000000..a1064f4 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.3) +enable_language(CXX) + +set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME ON) + +set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx iphonesimulator") +set(CMAKE_MACOSX_BUNDLE true) + +add_library(library STATIC foo.cpp) + +add_executable(main main.cpp) +target_link_libraries(main library) + +install(TARGETS library ARCHIVE DESTINATION lib) diff --git a/Tests/RunCMake/add_dependencies/ReadOnlyProperty-result.txt b/Tests/RunCMake/add_dependencies/ReadOnlyProperty-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_dependencies/ReadOnlyProperty-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_dependencies/ReadOnlyProperty-stderr.txt b/Tests/RunCMake/add_dependencies/ReadOnlyProperty-stderr.txt new file mode 100644 index 0000000..da30b81 --- /dev/null +++ b/Tests/RunCMake/add_dependencies/ReadOnlyProperty-stderr.txt @@ -0,0 +1 @@ +MANUALLY_ADDED_DEPENDENCIES property is read-only diff --git a/Tests/RunCMake/add_dependencies/ReadOnlyProperty.cmake b/Tests/RunCMake/add_dependencies/ReadOnlyProperty.cmake new file mode 100644 index 0000000..f0e4069 --- /dev/null +++ b/Tests/RunCMake/add_dependencies/ReadOnlyProperty.cmake @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.7) +project(ReadOnlyProperty C) + +add_library(a a.c) + +set_property(TARGET a PROPERTY MANUALLY_ADDED_DEPENDENCIES DEPENDENCIES foo) diff --git a/Tests/RunCMake/add_dependencies/RetrieveDependencies.cmake b/Tests/RunCMake/add_dependencies/RetrieveDependencies.cmake new file mode 100644 index 0000000..45b3974 --- /dev/null +++ b/Tests/RunCMake/add_dependencies/RetrieveDependencies.cmake @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.7) +project(RetrieveDependencies C) + +add_library(a a.c) + +add_library(b c.c) +target_link_libraries(a b) + +add_library(c c.c) +add_dependencies(a c) + +get_property(DEPS_A TARGET a PROPERTY MANUALLY_ADDED_DEPENDENCIES) + +if(NOT DEPS_A STREQUAL "c") + message(FATAL_ERROR "Expected target c being a dependency of a but got: '${DEPS_A}'") +endif() diff --git a/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake b/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake index 30b7e67..507d43f 100644 --- a/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake @@ -1,3 +1,5 @@ include(RunCMake) run_cmake(NoTarget) +run_cmake(ReadOnlyProperty) +run_cmake(RetrieveDependencies) diff --git a/Tests/RunCMake/add_dependencies/a.c b/Tests/RunCMake/add_dependencies/a.c new file mode 100644 index 0000000..707c1c3 --- /dev/null +++ b/Tests/RunCMake/add_dependencies/a.c @@ -0,0 +1,3 @@ +void a() +{ +} diff --git a/Tests/RunCMake/add_dependencies/b.c b/Tests/RunCMake/add_dependencies/b.c new file mode 100644 index 0000000..57b2900 --- /dev/null +++ b/Tests/RunCMake/add_dependencies/b.c @@ -0,0 +1,3 @@ +void b() +{ +} diff --git a/Tests/RunCMake/add_dependencies/c.c b/Tests/RunCMake/add_dependencies/c.c new file mode 100644 index 0000000..cbf94ca --- /dev/null +++ b/Tests/RunCMake/add_dependencies/c.c @@ -0,0 +1,3 @@ +void c() +{ +} diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadMissingFile-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadMissingFile-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadMissingFile-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadMissingFile-stderr.txt new file mode 100644 index 0000000..364ecde --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadMissingFile-stderr.txt @@ -0,0 +1 @@ +Upload file not found: 'bad-upload' diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt deleted file mode 100644 index 21621d4..0000000 --- a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT/test.cmake:[0-9]+ \(ctest_submit\): - ctest_submit called with unknown argument "RETRY_COUNT". diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt deleted file mode 100644 index f726674..0000000 --- a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY/test.cmake:[0-9]+ \(ctest_submit\): - ctest_submit called with unknown argument "RETRY_DELAY". diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadRetry-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadRetry-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRetry-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRetry-stderr.txt new file mode 100644 index 0000000..6780c17 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadRetry-stderr.txt @@ -0,0 +1 @@ +error uploading to CDash. diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRetry-stdout.txt b/Tests/RunCMake/ctest_submit/CDashUploadRetry-stdout.txt new file mode 100644 index 0000000..a5459ac --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadRetry-stdout.txt @@ -0,0 +1,4 @@ + Upload failed, waiting 1 seconds... + Retry upload: Attempt 1 of 2 + Upload failed, waiting 1 seconds... + Retry upload: Attempt 2 of 2 diff --git a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake index a81bc96..e104f8a 100644 --- a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake @@ -21,9 +21,9 @@ 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) +run_ctest_submit(CDashUploadMissingFile CDASH_UPLOAD bad-upload) +run_ctest_submit(CDashUploadRetry CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo RETRY_COUNT 2 RETRY_DELAY 1 INTERNAL_TEST_CHECKSUM) run_ctest_submit(CDashSubmitQuiet QUIET) function(run_ctest_CDashUploadFTP) |