From kwrobot at kitware.com Thu Nov 1 00:05:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 1 Nov 2018 00:05:05 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-275-g75b8513 Message-ID: <20181101040505.F285B125B69@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 75b85133d8cccb5d2680b0817d8720c6860238b0 (commit) from 7f68e4a1636a1691422e7a97873d34e1f5612fa1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=75b85133d8cccb5d2680b0817d8720c6860238b0 commit 75b85133d8cccb5d2680b0817d8720c6860238b0 Author: Kitware Robot AuthorDate: Thu Nov 1 00:01:09 2018 -0400 Commit: Kitware Robot CommitDate: Thu Nov 1 00:01:09 2018 -0400 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4481ea4..0ee5b60 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 13) -set(CMake_VERSION_PATCH 20181031) +set(CMake_VERSION_PATCH 20181101) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 1 07:45:07 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 1 Nov 2018 07:45:07 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-286-g707ac6a Message-ID: <20181101114507.3C3541260D8@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 707ac6aab6e46f8a55d44a57d9612073b2e47bb5 (commit) via ce45effe1324730f2c1a3d69d84b43bf10f09474 (commit) via 133465a0e579db3013887dd0ffc53b54773a7958 (commit) via d955b4f753d450ec10a2f928fcca1a91a50816ce (commit) via 8f043068d5f5953f4eb8440389fe37f8b044baca (commit) via 03454b0d0d5083530f87e3b2f4ed4fe93b182112 (commit) via 9040df31e2da7db351d76dcc72568d44d0223f92 (commit) via 3065a8a793705369da4dcaa2c85f558a8e5f8a35 (commit) via 609bdd126d56f81cbf59bacd6931cf8a53c36229 (commit) via 1acd1c2b50f461ee2cf90fb7166240f180147f19 (commit) via a56edad6d61268204af8228b8d58fa26d8f72269 (commit) from 75b85133d8cccb5d2680b0817d8720c6860238b0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=707ac6aab6e46f8a55d44a57d9612073b2e47bb5 commit 707ac6aab6e46f8a55d44a57d9612073b2e47bb5 Merge: ce45eff 8f04306 Author: Brad King AuthorDate: Thu Nov 1 07:38:54 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 07:38:54 2018 -0400 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ce45effe1324730f2c1a3d69d84b43bf10f09474 commit ce45effe1324730f2c1a3d69d84b43bf10f09474 Merge: 133465a 609bdd1 Author: Brad King AuthorDate: Thu Nov 1 07:38:08 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 07:38:08 2018 -0400 Merge branch 'release-3.12' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=133465a0e579db3013887dd0ffc53b54773a7958 commit 133465a0e579db3013887dd0ffc53b54773a7958 Merge: d955b4f 03454b0 Author: Brad King AuthorDate: Thu Nov 1 11:37:24 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 1 07:37:30 2018 -0400 Merge topic 'FindProtobuf-threads' 03454b0d0d FindProtobuf: Add missing link dependencies on threads Acked-by: Kitware Robot Merge-request: !2551 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d955b4f753d450ec10a2f928fcca1a91a50816ce commit d955b4f753d450ec10a2f928fcca1a91a50816ce Merge: 75b8513 9040df3 Author: Brad King AuthorDate: Thu Nov 1 11:36:14 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 1 07:36:39 2018 -0400 Merge topic 'fix-custom-target-with-csharp' 9040df31e2 Merge branch 'backport-fix-custom-target-with-csharp' 1acd1c2b50 CSharp: Fix regression in VS project type selection for custom target a56edad6d6 CSharp: Fix regression in VS project type selection for custom target Acked-by: Kitware Robot Merge-request: !2549 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9040df31e2da7db351d76dcc72568d44d0223f92 commit 9040df31e2da7db351d76dcc72568d44d0223f92 Merge: a56edad 1acd1c2 Author: Brad King AuthorDate: Wed Oct 31 09:38:01 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:38:01 2018 -0400 Merge branch 'backport-fix-custom-target-with-csharp' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=609bdd126d56f81cbf59bacd6931cf8a53c36229 commit 609bdd126d56f81cbf59bacd6931cf8a53c36229 Merge: 88477e0 1acd1c2 Author: Brad King AuthorDate: Wed Oct 31 09:35:19 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:35:19 2018 -0400 Merge branch 'backport-fix-custom-target-with-csharp' into release-3.12 Merge-request: !2549 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1acd1c2b50f461ee2cf90fb7166240f180147f19 commit 1acd1c2b50f461ee2cf90fb7166240f180147f19 Author: Brad King AuthorDate: Tue Oct 30 09:37:07 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:20:15 2018 -0400 CSharp: Fix regression in VS project type selection for custom target A target created by `add_custom_target` should always be a `.vcxproj` file even if it has `.cs` sources involved in custom commands and such. The latter case was broken by refactoring in commit v3.12.0-rc1~160^2~7 (remove TargetIsCSharpOnly() and use methods from cmGeneratorTarget, 2018-03-19). The reason is that the `HasLanguage` method added by commit v3.12.0-rc1~239^2~6 (cmGeneratorTarget: add HasLanguage() as wrapper for GetLanguages(), 2018-03-19) does not check the target type and so is not a suitable check for deciding the project file extension. The `HasLanguage` method was an attempt at an abstraction that turns out not to work very well. Replace it with a dedicated `IsCSharpOnly` method that considers the target type, sources, and non-transitive `LINKER_LANGUAGE`. Fixes: #18515 diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 9e6560f..ce9bc87 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -788,7 +788,7 @@ void cmExportFileGenerator::SetImportDetailProperties( std::string propval; if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) { propval = p; - } else if (target->HasLanguage("CSharp", config)) { + } else if (target->IsCSharpOnly()) { // C# projects do not have the /clr flag, so we set the property // here to mark the target as (only) managed (i.e. no .lib file // to link to). Otherwise the COMMON_LANGUAGE_RUNTIME target diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 8aab1be..9918b87 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5221,20 +5221,23 @@ void cmGeneratorTarget::GetLanguages(std::set& languages, } } -bool cmGeneratorTarget::HasLanguage(std::string const& language, - std::string const& config, - bool exclusive) const +bool cmGeneratorTarget::IsCSharpOnly() const { - std::set languages; - this->GetLanguages(languages, config); - // The "exclusive" check applies only to source files and not - // the linker language which may be affected by dependencies. - if (exclusive && languages.size() > 1) { + // Only certain target types may compile CSharp. + if (this->GetType() != cmStateEnums::SHARED_LIBRARY && + this->GetType() != cmStateEnums::STATIC_LIBRARY && + this->GetType() != cmStateEnums::EXECUTABLE) { return false; } - // add linker language (if it is different from compiler languages) - languages.insert(this->GetLinkerLanguage(config)); - return languages.count(language) > 0; + std::set languages; + this->GetLanguages(languages, ""); + // Consider an explicit linker language property, but *not* the + // computed linker language that may depend on linked targets. + const char* linkLang = this->GetProperty("LINKER_LANGUAGE"); + if (linkLang && *linkLang) { + languages.insert(linkLang); + } + return languages.size() == 1 && languages.count("CSharp") > 0; } void cmGeneratorTarget::ComputeLinkImplementationLanguages( @@ -5555,6 +5558,5 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType( // C# targets are always managed. This language specific check // is added to avoid that the COMMON_LANGUAGE_RUNTIME target property // has to be set manually for C# targets. - return this->HasLanguage("CSharp", config) ? ManagedType::Managed - : ManagedType::Native; + return this->IsCSharpOnly() ? ManagedType::Managed : ManagedType::Native; } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 2810887..14197f8 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -364,11 +364,7 @@ public: void GetLanguages(std::set& languages, std::string const& config) const; - // Evaluate if the target uses the given language for compilation - // and/or linking. If 'exclusive' is true, 'language' is expected - // to be the only language used in source files for the target. - bool HasLanguage(std::string const& language, std::string const& config, - bool exclusive = true) const; + bool IsCSharpOnly() const; void GetObjectLibrariesCMP0026( std::vector& objlibs) const; diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 0b086b0..ba12fac 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -98,7 +98,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, ext = ".vfproj"; project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \""; } - if (t->HasLanguage("CSharp", "")) { + if (t->IsCSharpOnly()) { ext = ".csproj"; project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \""; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index b8b04ae..c455fa2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -215,12 +215,11 @@ static bool cmVS10IsTargetsFile(std::string const& path) return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0; } -static std::string computeProjectFileExtension(cmGeneratorTarget const* t, - const std::string& config) +static std::string computeProjectFileExtension(cmGeneratorTarget const* t) { std::string res; res = ".vcxproj"; - if (t->HasLanguage("CSharp", config)) { + if (t->IsCSharpOnly()) { res = ".csproj"; } return res; @@ -316,8 +315,8 @@ void cmVisualStudio10TargetGenerator::Generate() this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) { return; } - const std::string ProjectFileExtension = computeProjectFileExtension( - this->GeneratorTarget, *this->Configurations.begin()); + const std::string ProjectFileExtension = + computeProjectFileExtension(this->GeneratorTarget); if (ProjectFileExtension == ".vcxproj") { this->ProjectType = vcxproj; this->Managed = false; @@ -1399,8 +1398,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); path += "/"; path += this->Name; - path += computeProjectFileExtension(this->GeneratorTarget, - *this->Configurations.begin()); + path += computeProjectFileExtension(this->GeneratorTarget); path += ".filters"; cmGeneratedFileStream fout(path.c_str()); fout.SetCopyIfDifferent(true); @@ -3734,7 +3732,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) path = lg->GetCurrentBinaryDirectory(); path += "/"; path += dt->GetName(); - path += computeProjectFileExtension(dt, *this->Configurations.begin()); + path += computeProjectFileExtension(dt); } ConvertToWindowsSlash(path); Elem e2(e1, "ProjectReference"); @@ -3761,7 +3759,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) // Workaround for static library C# targets if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) { - referenceNotManaged = !dt->HasLanguage("CSharp", ""); + referenceNotManaged = !dt->IsCSharpOnly(); } if (referenceNotManaged) { e2.Element("ReferenceOutputAssembly", "false"); diff --git a/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake b/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake index fa5618a..ab3e51b 100644 --- a/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake +++ b/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake @@ -1,5 +1,13 @@ include(RunCMake) +function(run_TargetWithCommand) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetWithCommand-build) + run_cmake(TargetWithCommand) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(TargetWithCommand-build ${CMAKE_COMMAND} --build . --config Debug) +endfunction() +run_TargetWithCommand() + # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandWithOutput-build) set(RunCMake_TEST_NO_CLEAN 1) diff --git a/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand-build-stdout.txt b/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand-build-stdout.txt new file mode 100644 index 0000000..c212a8f --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand-build-stdout.txt @@ -0,0 +1 @@ +Custom target with CSharp source diff --git a/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand.cmake b/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand.cmake new file mode 100644 index 0000000..fdaea5c --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/TargetWithCommand.cmake @@ -0,0 +1,4 @@ +enable_language(CSharp) + +add_custom_target(drive ALL SOURCES dummy.cs + COMMAND ${CMAKE_COMMAND} -E echo "Custom target with CSharp source") ----------------------------------------------------------------------- Summary of changes: Modules/FindProtobuf.cmake | 36 +++++++++++++--------- Source/cmExportFileGenerator.cxx | 2 +- Source/cmGeneratorTarget.cxx | 28 +++++++++-------- Source/cmGeneratorTarget.h | 6 +--- Source/cmGlobalVisualStudio71Generator.cxx | 2 +- Source/cmVisualStudio10TargetGenerator.cxx | 16 +++++----- Tests/CSharpOnly/CMakeLists.txt | 4 +-- .../CSharpCustomCommand/RunCMakeTest.cmake | 8 +++++ .../TargetWithCommand-build-stdout.txt | 1 + .../CSharpCustomCommand/TargetWithCommand.cmake | 4 +++ 10 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 Tests/RunCMake/CSharpCustomCommand/TargetWithCommand-build-stdout.txt create mode 100644 Tests/RunCMake/CSharpCustomCommand/TargetWithCommand.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 1 07:45:07 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 1 Nov 2018 07:45:07 -0400 (EDT) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-25-g8f04306 Message-ID: <20181101114507.89B6E1260D9@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 8f043068d5f5953f4eb8440389fe37f8b044baca (commit) via 03454b0d0d5083530f87e3b2f4ed4fe93b182112 (commit) via 3065a8a793705369da4dcaa2c85f558a8e5f8a35 (commit) via a56edad6d61268204af8228b8d58fa26d8f72269 (commit) from 09e36f9978609eb7efda101590ba685df850f5c8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindProtobuf.cmake | 36 +++++++++++++--------- Source/cmExportFileGenerator.cxx | 2 +- Source/cmGeneratorTarget.cxx | 28 +++++++++-------- Source/cmGeneratorTarget.h | 6 +--- Source/cmGlobalVisualStudio71Generator.cxx | 2 +- Source/cmVisualStudio10TargetGenerator.cxx | 16 +++++----- Tests/CSharpOnly/CMakeLists.txt | 4 +-- .../CSharpCustomCommand/RunCMakeTest.cmake | 8 +++++ .../TargetWithCommand-build-stdout.txt | 1 + .../CSharpCustomCommand/TargetWithCommand.cmake | 4 +++ 10 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 Tests/RunCMake/CSharpCustomCommand/TargetWithCommand-build-stdout.txt create mode 100644 Tests/RunCMake/CSharpCustomCommand/TargetWithCommand.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 00:05:08 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 00:05:08 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-287-gfa5e555 Message-ID: <20181102040509.2C47B1260AF@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via fa5e5550f3f19842590b2d9e19b3c3e3c1132e02 (commit) from 707ac6aab6e46f8a55d44a57d9612073b2e47bb5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fa5e5550f3f19842590b2d9e19b3c3e3c1132e02 commit fa5e5550f3f19842590b2d9e19b3c3e3c1132e02 Author: Kitware Robot AuthorDate: Fri Nov 2 00:01:13 2018 -0400 Commit: Kitware Robot CommitDate: Fri Nov 2 00:01:13 2018 -0400 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0ee5b60..b0b01c8 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 13) -set(CMake_VERSION_PATCH 20181101) +set(CMake_VERSION_PATCH 20181102) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 07:55:08 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 07:55:08 -0400 (EDT) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-27-ga567f53 Message-ID: <20181102115508.717671260F4@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via a567f533dbbcb0d41ac38837f2593059a456fe5e (commit) via eb52529ff41d375344c2bd45a717bf86669627f8 (commit) from 8f043068d5f5953f4eb8440389fe37f8b044baca (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/cmFileMonitor.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 07:55:08 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 07:55:08 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-295-g08da4f8 Message-ID: <20181102115508.5EB061260F5@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 08da4f8d70cce97a9a6913d74e6c128ca6c0a40b (commit) via bacb20a3364e6a868cc47720f4a5c9831103af42 (commit) via 34e011748e796972be4a7386207b2a203d6f282f (commit) via c384fc3ca4e4523efa7330d7684f5cf3de672826 (commit) via a567f533dbbcb0d41ac38837f2593059a456fe5e (commit) via 4ccf278f5bc9815f76f393948c09f82092e9f1ec (commit) via eb52529ff41d375344c2bd45a717bf86669627f8 (commit) via 9855a80fd41e384bc3accd07fa8b98f7da7d916d (commit) from fa5e5550f3f19842590b2d9e19b3c3e3c1132e02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=08da4f8d70cce97a9a6913d74e6c128ca6c0a40b commit 08da4f8d70cce97a9a6913d74e6c128ca6c0a40b Merge: bacb20a 9855a80 Author: Brad King AuthorDate: Fri Nov 2 11:53:16 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 2 07:53:22 2018 -0400 Merge topic 'FindBoost-exact-version' 9855a80fd4 FindBoost: search default path if Boost_FIND_VERSION_EXACT Acked-by: Kitware Robot Merge-request: !2543 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bacb20a3364e6a868cc47720f4a5c9831103af42 commit bacb20a3364e6a868cc47720f4a5c9831103af42 Merge: 34e0117 a567f53 Author: Brad King AuthorDate: Fri Nov 2 07:49:13 2018 -0400 Commit: Brad King CommitDate: Fri Nov 2 07:49:13 2018 -0400 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=34e011748e796972be4a7386207b2a203d6f282f commit 34e011748e796972be4a7386207b2a203d6f282f Merge: c384fc3 4ccf278 Author: Brad King AuthorDate: Fri Nov 2 07:48:59 2018 -0400 Commit: Brad King CommitDate: Fri Nov 2 07:48:59 2018 -0400 Merge branch 'release-3.12' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c384fc3ca4e4523efa7330d7684f5cf3de672826 commit c384fc3ca4e4523efa7330d7684f5cf3de672826 Merge: fa5e555 eb52529 Author: Brad King AuthorDate: Fri Nov 2 11:48:27 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 2 07:48:34 2018 -0400 Merge topic 'server-file-monitor-check' eb52529ff4 server: Fix assertion failure on directory paths in file monitor Acked-by: Kitware Robot Merge-request: !2556 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4ccf278f5bc9815f76f393948c09f82092e9f1ec commit 4ccf278f5bc9815f76f393948c09f82092e9f1ec Merge: 609bdd1 eb52529 Author: Brad King AuthorDate: Thu Nov 1 09:02:30 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 09:02:30 2018 -0400 Merge branch 'server-file-monitor-check' into release-3.12 Merge-request: !2556 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9855a80fd41e384bc3accd07fa8b98f7da7d916d commit 9855a80fd41e384bc3accd07fa8b98f7da7d916d Author: Hannes Franke AuthorDate: Mon Oct 29 16:20:40 2018 +0100 Commit: Hannes Franke CommitDate: Mon Oct 29 16:44:40 2018 +0100 FindBoost: search default path if Boost_FIND_VERSION_EXACT Search paths for boost versions should be build using _boost_TEST_VERSIONS instead of _Boost_KNOWN_VERSIONS because if Boost_FIND_VERSION_EXACT is used _Boost_KNOWN_VERSIONS is empty and boost isn't found even in its default installation path. Fixes: #17986 diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 501929a..cde3738 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1258,7 +1258,7 @@ if(NOT Boost_INCLUDE_DIR) list(APPEND _boost_INCLUDE_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) else() if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - foreach(ver ${_Boost_KNOWN_VERSIONS}) + foreach(ver ${_boost_TEST_VERSIONS}) string(REPLACE "." "_" ver "${ver}") list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS "C:/local/boost_${ver}") endforeach() @@ -1569,7 +1569,7 @@ foreach(c DEBUG RELEASE) if( Boost_NO_SYSTEM_PATHS ) list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) else() - foreach(ver ${_Boost_KNOWN_VERSIONS}) + foreach(ver ${_boost_TEST_VERSIONS}) string(REPLACE "." "_" ver "${ver}") _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "C:/local/boost_${ver}") endforeach() ----------------------------------------------------------------------- Summary of changes: Modules/FindBoost.cmake | 4 ++-- Source/cmFileMonitor.cxx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 08:05:13 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 08:05:13 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-311-gbdc5618 Message-ID: <20181102120514.4D3C11CFB@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via bdc5618e18b9868f46e48641cdd35f361199f28e (commit) via a052479a5c75cc4e892fe68002bc0a4d97013a66 (commit) via 9578c3f0d18a5407a3106a6c487115947d1355e4 (commit) via 22ba9b6a328a0eea77559b2d607fe8d525445812 (commit) via 525ff0c3bc1f625756337c2ae724a58ec93ba4d1 (commit) via 87324b9b6a1f29a25c96149e165e99bebe750ef5 (commit) via dfb3f58f79b05dfe7840373aa08a86204c94f33b (commit) via bd9bfc644954a48b1bf7ea18fc260a1231840671 (commit) via 0033676796748bd8fe00f3f96d3470405cdb94fe (commit) via 02f566a5592ac0438f03a84d713bae6913a7e39a (commit) via b601bb6f1c30c97e21ea893e8c84b05aab97fcb4 (commit) via 4babc9058a996e9cccd183eb25eda5faedd04591 (commit) via 45a49ae58abe835bc3ad446b054fa07035c33d60 (commit) via 9f64974f5eff103ceda107c362c66c2adc1997ba (commit) via 4201a11c2b5a5bdb442f99f88a5f17d6ae7c4a4c (commit) via 3eebe28ef41a298f9743db44a7265742891fc225 (commit) from 08da4f8d70cce97a9a6913d74e6c128ca6c0a40b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bdc5618e18b9868f46e48641cdd35f361199f28e commit bdc5618e18b9868f46e48641cdd35f361199f28e Merge: a052479 22ba9b6 Author: Brad King AuthorDate: Fri Nov 2 11:57:48 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 2 07:57:54 2018 -0400 Merge topic 'FindGDAL-target' 22ba9b6a32 FindGDAL: set the GDAL_VERSION 525ff0c3bc Tests/FindGDAL: add a test for FindGDAL 87324b9b6a FindGDAL: add an imported target dfb3f58f79 FindGDAL: Modernize documentation layout Acked-by: Kitware Robot Merge-request: !2552 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a052479a5c75cc4e892fe68002bc0a4d97013a66 commit a052479a5c75cc4e892fe68002bc0a4d97013a66 Merge: 9578c3f bd9bfc6 Author: Brad King AuthorDate: Fri Nov 2 11:56:57 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 2 07:57:06 2018 -0400 Merge topic 'msvc-custom-rc-mt' bd9bfc6449 MSVC: Respect CMAKE_RC_COMPILER and CMAKE_MT in vs_link_{dll,exe} 0033676796 CUDA: Enable RC language on Windows 02f566a559 MSVC: Factor out enable_language(RC) call into helper macro b601bb6f1c CUDA: Find CMAKE_LINKER on Windows 3eebe28ef4 cmLocalNinjaGenerator: Simplify CreateRulePlaceholderExpander Acked-by: Kitware Robot Merge-request: !2424 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9578c3f0d18a5407a3106a6c487115947d1355e4 commit 9578c3f0d18a5407a3106a6c487115947d1355e4 Merge: 08da4f8 4babc90 Author: Brad King AuthorDate: Fri Nov 2 11:55:06 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 2 07:55:14 2018 -0400 Merge topic 'check-keywords-only-if-used' 4babc9058a cmTargetPropCommandBase: check keywords after parsing 45a49ae58a cmTargetPropCommandBase: simplify code path 9f64974f5e cmTargetPropCommandBase: skip property setting if there's nothing to add 4201a11c2b Tests: add tests for empty-value keyword arguments in target_* Acked-by: Kitware Robot Merge-request: !2514 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=22ba9b6a328a0eea77559b2d607fe8d525445812 commit 22ba9b6a328a0eea77559b2d607fe8d525445812 Author: Ben Boeckel AuthorDate: Wed Oct 31 14:48:15 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:16:37 2018 -0400 FindGDAL: set the GDAL_VERSION diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake index 5dd9335..8522f9b 100644 --- a/Modules/FindGDAL.cmake +++ b/Modules/FindGDAL.cmake @@ -24,6 +24,8 @@ This module will set the following variables in your project: Include directories for GDAL headers. ``GDAL_LIBRARIES`` Libraries to link to GDAL. +``GDAL_VERSION`` + The version of GDAL found. Cache variables ^^^^^^^^^^^^^^^ @@ -138,8 +140,19 @@ find_library(GDAL_LIBRARY PATH_SUFFIXES lib ) +if (EXISTS "${GDAL_INCLUDE_DIR}/gdal_version.h") + file(STRINGS "${GDAL_INCLUDE_DIR}/gdal_version.h" _gdal_version + REGEX "GDAL_RELEASE_NAME") + string(REGEX REPLACE ".*\"\(.*\)\"" "\\1" GDAL_VERSION "${_gdal_version}") + unset(_gdal_version) +else () + set(GDAL_VERSION GDAL_VERSION-NOTFOUND) +endif () + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL DEFAULT_MSG GDAL_LIBRARY GDAL_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL + VERSION_VAR GDAL_VERSION + REQUIRED_VARS GDAL_LIBRARY GDAL_INCLUDE_DIR) if (GDAL_FOUND AND NOT TARGET GDAL::GDAL) add_library(GDAL::GDAL UNKNOWN IMPORTED) diff --git a/Tests/FindGDAL/Test/CMakeLists.txt b/Tests/FindGDAL/Test/CMakeLists.txt index 20f4b84..8bdc57c 100644 --- a/Tests/FindGDAL/Test/CMakeLists.txt +++ b/Tests/FindGDAL/Test/CMakeLists.txt @@ -4,9 +4,7 @@ include(CTest) find_package(GDAL REQUIRED) -# FindGDAL doesn't export a version number. -#add_definitions(-DCMAKE_EXPECTED_GDAL_VERSION="${GDAL_VERSION}") -add_definitions(-DCMAKE_EXPECTED_GDAL_VERSION="unknown") +add_definitions(-DCMAKE_EXPECTED_GDAL_VERSION="${GDAL_VERSION}") add_executable(test_tgt main.c) target_link_libraries(test_tgt GDAL::GDAL) diff --git a/Tests/FindGDAL/Test/main.c b/Tests/FindGDAL/Test/main.c index 046eb99..7b31a13 100644 --- a/Tests/FindGDAL/Test/main.c +++ b/Tests/FindGDAL/Test/main.c @@ -1,12 +1,11 @@ #include #include -// #include +#include int main() { printf("Found GDAL version %s, expected version %s\n", GDAL_RELEASE_NAME, CMAKE_EXPECTED_GDAL_VERSION); GDALAllRegister(); - // return strcmp(GDAL_RELEASE_NAME, CMAKE_EXPECTED_GDAL_VERSION); - return 0; + return strcmp(GDAL_RELEASE_NAME, CMAKE_EXPECTED_GDAL_VERSION); } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=525ff0c3bc1f625756337c2ae724a58ec93ba4d1 commit 525ff0c3bc1f625756337c2ae724a58ec93ba4d1 Author: Ben Boeckel AuthorDate: Wed Oct 31 14:47:56 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:16:37 2018 -0400 Tests/FindGDAL: add a test for FindGDAL diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index c7cfa86..1c49fea 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1384,6 +1384,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindFreetype) endif() + if(CMake_TEST_FindGDAL) + add_subdirectory(FindGDAL) + endif() + if(CMake_TEST_FindGSL) add_subdirectory(FindGSL) endif() diff --git a/Tests/FindGDAL/CMakeLists.txt b/Tests/FindGDAL/CMakeLists.txt new file mode 100644 index 0000000..12f95e1 --- /dev/null +++ b/Tests/FindGDAL/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindGDAL.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindGDAL/Test" + "${CMake_BINARY_DIR}/Tests/FindGDAL/Test" + ${build_generator_args} + --build-project TestFindGDAL + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) diff --git a/Tests/FindGDAL/Test/CMakeLists.txt b/Tests/FindGDAL/Test/CMakeLists.txt new file mode 100644 index 0000000..20f4b84 --- /dev/null +++ b/Tests/FindGDAL/Test/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.10) +project(TestFindGDAL C) +include(CTest) + +find_package(GDAL REQUIRED) + +# FindGDAL doesn't export a version number. +#add_definitions(-DCMAKE_EXPECTED_GDAL_VERSION="${GDAL_VERSION}") +add_definitions(-DCMAKE_EXPECTED_GDAL_VERSION="unknown") + +add_executable(test_tgt main.c) +target_link_libraries(test_tgt GDAL::GDAL) +add_test(NAME test_tgt COMMAND test_tgt) + +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${GDAL_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${GDAL_LIBRARIES}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindGDAL/Test/main.c b/Tests/FindGDAL/Test/main.c new file mode 100644 index 0000000..046eb99 --- /dev/null +++ b/Tests/FindGDAL/Test/main.c @@ -0,0 +1,12 @@ +#include +#include +// #include + +int main() +{ + printf("Found GDAL version %s, expected version %s\n", GDAL_RELEASE_NAME, + CMAKE_EXPECTED_GDAL_VERSION); + GDALAllRegister(); + // return strcmp(GDAL_RELEASE_NAME, CMAKE_EXPECTED_GDAL_VERSION); + return 0; +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=87324b9b6a1f29a25c96149e165e99bebe750ef5 commit 87324b9b6a1f29a25c96149e165e99bebe750ef5 Author: Ben Boeckel AuthorDate: Wed Oct 31 11:05:01 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:16:36 2018 -0400 FindGDAL: add an imported target diff --git a/Help/release/dev/FindGDAL-target.rst b/Help/release/dev/FindGDAL-target.rst new file mode 100644 index 0000000..b121a72 --- /dev/null +++ b/Help/release/dev/FindGDAL-target.rst @@ -0,0 +1,4 @@ +FindGDAL-target +--------------- + +* The :module:`FindGDAL` module now provides an imported target. diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake index 9c989b8..5dd9335 100644 --- a/Modules/FindGDAL.cmake +++ b/Modules/FindGDAL.cmake @@ -7,6 +7,12 @@ FindGDAL Find GDAL. +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``GDAL::GDAL`` +if GDAL has been found. + Result Variables ^^^^^^^^^^^^^^^^ @@ -135,5 +141,12 @@ find_library(GDAL_LIBRARY include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL DEFAULT_MSG GDAL_LIBRARY GDAL_INCLUDE_DIR) +if (GDAL_FOUND AND NOT TARGET GDAL::GDAL) + add_library(GDAL::GDAL UNKNOWN IMPORTED) + set_target_properties(GDAL::GDAL PROPERTIES + IMPORTED_LOCATION "${GDAL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GDAL_INCLUDE_DIR}") +endif () + set(GDAL_LIBRARIES ${GDAL_LIBRARY}) set(GDAL_INCLUDE_DIRS ${GDAL_INCLUDE_DIR}) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dfb3f58f79b05dfe7840373aa08a86204c94f33b commit dfb3f58f79b05dfe7840373aa08a86204c94f33b Author: Brad King AuthorDate: Thu Nov 1 13:12:18 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:16:36 2018 -0400 FindGDAL: Modernize documentation layout diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake index 030553f..9c989b8 100644 --- a/Modules/FindGDAL.cmake +++ b/Modules/FindGDAL.cmake @@ -5,28 +5,37 @@ FindGDAL -------- +Find GDAL. +Result Variables +^^^^^^^^^^^^^^^^ -Locate gdal +This module will set the following variables in your project: -This module accepts the following environment variables: +``GDAL_FOUND`` + True if GDAL is found. +``GDAL_INCLUDE_DIRS`` + Include directories for GDAL headers. +``GDAL_LIBRARIES`` + Libraries to link to GDAL. -:: +Cache variables +^^^^^^^^^^^^^^^ - GDAL_DIR or GDAL_ROOT - Specify the location of GDAL +The following cache variables may also be set: +``GDAL_LIBRARY`` + The libgdal library file. +``GDAL_INCLUDE_DIR`` + The directory containing ``gdal.h``. +Hints +^^^^^ -This module defines the following CMake variables: - -:: - - GDAL_FOUND - True if libgdal is found - GDAL_LIBRARY - A variable pointing to the GDAL library - GDAL_INCLUDE_DIR - Where to find the headers +Set ``GDAL_DIR`` or ``GDAL_ROOT`` in the environment to specify the +GDAL installation prefix. #]=======================================================================] -# # $GDALDIR is an environment variable that would # correspond to the ./configure --prefix=$GDAL_DIR # used in building gdal. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd9bfc644954a48b1bf7ea18fc260a1231840671 commit bd9bfc644954a48b1bf7ea18fc260a1231840671 Author: Mateusz Zych AuthorDate: Thu Oct 25 02:34:26 2018 +0200 Commit: Brad King CommitDate: Mon Oct 29 13:40:47 2018 -0400 MSVC: Respect CMAKE_RC_COMPILER and CMAKE_MT in vs_link_{dll,exe} CMake commands vs_link_dll and vs_link_exe, performing linking on MSVC, are responsible for calling resource compiler and manifest tool. Before this commit, both of these tools were called directly, with the expectation that they are available in the `PATH`. This has been fixed by respecting CMake variables `CMAKE_RC_COMPILER` and `CMAKE_MT` defining paths to these tools. Fixes: #17804 diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in index a6465f6..b8e09fe 100644 --- a/Modules/CMakeASMCompiler.cmake.in +++ b/Modules/CMakeASMCompiler.cmake.in @@ -5,6 +5,7 @@ set(CMAKE_ASM at ASM_DIALECT@_COMPILER_AR "@_CMAKE_ASM_COMPILER_AR@") set(CMAKE_RANLIB "@CMAKE_RANLIB@") set(CMAKE_ASM at ASM_DIALECT@_COMPILER_RANLIB "@_CMAKE_ASM_COMPILER_RANLIB@") set(CMAKE_LINKER "@CMAKE_LINKER@") +set(CMAKE_MT "@CMAKE_MT@") set(CMAKE_ASM at ASM_DIALECT@_COMPILER_LOADED 1) set(CMAKE_ASM at ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@") set(CMAKE_ASM at ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@") diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index 72144cf..e75c74e 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -21,6 +21,7 @@ set(CMAKE_C_COMPILER_AR "@CMAKE_C_COMPILER_AR@") set(CMAKE_RANLIB "@CMAKE_RANLIB@") set(CMAKE_C_COMPILER_RANLIB "@CMAKE_C_COMPILER_RANLIB@") set(CMAKE_LINKER "@CMAKE_LINKER@") +set(CMAKE_MT "@CMAKE_MT@") set(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@) set(CMAKE_C_COMPILER_LOADED 1) set(CMAKE_C_COMPILER_WORKS @CMAKE_C_COMPILER_WORKS@) diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index e1e1d33..feb3e79 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -28,3 +28,4 @@ set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@ set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") set(CMAKE_LINKER "@CMAKE_LINKER@") +set(CMAKE_MT "@CMAKE_MT@") diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 8da6a8c..5f52fd8 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -23,6 +23,7 @@ set(CMAKE_CXX_COMPILER_AR "@CMAKE_CXX_COMPILER_AR@") set(CMAKE_RANLIB "@CMAKE_RANLIB@") set(CMAKE_CXX_COMPILER_RANLIB "@CMAKE_CXX_COMPILER_RANLIB@") set(CMAKE_LINKER "@CMAKE_LINKER@") +set(CMAKE_MT "@CMAKE_MT@") set(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@) set(CMAKE_CXX_COMPILER_LOADED 1) set(CMAKE_CXX_COMPILER_WORKS @CMAKE_CXX_COMPILER_WORKS@) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index b805fa7..35f75c9 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -14,29 +14,48 @@ # CMAKE_AR # CMAKE_RANLIB # CMAKE_LINKER +# CMAKE_MT # CMAKE_STRIP # CMAKE_INSTALL_NAME_TOOL # on UNIX, cygwin and mingw -if(CMAKE_LINKER) - # we only get here if CMAKE_LINKER was specified using -D or a pre-made CMakeCache.txt - # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE - # find the linker in the PATH if necessary - get_filename_component(_CMAKE_USER_LINKER_PATH "${CMAKE_LINKER}" PATH) - if(NOT _CMAKE_USER_LINKER_PATH) - find_program(CMAKE_LINKER_WITH_PATH NAMES ${CMAKE_LINKER} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - if(CMAKE_LINKER_WITH_PATH) - set(CMAKE_LINKER ${CMAKE_LINKER_WITH_PATH}) - get_property(_CMAKE_LINKER_CACHED CACHE CMAKE_LINKER PROPERTY TYPE) - if(_CMAKE_LINKER_CACHED) - set(CMAKE_LINKER "${CMAKE_LINKER}" CACHE STRING "Default Linker" FORCE) +# Resolve full path of CMAKE_TOOL from user-defined name and SEARCH_PATH. +function(__resolve_tool_path CMAKE_TOOL SEARCH_PATH DOCSTRING) + + if(${CMAKE_TOOL}) + # We only get here if CMAKE_TOOL was + # specified using -D or a pre-made CMakeCache.txt (e.g. via ctest) + # or set in CMAKE_TOOLCHAIN_FILE. + + get_filename_component(_CMAKE_USER_TOOL_PATH "${${CMAKE_TOOL}}" DIRECTORY) + # Is CMAKE_TOOL a user-defined name instead of a full path? + if(NOT _CMAKE_USER_TOOL_PATH) + + # Find CMAKE_TOOL in the SEARCH_PATH directory by user-defined name. + find_program(_CMAKE_TOOL_WITH_PATH NAMES ${${CMAKE_TOOL}} HINTS ${SEARCH_PATH}) + if(_CMAKE_TOOL_WITH_PATH) + + # Overwrite CMAKE_TOOL with full path found in SEARCH_PATH. + set(${CMAKE_TOOL} ${_CMAKE_TOOL_WITH_PATH} PARENT_SCOPE) + + get_property(_CMAKE_TOOL_CACHED CACHE ${CMAKE_TOOL} PROPERTY TYPE) + # If CMAKE_TOOL is present in the CMake Cache, then overwrit it as well. + if(_CMAKE_TOOL_CACHED) + set(${CMAKE_TOOL} "${_CMAKE_TOOL_WITH_PATH}" CACHE STRING ${DOCSTRING} FORCE) + endif() + endif() - unset(_CMAKE_LINKER_CACHED) + unset(_CMAKE_TOOL_WITH_PATH CACHE) + endif() - unset(CMAKE_LINKER_WITH_PATH CACHE) + endif() -endif() + +endfunction() + +__resolve_tool_path(CMAKE_LINKER "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Linker") +__resolve_tool_path(CMAKE_MT "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Manifest Tool") set(_CMAKE_TOOL_VARS "") @@ -49,8 +68,9 @@ if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - list(APPEND _CMAKE_TOOL_VARS CMAKE_LINKER) + list(APPEND _CMAKE_TOOL_VARS CMAKE_LINKER CMAKE_MT) # in all other cases search for ar, ranlib, etc. else() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 73906c6..2daf313 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -298,8 +298,8 @@ unset(_MACHINE_ARCH_FLAG) macro(__windows_compiler_msvc lang) if(NOT MSVC_VERSION LESS 1400) # for 2005 make sure the manifest is put in the dll with mt - set(_CMAKE_VS_LINK_DLL " -E vs_link_dll --intdir= --manifests -- ") - set(_CMAKE_VS_LINK_EXE " -E vs_link_exe --intdir= --manifests -- ") + set(_CMAKE_VS_LINK_DLL " -E vs_link_dll --intdir= --rc= --mt= --manifests -- ") + set(_CMAKE_VS_LINK_EXE " -E vs_link_exe --intdir= --rc= --mt= --manifests -- ") endif() set(CMAKE_${lang}_CREATE_SHARED_LIBRARY "${_CMAKE_VS_LINK_DLL} ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out: /implib: /pdb: /dll /version:.${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}") diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 631a7de..6a2667a 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -17,8 +17,8 @@ endforeach() set(CMAKE_CUDA_LINK_EXECUTABLE " /out: /implib: /pdb: /version:. ${__IMPLICT_LINKS}") -set(_CMAKE_VS_LINK_DLL " -E vs_link_dll --intdir= --manifests -- ") -set(_CMAKE_VS_LINK_EXE " -E vs_link_exe --intdir= --manifests -- ") +set(_CMAKE_VS_LINK_DLL " -E vs_link_dll --intdir= --rc= --mt= --manifests -- ") +set(_CMAKE_VS_LINK_EXE " -E vs_link_exe --intdir= --rc= --mt= --manifests -- ") set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "${_CMAKE_VS_LINK_DLL} ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out: /implib: /pdb: /dll /version:.${_PLATFORM_LINK_FLAGS} ${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}") diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7030725..b07d504 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -65,6 +65,7 @@ static const char* ruleReplaceVars[] = { "CMAKE_CURRENT_BINARY_DIR", "CMAKE_RANLIB", "CMAKE_LINKER", + "CMAKE_MT", "CMAKE_CUDA_HOST_COMPILER", "CMAKE_CUDA_HOST_LINK_LAUNCHER", "CMAKE_CL_SHOWINCLUDES_PREFIX" diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 1d2f741..9f1618b 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1517,6 +1517,8 @@ class cmVSLink std::string ManifestFileRC; std::string ManifestFileRes; std::string TargetFile; + std::string MtPath; + std::string RcPath; public: cmVSLink(int type, bool verbose) @@ -1660,6 +1662,12 @@ bool cmVSLink::Parse(std::vector::const_iterator argBeg, } else if (cmHasLiteralPrefix(*arg, "--intdir=")) { intDir = arg->substr(9); ++arg; + } else if (cmHasLiteralPrefix(*arg, "--rc=")) { + this->RcPath = arg->substr(5); + ++arg; + } else if (cmHasLiteralPrefix(*arg, "--mt=")) { + this->MtPath = arg->substr(5); + ++arg; } else { std::cerr << "unknown argument '" << *arg << "'\n"; return false; @@ -1799,7 +1807,7 @@ int cmVSLink::LinkIncremental() // Compile the resource file. std::vector rcCommand; - rcCommand.push_back("rc"); + rcCommand.push_back(this->RcPath.empty() ? "rc" : this->RcPath); rcCommand.push_back("/fo" + this->ManifestFileRes); rcCommand.push_back(this->ManifestFileRC); if (!RunCommand("RC Pass 1", rcCommand, this->Verbose, FORMAT_DECIMAL)) { @@ -1858,7 +1866,7 @@ int cmVSLink::LinkNonIncremental() int cmVSLink::RunMT(std::string const& out, bool notify) { std::vector mtCommand; - mtCommand.push_back("mt"); + mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath); mtCommand.push_back("/nologo"); mtCommand.push_back("/manifest"); if (this->LinkGeneratesManifest) { https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0033676796748bd8fe00f3f96d3470405cdb94fe commit 0033676796748bd8fe00f3f96d3470405cdb94fe Author: Brad King AuthorDate: Mon Oct 29 13:32:07 2018 -0400 Commit: Brad King CommitDate: Mon Oct 29 13:40:47 2018 -0400 CUDA: Enable RC language on Windows We need the resource compiler to place manifests in binaries. Make sure it is available. diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index ba1638f..631a7de 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -67,3 +67,5 @@ string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=\"-MD -Zi -O2 -O string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Xcompiler=\"-MD -O1 -Ob1\" -DNDEBUG") set(CMAKE_CUDA_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") + +__windows_compiler_msvc_enable_rc("${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_CXX}") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=02f566a5592ac0438f03a84d713bae6913a7e39a commit 02f566a5592ac0438f03a84d713bae6913a7e39a Author: Brad King AuthorDate: Mon Oct 29 13:30:17 2018 -0400 Commit: Brad King CommitDate: Mon Oct 29 13:40:47 2018 -0400 MSVC: Factor out enable_language(RC) call into helper macro This will be useful to call from elsewhere later. diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index ae180ed..73906c6 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -366,12 +366,15 @@ macro(__windows_compiler_msvc lang) endif() set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) set(CMAKE_NINJA_DEPTYPE_${lang} msvc) + __windows_compiler_msvc_enable_rc("${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}") +endmacro() +macro(__windows_compiler_msvc_enable_rc flags) if(NOT CMAKE_RC_COMPILER_INIT) set(CMAKE_RC_COMPILER_INIT rc) endif() if(NOT CMAKE_RC_FLAGS_INIT) - string(APPEND CMAKE_RC_FLAGS_INIT " ${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}") + string(APPEND CMAKE_RC_FLAGS_INIT " ${flags}") endif() if(NOT CMAKE_RC_FLAGS_DEBUG_INIT) string(APPEND CMAKE_RC_FLAGS_DEBUG_INIT " /D_DEBUG") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b601bb6f1c30c97e21ea893e8c84b05aab97fcb4 commit b601bb6f1c30c97e21ea893e8c84b05aab97fcb4 Author: Brad King AuthorDate: Mon Oct 29 13:25:49 2018 -0400 Commit: Brad King CommitDate: Mon Oct 29 13:40:47 2018 -0400 CUDA: Find CMAKE_LINKER on Windows We use this in `Modules/Platform/Windows-NVIDIA-CUDA.cmake`, so make sure it is available. diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index 9761d8c..e1e1d33 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -26,3 +26,5 @@ set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_HOST_IMPLIC set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES@") set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") + +set(CMAKE_LINKER "@CMAKE_LINKER@") diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 830639d..b805fa7 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -44,6 +44,7 @@ set(_CMAKE_TOOL_VARS "") if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xPGI") + OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xNVIDIA") OR (CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4babc9058a996e9cccd183eb25eda5faedd04591 commit 4babc9058a996e9cccd183eb25eda5faedd04591 Author: Ben Boeckel AuthorDate: Mon Oct 22 16:48:28 2018 -0400 Commit: Ben Boeckel CommitDate: Fri Oct 26 12:09:41 2018 -0400 cmTargetPropCommandBase: check keywords after parsing The following was disallowed: add_library(iface INTERFACE) target_link_libraries(iface PUBLIC) just due to the mention of the `PUBLIC` keyword. Instead, only error if there are actually `PUBLIC` dependencies specified (and analogously for other restrictions). Update tests to expect this new behavior. diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 48348f3..1b8ee81 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -84,15 +84,6 @@ bool cmTargetPropCommandBase::ProcessContentArgs( this->SetError("called with invalid arguments"); return false; } - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && - scope != "INTERFACE") { - this->SetError("may only set INTERFACE properties on INTERFACE targets"); - return false; - } - if (this->Target->IsImported() && scope != "INTERFACE") { - this->SetError("may only set INTERFACE properties on IMPORTED targets"); - return false; - } ++argIndex; @@ -105,6 +96,17 @@ bool cmTargetPropCommandBase::ProcessContentArgs( } content.push_back(args[i]); } + if (!content.empty()) { + if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && + scope != "INTERFACE") { + this->SetError("may only set INTERFACE properties on INTERFACE targets"); + return false; + } + if (this->Target->IsImported() && scope != "INTERFACE") { + this->SetError("may only set INTERFACE properties on IMPORTED targets"); + return false; + } + } return this->PopulateTargetProperies(scope, content, prepend, system); } diff --git a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt deleted file mode 100644 index d8fb3ba..0000000 --- a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_compile_definitions\): - target_compile_definitions may only set INTERFACE properties on INTERFACE - targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt deleted file mode 100644 index eecd3cf..0000000 --- a/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_compile_features\): - target_compile_features may only set INTERFACE properties on INTERFACE - targets -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt deleted file mode 100644 index 381ff48..0000000 --- a/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_compile_options\): - target_compile_options may only set INTERFACE properties on INTERFACE - targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt b/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt deleted file mode 100644 index 6200703..0000000 --- a/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_include_directories\): - target_include_directories may only set INTERFACE properties on INTERFACE - targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt b/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt deleted file mode 100644 index 26ee9a1..0000000 --- a/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_link_directories\): - target_link_directories may only set INTERFACE properties on INTERFACE - targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt b/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt deleted file mode 100644 index 0103d00..0000000 --- a/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,4 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_link_options\): - target_link_options may only set INTERFACE properties on INTERFACE targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_sources/empty_keyword_args-result.txt b/Tests/RunCMake/target_sources/empty_keyword_args-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/target_sources/empty_keyword_args-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt deleted file mode 100644 index 9ff5bb0..0000000 --- a/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt +++ /dev/null @@ -1,4 +0,0 @@ -CMake Error at empty_keyword_args.cmake:2 \(target_sources\): - target_sources may only set INTERFACE properties on INTERFACE targets -Call Stack \(most recent call first\): - CMakeLists.txt:5 \(include\) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=45a49ae58abe835bc3ad446b054fa07035c33d60 commit 45a49ae58abe835bc3ad446b054fa07035c33d60 Author: Ben Boeckel AuthorDate: Fri Oct 26 09:16:24 2018 -0400 Commit: Ben Boeckel CommitDate: Fri Oct 26 12:08:45 2018 -0400 cmTargetPropCommandBase: simplify code path The outside of the loop does the same return expression. diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index cd82299..48348f3 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -101,7 +101,7 @@ bool cmTargetPropCommandBase::ProcessContentArgs( for (unsigned int i = argIndex; i < args.size(); ++i, ++argIndex) { if (args[i] == "PUBLIC" || args[i] == "PRIVATE" || args[i] == "INTERFACE") { - return this->PopulateTargetProperies(scope, content, prepend, system); + break; } content.push_back(args[i]); } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9f64974f5eff103ceda107c362c66c2adc1997ba commit 9f64974f5eff103ceda107c362c66c2adc1997ba Author: Ben Boeckel AuthorDate: Fri Oct 26 09:14:44 2018 -0400 Commit: Ben Boeckel CommitDate: Fri Oct 26 12:08:16 2018 -0400 cmTargetPropCommandBase: skip property setting if there's nothing to add Some target types don't allow setting certain properties even if there is no value being set there. Guard against this by avoiding property setting when there is nothing to add. diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 9a8fd96..cd82299 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -112,6 +112,9 @@ bool cmTargetPropCommandBase::PopulateTargetProperies( const std::string& scope, const std::vector& content, bool prepend, bool system) { + if (content.empty()) { + return true; + } if (scope == "PRIVATE" || scope == "PUBLIC") { if (!this->HandleDirectContent(this->Target, content, prepend, system)) { return false; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4201a11c2b5a5bdb442f99f88a5f17d6ae7c4a4c commit 4201a11c2b5a5bdb442f99f88a5f17d6ae7c4a4c Author: Ben Boeckel AuthorDate: Fri Oct 26 09:11:42 2018 -0400 Commit: Ben Boeckel CommitDate: Fri Oct 26 12:08:05 2018 -0400 Tests: add tests for empty-value keyword arguments in target_* Not all of these commands accept non-compilable (i.e., IMPORTED) targets, so those calls are currently just commented out. If they ever do start to accept them, the tests should be enabled. diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 90681b9..b2880b6 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -342,11 +342,16 @@ endif() add_RunCMake_test(File_Generate) add_RunCMake_test(ExportWithoutLanguage) +add_RunCMake_test(target_link_directories) add_RunCMake_test(target_link_libraries) add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) +add_RunCMake_test(target_compile_definitions) add_RunCMake_test(target_compile_features) +add_RunCMake_test(target_compile_options) +add_RunCMake_test(target_include_directories) +add_RunCMake_test(target_sources) add_RunCMake_test(CheckModules) add_RunCMake_test(CheckIPOSupported) add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}) diff --git a/Tests/RunCMake/target_compile_definitions/CMakeLists.txt b/Tests/RunCMake/target_compile_definitions/CMakeLists.txt new file mode 100644 index 0000000..14ef56e --- /dev/null +++ b/Tests/RunCMake/target_compile_definitions/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.11) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake new file mode 100644 index 0000000..b67c598 --- /dev/null +++ b/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..d8fb3ba --- /dev/null +++ b/Tests/RunCMake/target_compile_definitions/empty_keyword_args-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_compile_definitions\): + target_compile_definitions may only set INTERFACE properties on INTERFACE + targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_compile_definitions/empty_keyword_args.cmake b/Tests/RunCMake/target_compile_definitions/empty_keyword_args.cmake new file mode 100644 index 0000000..cb94e87 --- /dev/null +++ b/Tests/RunCMake/target_compile_definitions/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_compile_definitions(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_compile_definitions(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake index 1f67f11..f8b0809 100644 --- a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake @@ -12,3 +12,4 @@ run_cmake(no_matching_cxx_feature) run_cmake(not_a_c_feature) run_cmake(no_matching_c_feature) run_cmake(cxx_not_enabled) +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_compile_features/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..eecd3cf --- /dev/null +++ b/Tests/RunCMake/target_compile_features/empty_keyword_args-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_compile_features\): + target_compile_features may only set INTERFACE properties on INTERFACE + targets +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_features/empty_keyword_args.cmake b/Tests/RunCMake/target_compile_features/empty_keyword_args.cmake new file mode 100644 index 0000000..8d57c1c --- /dev/null +++ b/Tests/RunCMake/target_compile_features/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_compile_features(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_compile_features(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_compile_options/CMakeLists.txt b/Tests/RunCMake/target_compile_options/CMakeLists.txt new file mode 100644 index 0000000..14ef56e --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.11) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake new file mode 100644 index 0000000..b67c598 --- /dev/null +++ b/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt b/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_compile_options/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..381ff48 --- /dev/null +++ b/Tests/RunCMake/target_compile_options/empty_keyword_args-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_compile_options\): + target_compile_options may only set INTERFACE properties on INTERFACE + targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_compile_options/empty_keyword_args.cmake b/Tests/RunCMake/target_compile_options/empty_keyword_args.cmake new file mode 100644 index 0000000..8b92fcf --- /dev/null +++ b/Tests/RunCMake/target_compile_options/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_compile_options(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_compile_options(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_include_directories/CMakeLists.txt b/Tests/RunCMake/target_include_directories/CMakeLists.txt new file mode 100644 index 0000000..14ef56e --- /dev/null +++ b/Tests/RunCMake/target_include_directories/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.11) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake b/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake new file mode 100644 index 0000000..b67c598 --- /dev/null +++ b/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt b/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_include_directories/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..6200703 --- /dev/null +++ b/Tests/RunCMake/target_include_directories/empty_keyword_args-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_include_directories\): + target_include_directories may only set INTERFACE properties on INTERFACE + targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_include_directories/empty_keyword_args.cmake b/Tests/RunCMake/target_include_directories/empty_keyword_args.cmake new file mode 100644 index 0000000..08eaf91 --- /dev/null +++ b/Tests/RunCMake/target_include_directories/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_include_directories(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_include_directories(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_link_directories/CMakeLists.txt b/Tests/RunCMake/target_link_directories/CMakeLists.txt new file mode 100644 index 0000000..14ef56e --- /dev/null +++ b/Tests/RunCMake/target_link_directories/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.11) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake new file mode 100644 index 0000000..b67c598 --- /dev/null +++ b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt b/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_directories/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..26ee9a1 --- /dev/null +++ b/Tests/RunCMake/target_link_directories/empty_keyword_args-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_link_directories\): + target_link_directories may only set INTERFACE properties on INTERFACE + targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_link_directories/empty_keyword_args.cmake b/Tests/RunCMake/target_link_directories/empty_keyword_args.cmake new file mode 100644 index 0000000..aadf80a --- /dev/null +++ b/Tests/RunCMake/target_link_directories/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_link_directories(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_link_directories(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake index a041d6d..0152d4c 100644 --- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake @@ -19,3 +19,4 @@ run_cmake(SharedDepNotTarget) run_cmake(StaticPrivateDepNotExported) run_cmake(StaticPrivateDepNotTarget) run_cmake(UNKNOWN-IMPORTED-GLOBAL) +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_link_libraries/empty_keyword_args.cmake b/Tests/RunCMake/target_link_libraries/empty_keyword_args.cmake new file mode 100644 index 0000000..440fa06 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/empty_keyword_args.cmake @@ -0,0 +1,4 @@ +add_library(iface INTERFACE) +target_link_libraries(iface PUBLIC PRIVATE INTERFACE) +add_library(imported UNKNOWN IMPORTED) +target_link_libraries(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake index 1eaa5d2..1d9ef8b 100644 --- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake @@ -39,3 +39,5 @@ if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)") run_cmake_target(LINKER_expansion LINKER linker) run_cmake_target(LINKER_expansion LINKER_SHELL linker_shell) endif() + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt b/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_options/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..0103d00 --- /dev/null +++ b/Tests/RunCMake/target_link_options/empty_keyword_args-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_link_options\): + target_link_options may only set INTERFACE properties on INTERFACE targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_link_options/empty_keyword_args.cmake b/Tests/RunCMake/target_link_options/empty_keyword_args.cmake new file mode 100644 index 0000000..a1a297e --- /dev/null +++ b/Tests/RunCMake/target_link_options/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_link_options(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_link_options(imported PUBLIC PRIVATE INTERFACE) diff --git a/Tests/RunCMake/target_sources/CMakeLists.txt b/Tests/RunCMake/target_sources/CMakeLists.txt new file mode 100644 index 0000000..14ef56e --- /dev/null +++ b/Tests/RunCMake/target_sources/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.11) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_sources/RunCMakeTest.cmake b/Tests/RunCMake/target_sources/RunCMakeTest.cmake new file mode 100644 index 0000000..b67c598 --- /dev/null +++ b/Tests/RunCMake/target_sources/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(empty_keyword_args) diff --git a/Tests/RunCMake/target_sources/empty_keyword_args-result.txt b/Tests/RunCMake/target_sources/empty_keyword_args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_sources/empty_keyword_args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt b/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt new file mode 100644 index 0000000..9ff5bb0 --- /dev/null +++ b/Tests/RunCMake/target_sources/empty_keyword_args-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at empty_keyword_args.cmake:2 \(target_sources\): + target_sources may only set INTERFACE properties on INTERFACE targets +Call Stack \(most recent call first\): + CMakeLists.txt:5 \(include\) diff --git a/Tests/RunCMake/target_sources/empty_keyword_args.cmake b/Tests/RunCMake/target_sources/empty_keyword_args.cmake new file mode 100644 index 0000000..5cee451 --- /dev/null +++ b/Tests/RunCMake/target_sources/empty_keyword_args.cmake @@ -0,0 +1,5 @@ +add_library(iface INTERFACE) +target_sources(iface PUBLIC PRIVATE INTERFACE) +# Cannot be called with non-compilable targets. +#add_library(imported UNKNOWN IMPORTED) +#target_sources(imported PUBLIC PRIVATE INTERFACE) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3eebe28ef41a298f9743db44a7265742891fc225 commit 3eebe28ef41a298f9743db44a7265742891fc225 Author: Mateusz Zych AuthorDate: Sat Oct 6 22:29:37 2018 +0200 Commit: Brad King CommitDate: Fri Oct 26 11:31:37 2018 -0400 cmLocalNinjaGenerator: Simplify CreateRulePlaceholderExpander Re-use the derived class implementation instead of duplicating it. diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index eb31478..66edc91 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -17,6 +17,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalNinjaGenerator.h" +#include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmNinjaTargetGenerator.h" #include "cmRulePlaceholderExpander.h" @@ -40,8 +41,7 @@ cmRulePlaceholderExpander* cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const { cmRulePlaceholderExpander* ret = - new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings, - this->CompilerSysroot, this->LinkerSysroot); + this->cmLocalGenerator::CreateRulePlaceholderExpander(); ret->SetTargetImpLib("$TARGET_IMPLIB"); return ret; } ----------------------------------------------------------------------- Summary of changes: Help/release/dev/FindGDAL-target.rst | 4 ++ Modules/CMakeASMCompiler.cmake.in | 1 + Modules/CMakeCCompiler.cmake.in | 1 + Modules/CMakeCUDACompiler.cmake.in | 3 ++ Modules/CMakeCXXCompiler.cmake.in | 1 + Modules/CMakeFindBinUtils.cmake | 53 ++++++++++++++------ Modules/FindGDAL.cmake | 57 +++++++++++++++++----- Modules/Platform/Windows-MSVC.cmake | 9 ++-- Modules/Platform/Windows-NVIDIA-CUDA.cmake | 6 ++- Source/cmLocalGenerator.cxx | 1 + Source/cmLocalNinjaGenerator.cxx | 4 +- Source/cmTargetPropCommandBase.cxx | 25 ++++++---- Source/cmcmd.cxx | 12 ++++- Tests/CMakeLists.txt | 4 ++ Tests/FindGDAL/CMakeLists.txt | 10 ++++ Tests/FindGDAL/Test/CMakeLists.txt | 16 ++++++ Tests/FindGDAL/Test/main.c | 11 +++++ Tests/RunCMake/CMakeLists.txt | 5 ++ .../CMakeLists.txt | 0 .../target_compile_definitions/RunCMakeTest.cmake | 3 ++ .../empty_keyword_args.cmake | 5 ++ .../target_compile_features/RunCMakeTest.cmake | 1 + .../empty_keyword_args.cmake | 5 ++ .../CMakeLists.txt | 0 .../target_compile_options/RunCMakeTest.cmake | 3 ++ .../empty_keyword_args.cmake | 5 ++ .../CMakeLists.txt | 0 .../target_include_directories/RunCMakeTest.cmake | 3 ++ .../empty_keyword_args.cmake | 5 ++ .../CMakeLists.txt | 0 .../target_link_directories/RunCMakeTest.cmake | 3 ++ .../empty_keyword_args.cmake | 5 ++ .../target_link_libraries/RunCMakeTest.cmake | 1 + .../target_link_libraries/empty_keyword_args.cmake | 4 ++ .../target_link_options/RunCMakeTest.cmake | 2 + .../target_link_options/empty_keyword_args.cmake | 5 ++ .../CMakeLists.txt | 0 Tests/RunCMake/target_sources/RunCMakeTest.cmake | 3 ++ .../target_sources/empty_keyword_args.cmake | 5 ++ 39 files changed, 235 insertions(+), 46 deletions(-) create mode 100644 Help/release/dev/FindGDAL-target.rst create mode 100644 Tests/FindGDAL/CMakeLists.txt create mode 100644 Tests/FindGDAL/Test/CMakeLists.txt create mode 100644 Tests/FindGDAL/Test/main.c copy Tests/RunCMake/{target_link_options => target_compile_definitions}/CMakeLists.txt (100%) create mode 100644 Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/target_compile_definitions/empty_keyword_args.cmake create mode 100644 Tests/RunCMake/target_compile_features/empty_keyword_args.cmake copy Tests/RunCMake/{target_link_options => target_compile_options}/CMakeLists.txt (100%) create mode 100644 Tests/RunCMake/target_compile_options/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/target_compile_options/empty_keyword_args.cmake copy Tests/RunCMake/{target_link_options => target_include_directories}/CMakeLists.txt (100%) create mode 100644 Tests/RunCMake/target_include_directories/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/target_include_directories/empty_keyword_args.cmake copy Tests/RunCMake/{target_link_options => target_link_directories}/CMakeLists.txt (100%) create mode 100644 Tests/RunCMake/target_link_directories/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/target_link_directories/empty_keyword_args.cmake create mode 100644 Tests/RunCMake/target_link_libraries/empty_keyword_args.cmake create mode 100644 Tests/RunCMake/target_link_options/empty_keyword_args.cmake copy Tests/RunCMake/{target_link_options => target_sources}/CMakeLists.txt (100%) create mode 100644 Tests/RunCMake/target_sources/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/target_sources/empty_keyword_args.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 09:35:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 09:35:04 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-313-g0730fb5 Message-ID: <20181102133504.7892512658A@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 0730fb5c44e8b7bcd07fa902a7704215f2080245 (commit) via 3a77329c40803b02fe33ffc86197c1baf291aaff (commit) from bdc5618e18b9868f46e48641cdd35f361199f28e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0730fb5c44e8b7bcd07fa902a7704215f2080245 commit 0730fb5c44e8b7bcd07fa902a7704215f2080245 Merge: bdc5618 3a77329c Author: Brad King AuthorDate: Fri Nov 2 09:25:14 2018 -0400 Commit: Brad King CommitDate: Fri Nov 2 09:25:14 2018 -0400 Merge branch 'release-3.12' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3a77329c40803b02fe33ffc86197c1baf291aaff commit 3a77329c40803b02fe33ffc86197c1baf291aaff Author: Brad King AuthorDate: Fri Nov 2 08:05:07 2018 -0400 Commit: Brad King CommitDate: Fri Nov 2 08:05:07 2018 -0400 CMake 3.12.4 diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4978bd6..ff557e1 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 12) -set(CMake_VERSION_PATCH 3) +set(CMake_VERSION_PATCH 4) #set(CMake_VERSION_RC 0) ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 2 09:35:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 2 Nov 2018 09:35:04 -0400 (EDT) Subject: [Cmake-commits] CMake annotated tag, v3.12.4, created. v3.12.4 Message-ID: <20181102133504.8AC6312658B@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The annotated tag, v3.12.4 has been created at d1846ce57eb34bed25cb09801ac4a4ed03e3f6f6 (tag) tagging 3a77329c40803b02fe33ffc86197c1baf291aaff (commit) replaces v3.12.3 tagged by Brad King on Fri Nov 2 09:18:42 2018 -0400 - Log ----------------------------------------------------------------- CMake 3.12.4 -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEExsJlMku+vcNQtRPQLSzvEDSSFoQFAlvcTrIWHGJyYWQua2lu Z0BraXR3YXJlLmNvbQAKCRAtLO8QNJIWhEyuD/4iKXQMfEEAVMvCWvybyHTnBkQi fnO3zfYa0vvaLMkgbKzaoepmqema50tLrIdHZVrDUZcn9jUmjVbR46QhhlaLB4he 6/psNhWae36piVoPip10dRNOxythB5MwA5kPrnETjGDrLO1bBfy4TVI5UcPr+UHR R5hQBIZUdAsajI3vrSRDwjV3Rkblwqi9Z8WBx1d6qe/RHV4k1TMQPSls4LoxRSPI GTA0kMJjxUsvmwwY4KS6pp1HXukNpJE7zeCekDmZLcMsd/P5OYu5nOXRg2K9SYPY +b++z8NVnTY7iZ99ndj3xQGZik4rS52AZXqM+sPQxBRfUCSfnO8QtWICN28kPqgs RH5djwrmLWXfweLjrfiPiU53s323jQMGMiBxcz9bUdu4ZNdR2T20hyv3TipN4bkK +MEGKEd1WN56XBryXuuZfvM0etI7iwwDag4BoHx5tJWFGqosVuRJDiFsKtcgsn0a io5xZrc+TYh7lJOJIuJaWWFdFGuOkPdGVtZUOnN56ft2L6O2MHrfq31kRBV6UbiJ cViXkj7IaePVfpPnRXKyEKKhQ4mPiYzDyX3i1AuTGpJ/t/fT8RkKRaFiKPDzrQev jhMCEshehRm9Oz0Bw85+g97G6IPvOoVxfZFhUmNd6uF1loaRQ7mtf+uItLzsFj7U qNDvyOEnmdTiSXha1Q== =fq8x -----END PGP SIGNATURE----- Brad King (12): Merge branch 'UseSWIG-php-regression' into release-3.12 Merge branch 'backport-FindMatlab-missing-install' into release-3.12 Merge branch 'cuda-filter-device-link-items' into release-3.12 cmake: Distinguish '-E tar' warnings from errors copying data Merge branch 'tar-warnings' into release-3.12 set_directory_properties: Restore in script mode Merge branch 'set_directory_properties-script-mode' into release-3.12 Merge branch 'backport-cuda-filter-device-link-libs' into release-3.12 CSharp: Fix regression in VS project type selection for custom target Merge branch 'backport-fix-custom-target-with-csharp' into release-3.12 Merge branch 'server-file-monitor-check' into release-3.12 CMake 3.12.4 Chuck Atkins (1): FindMatlab: Guard against nonexistent installation Marc Chevrier (1): UseSWIG: fix regression for PHP language Robert Maynard (2): CUDA: Filter out host link flags during device linking CUDA: Filter out non-static libraries during device linking Vladimir Penev (1): server: Fix assertion failure on directory paths in file monitor ----------------------------------------------------------------------- hooks/post-receive -- CMake From kwrobot at kitware.com Sat Nov 3 00:05:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sat, 3 Nov 2018 00:05:05 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-314-g443c574 Message-ID: <20181103040505.31F3112616F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 443c574a7cc39ea490fabd1392108e651806a3e6 (commit) from 0730fb5c44e8b7bcd07fa902a7704215f2080245 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=443c574a7cc39ea490fabd1392108e651806a3e6 commit 443c574a7cc39ea490fabd1392108e651806a3e6 Author: Kitware Robot AuthorDate: Sat Nov 3 00:01:09 2018 -0400 Commit: Kitware Robot CommitDate: Sat Nov 3 00:01:09 2018 -0400 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b0b01c8..5c5c21e 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 13) -set(CMake_VERSION_PATCH 20181102) +set(CMake_VERSION_PATCH 20181103) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 4 00:05:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 4 Nov 2018 00:05:03 -0400 (EDT) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-315-g112100d Message-ID: <20181104040503.EE82412628D@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 112100da9033fdf678e83ac65580dc456b83a2cb (commit) from 443c574a7cc39ea490fabd1392108e651806a3e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=112100da9033fdf678e83ac65580dc456b83a2cb commit 112100da9033fdf678e83ac65580dc456b83a2cb Author: Kitware Robot AuthorDate: Sun Nov 4 00:01:06 2018 -0400 Commit: Kitware Robot CommitDate: Sun Nov 4 00:01:06 2018 -0400 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 5c5c21e..459202e 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 13) -set(CMake_VERSION_PATCH 20181103) +set(CMake_VERSION_PATCH 20181104) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 4 20:05:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 4 Nov 2018 20:05:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-317-gaa78b61 Message-ID: <20181105010504.579B6126757@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via aa78b61bbcc346e602f7f982ecb8ac8f8e72623d (commit) via c12eefa8fdad306f938b7858168b3e65cd9740d6 (commit) from 112100da9033fdf678e83ac65580dc456b83a2cb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=aa78b61bbcc346e602f7f982ecb8ac8f8e72623d commit aa78b61bbcc346e602f7f982ecb8ac8f8e72623d Merge: 112100d c12eefa Author: Craig Scott AuthorDate: Mon Nov 5 01:00:26 2018 +0000 Commit: Kitware Robot CommitDate: Sun Nov 4 20:01:08 2018 -0500 Merge topic 'cpack-gen-docs-link' c12eefa8fd Help: Fix generators link in cpack(1) manual Acked-by: Kitware Robot Merge-request: !2562 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c12eefa8fdad306f938b7858168b3e65cd9740d6 commit c12eefa8fdad306f938b7858168b3e65cd9740d6 Author: Craig Scott AuthorDate: Sun Nov 4 08:50:22 2018 +1100 Commit: Craig Scott CommitDate: Sun Nov 4 08:50:22 2018 +1100 Help: Fix generators link in cpack(1) manual Minor rewording around the updated link and extra blank line added to improve readability and remove a potential ambiguity around the same area. Fixes: #18545 diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst index 87aa38d..6159d7b 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst @@ -29,9 +29,10 @@ Options package(s) in that generator's format according to the details provided in the ``CPackConfig.cmake`` configuration file. A generator is responsible for generating the required inputs for a particular package system and invoking - that system's package creation tools. Possible generator names are specified - in the :manual:`Generators ` section of the manual and + that system's package creation tools. All supported generators are specified + in the :manual:`Generators ` section of the manual and the ``--help`` option lists the generators supported for the target platform. + If this option is not given, the :variable:`CPACK_GENERATOR` variable determines the default set of generators that will be used. ----------------------------------------------------------------------- Summary of changes: Help/manual/cpack.1.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 4 20:25:02 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 4 Nov 2018 20:25:02 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-319-g4961092 Message-ID: <20181105012502.B0F601265D9@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 4961092cad1627bb7703bee8e43439de9ab8fafb (commit) via 03d00d63dfc2ee5ed3775eccdbd012245acba6ce (commit) from aa78b61bbcc346e602f7f982ecb8ac8f8e72623d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4961092cad1627bb7703bee8e43439de9ab8fafb commit 4961092cad1627bb7703bee8e43439de9ab8fafb Merge: aa78b61 03d00d6 Author: Craig Scott AuthorDate: Mon Nov 5 12:06:29 2018 +1100 Commit: Craig Scott CommitDate: Mon Nov 5 12:06:29 2018 +1100 Merge branch 'release-3.13' ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 4 20:25:02 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 4 Nov 2018 20:25:02 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-29-g03d00d6 Message-ID: <20181105012502.C36AE1265DA@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 03d00d63dfc2ee5ed3775eccdbd012245acba6ce (commit) via c12eefa8fdad306f938b7858168b3e65cd9740d6 (commit) from a567f533dbbcb0d41ac38837f2593059a456fe5e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Help/manual/cpack.1.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 5 00:05:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 5 Nov 2018 00:05:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-320-g95894a6 Message-ID: <20181105050506.25E4D12679C@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 95894a605e3c39c73390f4db1868c457b16bf5a2 (commit) from 4961092cad1627bb7703bee8e43439de9ab8fafb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=95894a605e3c39c73390f4db1868c457b16bf5a2 commit 95894a605e3c39c73390f4db1868c457b16bf5a2 Author: Kitware Robot AuthorDate: Mon Nov 5 00:01:52 2018 -0500 Commit: Kitware Robot CommitDate: Mon Nov 5 00:01:52 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 459202e..cfce90d 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 13) -set(CMake_VERSION_PATCH 20181104) +set(CMake_VERSION_PATCH 20181105) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 5 07:45:08 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 5 Nov 2018 07:45:08 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-329-gb83420e Message-ID: <20181105124509.1BD641262E0@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via b83420e45d963e2decd94336b97c127c75eed990 (commit) via 259292ebcccac1a3aba931d2437e1432f77c0945 (commit) via 98d59417b0c6ac3ea85e315133337030dad93496 (commit) via c1ad5118deb0eb52c2130e0fb3363f44c25bf42e (commit) via 03bf934fbe93ef04d6c62c64912d2f212db997b7 (commit) via 2b3c1bb9b014cf34ab882b8ab9569846c274cc8a (commit) via 636bcefeab3b386e65efe03b199b9b2614d8a78d (commit) via 9835e9075037db3d23ade0ef865c562b08cf6023 (commit) via 9c6574795c404417939c889d8cb45095c4175474 (commit) from 95894a605e3c39c73390f4db1868c457b16bf5a2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b83420e45d963e2decd94336b97c127c75eed990 commit b83420e45d963e2decd94336b97c127c75eed990 Merge: 259292e c1ad511 Author: Brad King AuthorDate: Mon Nov 5 12:42:38 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 5 07:43:41 2018 -0500 Merge topic 'update-curl' c1ad5118de curl: backport upstream fix to 7.62.0 regression 03bf934fbe curl: Modernize tiny test code used for build inside CMake 2b3c1bb9b0 curl: Update build within CMake to account for 7.62 changes 636bcefeab Merge branch 'upstream-curl' into update-curl 9835e90750 curl 2018-10-30 (19667715) 9c6574795c curl: Update script to get curl 7.62.0 Acked-by: Kitware Robot Merge-request: !2550 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=259292ebcccac1a3aba931d2437e1432f77c0945 commit 259292ebcccac1a3aba931d2437e1432f77c0945 Merge: 95894a6 98d5941 Author: Brad King AuthorDate: Mon Nov 5 12:42:27 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 5 07:42:47 2018 -0500 Merge topic 'custom-command-work-dir-genex' 98d59417b0 add_custom_{command,target}: Fix WORKING_DIRECTORY leading genex Acked-by: Kitware Robot Merge-request: !2559 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=98d59417b0c6ac3ea85e315133337030dad93496 commit 98d59417b0c6ac3ea85e315133337030dad93496 Author: Brad King AuthorDate: Fri Nov 2 12:46:00 2018 -0400 Commit: Brad King CommitDate: Sat Nov 3 08:39:45 2018 -0400 add_custom_{command,target}: Fix WORKING_DIRECTORY leading genex Since commit v3.13.0-rc1~39^2 (add_custom_{command,target}: WORKING_DIRECTORY generator expressions, 2018-09-22) the `WORKING_DIRECTORY` option accepts generator expressions. Fix support for the case of a leading generator expression by deferring conversion to an absolute path until after evaluation of the generator expression. Fixes: #18543 diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 91ccdf7..53f5593 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -318,12 +318,6 @@ bool cmAddCustomCommandCommand::InitialPass( return false; } - // Convert working directory to a full path. - if (!working.empty()) { - const std::string& build_dir = this->Makefile->GetCurrentBinaryDirectory(); - working = cmSystemTools::CollapseFullPath(working, build_dir); - } - // Choose which mode of the command to use. bool escapeOldStyle = !verbatim; if (source.empty() && output.empty()) { diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 82ee6b4..ddd9b70 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -181,13 +181,6 @@ bool cmAddCustomTargetCommand::InitialPass( } } - // Convert working directory to a full path. - if (!working_directory.empty()) { - const std::string& build_dir = this->Makefile->GetCurrentBinaryDirectory(); - working_directory = - cmSystemTools::CollapseFullPath(working_directory, build_dir); - } - if (commandLines.empty() && !byproducts.empty()) { this->Makefile->IssueMessage( cmake::FATAL_ERROR, diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 5bbae17..d1c1736 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -70,6 +70,12 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::unique_ptr cge = this->GE->Parse(workingdirectory); this->WorkingDirectory = cge->Evaluate(this->LG, this->Config); + // Convert working directory to a full path. + if (!this->WorkingDirectory.empty()) { + std::string const& build_dir = this->LG->GetCurrentBinaryDirectory(); + this->WorkingDirectory = + cmSystemTools::CollapseFullPath(this->WorkingDirectory, build_dir); + } } } diff --git a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt index 2e12a78..3bab1fe 100644 --- a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt +++ b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt @@ -47,7 +47,7 @@ file(MAKE_DIRECTORY ${TestWorkingDir_BINARY_DIR}/genex) add_custom_command( OUTPUT "${TestWorkingDir_BINARY_DIR}/genex/working.c" COMMAND "${CMAKE_COMMAND}" -E copy "${TestWorkingDir_SOURCE_DIR}/working.c.in" "${TestWorkingDir_BINARY_DIR}/genex/working.c" - WORKING_DIRECTORY "${TestWorkingDir_BINARY_DIR}/$<1:genex>/" + WORKING_DIRECTORY "$<0:not_used/>${TestWorkingDir_BINARY_DIR}/$<1:genex>/" COMMENT "custom command" ) @@ -58,7 +58,7 @@ add_custom_target( CustomGenex ALL COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${TestWorkingDir_SOURCE_DIR}/customTarget.c" "${TestWorkingDir_BINARY_DIR}/genex/customTarget.c" BYPRODUCTS "${TestWorkingDir_BINARY_DIR}/genex/customTarget.c" - WORKING_DIRECTORY "${TestWorkingDir_BINARY_DIR}/$<1:genex>/" + WORKING_DIRECTORY "$<0:not_used/>${TestWorkingDir_BINARY_DIR}/$<1:genex>/" ) add_dependencies(workinggenex CustomGenex) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c1ad5118deb0eb52c2130e0fb3363f44c25bf42e commit c1ad5118deb0eb52c2130e0fb3363f44c25bf42e Author: Brad King AuthorDate: Fri Nov 2 08:14:12 2018 -0400 Commit: Brad King CommitDate: Fri Nov 2 08:14:12 2018 -0400 curl: backport upstream fix to 7.62.0 regression Backport upstream curl commit 2c5ec339ea (Curl_follow: accept non-supported schemes for "fake" redirects, 2018-11-01) to get a fix to curl issue 3210, a regression in 7.62.0. diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c index b73f94d..05ba862 100644 --- a/Utilities/cmcurl/lib/transfer.c +++ b/Utilities/cmcurl/lib/transfer.c @@ -1514,7 +1514,8 @@ CURLcode Curl_follow(struct Curl_easy *data, disallowport = TRUE; DEBUGASSERT(data->state.uh); - uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, 0); + uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, + (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : 0); if(uc) return Curl_uc_to_curlcode(uc); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=03bf934fbe93ef04d6c62c64912d2f212db997b7 commit 03bf934fbe93ef04d6c62c64912d2f212db997b7 Author: Brad King AuthorDate: Thu Nov 1 08:35:48 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 08:55:50 2018 -0400 curl: Modernize tiny test code used for build inside CMake Drop unused code. Report the error message on failure. Format the source file using clang-format. diff --git a/Utilities/.gitattributes b/Utilities/.gitattributes index 96a4323..81bbf26 100644 --- a/Utilities/.gitattributes +++ b/Utilities/.gitattributes @@ -5,3 +5,4 @@ SetupForDevelopment.sh export-ignore # Do not format third-party sources. /KWIML/** -format.clang-format-6.0 /cm*/** -format.clang-format-6.0 +/cmcurl/curltest.c format.clang-format-6.0 diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 2d6def4..27b7507 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -1285,11 +1285,11 @@ endif() #----------------------------------------------------------------------------- # CMake-specific curl code. -add_executable(LIBCURL curltest.c) -target_link_libraries(LIBCURL cmcurl) +add_executable(curltest curltest.c) +target_link_libraries(curltest cmcurl) if(BUILD_TESTING AND CMAKE_CURL_TEST_URL) - add_test(curl LIBCURL ${CMAKE_CURL_TEST_URL}) + add_test(curl curltest ${CMAKE_CURL_TEST_URL}) endif() install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl) diff --git a/Utilities/cmcurl/curltest.c b/Utilities/cmcurl/curltest.c index 210868e..f80e758 100644 --- a/Utilities/cmcurl/curltest.c +++ b/Utilities/cmcurl/curltest.c @@ -1,159 +1,81 @@ -/* Prevent warnings on Visual Studio */ -struct _RPC_ASYNC_STATE; - #include "curl/curl.h" + +#include #include #include -int GetFtpFile(void) +int test_curl(const char* url) { - int retVal = 0; - CURL *curl; - CURLcode res; - curl = curl_easy_init(); - if(curl) - { - /* Get curl 7.9.2 from sunet.se's FTP site: */ - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, 1); - curl_easy_setopt(curl, CURLOPT_URL, - "ftp://public.kitware.com/pub/cmake/cygwin/setup.hint"); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: ftp://public.kitware.com/pub/cmake/cygwin/setup.hint\n"); - retVal = 1; - } - - /* always cleanup */ - curl_easy_cleanup(curl); - } - else - { - printf("Cannot create curl object\n"); - retVal = 1; - } - return retVal; -} - -int GetWebFiles(char *url1, char *url2) -{ - int retVal = 0; - CURL *curl; - CURLcode res; - + CURL* curl; + CURLcode r; char proxy[1024]; int proxy_type = 0; - if ( getenv("HTTP_PROXY") ) - { + if (getenv("HTTP_PROXY")) { proxy_type = 1; - if (getenv("HTTP_PROXY_PORT") ) - { + if (getenv("HTTP_PROXY_PORT")) { sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT")); - } - else - { + } else { sprintf(proxy, "%s", getenv("HTTP_PROXY")); - } - if ( getenv("HTTP_PROXY_TYPE") ) - { + } + if (getenv("HTTP_PROXY_TYPE")) { /* HTTP/SOCKS4/SOCKS5 */ - if ( strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0 ) - { + if (strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0) { proxy_type = 1; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0 ) - { + } else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0) { proxy_type = 2; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0 ) - { + } else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0) { proxy_type = 3; - } } } + } curl = curl_easy_init(); - if(curl) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, 1); - - /* Using proxy */ - if ( proxy_type > 0 ) - { - curl_easy_setopt(curl, CURLOPT_PROXY, proxy); - switch (proxy_type) - { - case 2: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); - break; - case 3: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - break; - default: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); - } - } - - /* get the first document */ - curl_easy_setopt(curl, CURLOPT_URL, url1); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: %s\n", url1); - retVal = 1; - } + if (!curl) { + fprintf(stderr, "curl_easy_init failed\n"); + return 1; + } + + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt(curl, CURLOPT_HEADER, 1); + + if (proxy_type > 0) { + curl_easy_setopt(curl, CURLOPT_PROXY, proxy); + switch (proxy_type) { + case 2: + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); + break; + case 3: + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); + break; + default: + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + } + } - /* get another document from the same server using the same - connection */ - /* avoid warnings about url2 since below block is commented out: */ - (void) url2; - /* - curl_easy_setopt(curl, CURLOPT_URL, url2); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: %s\n", url2); - retVal = 1; - } - */ + curl_easy_setopt(curl, CURLOPT_URL, url); + r = curl_easy_perform(curl); + curl_easy_cleanup(curl); - /* always cleanup */ - curl_easy_cleanup(curl); - } - else - { - printf("Cannot create curl object\n"); - retVal = 1; - } + if (r != CURLE_OK) { + fprintf(stderr, "error: fetching '%s' failed: %s\n", url, + curl_easy_strerror(r)); + return 1; + } - return retVal; + return 0; } - -int main(int argc, char **argv) +int main(int argc, const char* argv[]) { - int retVal = 0; - + int r; curl_global_init(CURL_GLOBAL_DEFAULT); - - if(argc>1) - { - retVal += GetWebFiles(argv[1], 0); - } - else - { - printf("error: first argument should be a url to download\n"); - retVal = 1; - } - - /* Do not check the output of FTP socks5 cannot handle FTP yet */ - /* GetFtpFile(); */ - /* do not test ftp right now because we don't enable that port */ - + if (argc == 2) { + r = test_curl(argv[1]); + } else { + fprintf(stderr, "error: no URL given as first argument\n"); + r = 1; + } curl_global_cleanup(); - - return retVal; + return r; } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2b3c1bb9b014cf34ab882b8ab9569846c274cc8a commit 2b3c1bb9b014cf34ab882b8ab9569846c274cc8a Author: Brad King AuthorDate: Wed Oct 31 09:50:04 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:50:04 2018 -0400 curl: Update build within CMake to account for 7.62 changes diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index b34a493..2d6def4 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -1263,6 +1263,7 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE) endfunction() +if(0) # This code not needed for building within CMake. include(GNUInstallDirs) set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) @@ -1270,6 +1271,7 @@ set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") +endif() if(USE_MANUAL) add_subdirectory(docs) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=636bcefeab3b386e65efe03b199b9b2614d8a78d commit 636bcefeab3b386e65efe03b199b9b2614d8a78d Merge: 9c65747 9835e90 Author: Brad King AuthorDate: Wed Oct 31 09:46:23 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:46:23 2018 -0400 Merge branch 'upstream-curl' into update-curl * upstream-curl: curl 2018-10-30 (19667715) diff --cc Utilities/cmcurl/CMakeLists.txt index 636530e,0000000..b34a493 mode 100644,000000..100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@@ -1,1482 -1,0 +1,1481 @@@ +# Set curl options as needed for CMake build +set(BUILD_CURL_EXE OFF CACHE INTERNAL "No curl exe") +set(BUILD_DASHBOARD_REPORTS OFF CACHE INTERNAL "No curl dashboard reports") +set(BUILD_RELEASE_DEBUG_DIRS OFF CACHE INTERNAL "No curl release/debug dirs") +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Build shared libraries") +set(CMAKE_USE_GSSAPI OFF CACHE INTERNAL "Disable curl gssapi") +set(CMAKE_USE_LIBSSH2 OFF CACHE INTERNAL "Disable curl libssh2") +set(CMAKE_USE_OPENLDAP OFF CACHE INTERNAL "No curl OpenLDAP") +set(CURL_DISABLE_COOKIES OFF CACHE INTERNAL "Do not disable curl cookie support") +set(CURL_DISABLE_CRYPTO_AUTH OFF CACHE INTERNAL "Do not disable curl crypto auth") +set(CURL_DISABLE_DICT ON CACHE INTERNAL "Disable curl dict protocol?") +set(CURL_DISABLE_FILE OFF CACHE INTERNAL "Disable curl file protocol?") +set(CURL_DISABLE_FTP OFF CACHE INTERNAL "Disable curl ftp protocol?") +set(CURL_DISABLE_GOPHER ON CACHE INTERNAL "Disable curl gopher protocol?") +set(CURL_DISABLE_HTTP OFF CACHE INTERNAL "Disable curl http protocol?") +set(CURL_DISABLE_IMAP ON CACHE INTERNAL "Disable curl imap protocol?") +set(CURL_DISABLE_LDAP ON CACHE INTERNAL "Disable curl ldap protocol?") +set(CURL_DISABLE_LDAPS ON CACHE INTERNAL "Disable curl ldaps protocol?") +set(CURL_DISABLE_POP3 ON CACHE INTERNAL "Disable curl pop3 protocol?") +set(CURL_DISABLE_PROXY OFF CACHE INTERNAL "Do not disable curl proxy") +set(CURL_DISABLE_RTSP ON CACHE INTERNAL "Disable curl rtsp protocol?") +set(CURL_DISABLE_SMTP ON CACHE INTERNAL "Disable curl smtp protocol?") +set(CURL_DISABLE_TELNET ON CACHE INTERNAL "Disable curl telnet protocol?") +set(CURL_DISABLE_TFTP ON CACHE INTERNAL "Disable curl tftp protocol?") +set(CURL_DISABLE_VERBOSE_STRINGS OFF CACHE INTERNAL "Do not disable curl verbosity") +set(CURL_HIDDEN_SYMBOLS OFF CACHE INTERNAL "No curl hidden symbols") +set(CURL_WERROR OFF CACHE INTERNAL "Turn compiler warnings into errors") +set(DISABLED_THREADSAFE OFF CACHE INTERNAL "Curl can use thread-safe functions") +set(ENABLE_ARES OFF CACHE INTERNAL "No curl c-ares support") +set(ENABLE_CURLDEBUG OFF CACHE INTERNAL "No curl TrackMemory features") +set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features") +set(ENABLE_IPV6 OFF CACHE INTERNAL "No curl IPv6 support") +set(ENABLE_MANUAL OFF CACHE INTERNAL "No curl built-in manual") +set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup") +set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support") +set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only") +set(PICKY_COMPILER OFF CACHE INTERNAL "Enable picky compiler options") +set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP") +if(CMAKE_USE_OPENSSL) +elseif(WIN32) + set(CMAKE_USE_WINSSL ON CACHE INTERNAL "enable Windows native SSL/TLS") + set(CURL_WINDOWS_SSPI ON CACHE INTERNAL "Use windows libraries to allow NTLM authentication without openssl") +elseif(APPLE) + # Use OS X SSL/TLS native implementation if available on target version. + if(CMAKE_OSX_DEPLOYMENT_TARGET) + set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET}) + else() + execute_process( + COMMAND sw_vers -productVersion + OUTPUT_VARIABLE OSX_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + if(NOT OSX_VERSION VERSION_LESS 10.6 AND + CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + set(CMAKE_USE_DARWINSSL ON CACHE INTERNAL "enable Apple OS native SSL/TLS") + else() + set(CMAKE_USE_DARWINSSL OFF CACHE INTERNAL "enable Apple OS native SSL/TLS") + endif() +endif() +set(CMAKE_USE_MBEDTLS OFF CACHE INTERNAL "Enable mbedTLS for SSL/TLS") + +# Windows Vista and above have inet_pton, but this will link on +# older versions and then the executable will fail to launch at +# runtime on older versions because no DLL provides the symbol. +if(WIN32) + set(HAVE_INET_PTON 0 CACHE INTERNAL "Do not use inet_pton") +endif() + +# Starting with OSX 10.11 there is an unrelated libnetwork library which will +# be picked up during curl configuration. Linking against this library is +# unnecessary and breaks backward compatibility of the resulting binaries +# because libnetwork is unavailable on older OSX versions. +if(APPLE) + set(HAVE_LIBNETWORK 0 CACHE INTERNAL "Do not use libnetwork") +endif(APPLE) + +# Disable warnings to avoid changing 3rd party code. +if(CMAKE_C_COMPILER_ID MATCHES + "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") +elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") +endif() + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +# curl/libcurl CMake script +# by Tetetest and Sukender (Benoit Neil) + +# TODO: +# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file +# Add full (4 or 5 libs) SSL support +# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include). +# Add CTests(?) +# Check on all possible platforms +# Test with as many configurations possible (With or without any option) +# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest: +# - lists of headers that 'configure' checks for; +# - curl-specific tests (the ones that are in m4/curl-*.m4 files); +# - (most obvious thing:) curl version numbers. +# Add documentation subproject +# +# To check: +# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not. +# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options. +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") +include(Utilities) +include(Macros) +include(CMakeDependentOption) +include(CheckCCompilerFlag) + +project(CURL C) + +if(0) # This code not needed for building within CMake. +message(WARNING "the curl cmake build system is poorly maintained. Be aware") +endif() + +file(READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS) +string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" + CURL_VERSION ${CURL_VERSION_H_CONTENTS}) +string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION}) +string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" + CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS}) +string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM}) + +include_regular_expression("^.*$") # Sukender: Is it necessary? + +# Setup package meta-data +# SET(PACKAGE "curl") +if(0) # This code not needed for building within CMake. +message(STATUS "curl version=[${CURL_VERSION}]") +endif() +# SET(PACKAGE_TARNAME "curl") +# SET(PACKAGE_NAME "curl") +# SET(PACKAGE_VERSION "-") +# SET(PACKAGE_STRING "curl-") +# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/") +set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}") +set(OS "\"${CMAKE_SYSTEM_NAME}\"") + +include_directories(${PROJECT_BINARY_DIR}/include/curl) +include_directories(${CURL_SOURCE_DIR}/include) + +option(CURL_WERROR "Turn compiler warnings into errors" OFF) +option(PICKY_COMPILER "Enable picky compiler options" ON) +option(BUILD_CURL_EXE "Set to ON to build curl executable." ON) +option(BUILD_SHARED_LIBS "Build shared libraries" ON) +option(ENABLE_ARES "Set to ON to enable c-ares support" OFF) +if(WIN32) + option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF) + option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON) +endif() + +cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup" + ON "NOT ENABLE_ARES" + OFF) + +option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF) +option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF) + +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) + if(PICKY_COMPILER) - foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers) ++ foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers -Wno-pedantic-ms-format) + # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new + # test result in. + check_c_compiler_flag(${_CCOPT} OPT${_CCOPT}) + if(OPT${_CCOPT}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}") + endif() + endforeach() + endif() +endif() + +if(ENABLE_DEBUG) + # DEBUGBUILD will be defined only for Debug builds + if(NOT CMAKE_VERSION VERSION_LESS 3.0) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$:DEBUGBUILD>) + else() + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD) + endif() + set(ENABLE_CURLDEBUG ON) +endif() + +if(ENABLE_CURLDEBUG) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG) +endif() + +if(0) # This code not needed for building within CMake. +# For debug libs and exes, add "-d" postfix +if(NOT DEFINED CMAKE_DEBUG_POSTFIX) + set(CMAKE_DEBUG_POSTFIX "-d") +endif() +endif() + +# initialize CURL_LIBS +set(CURL_LIBS "") + +if(ENABLE_ARES) + set(USE_ARES 1) + find_package(CARES REQUIRED) + list(APPEND CURL_LIBS ${CARES_LIBRARY}) + set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY}) +endif() + +if(0) # This code not needed for building within CMake. +include(CurlSymbolHiding) +endif() + +option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF) +mark_as_advanced(HTTP_ONLY) +option(CURL_DISABLE_FTP "disables FTP" OFF) +mark_as_advanced(CURL_DISABLE_FTP) +option(CURL_DISABLE_LDAP "disables LDAP" OFF) +mark_as_advanced(CURL_DISABLE_LDAP) +option(CURL_DISABLE_TELNET "disables Telnet" OFF) +mark_as_advanced(CURL_DISABLE_TELNET) +option(CURL_DISABLE_DICT "disables DICT" OFF) +mark_as_advanced(CURL_DISABLE_DICT) +option(CURL_DISABLE_FILE "disables FILE" OFF) +mark_as_advanced(CURL_DISABLE_FILE) +option(CURL_DISABLE_TFTP "disables TFTP" OFF) +mark_as_advanced(CURL_DISABLE_TFTP) +option(CURL_DISABLE_HTTP "disables HTTP" OFF) +mark_as_advanced(CURL_DISABLE_HTTP) + +option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF) +mark_as_advanced(CURL_DISABLE_LDAPS) + +option(CURL_DISABLE_RTSP "to disable RTSP" OFF) +mark_as_advanced(CURL_DISABLE_RTSP) +option(CURL_DISABLE_PROXY "to disable proxy" OFF) +mark_as_advanced(CURL_DISABLE_PROXY) +option(CURL_DISABLE_POP3 "to disable POP3" OFF) +mark_as_advanced(CURL_DISABLE_POP3) +option(CURL_DISABLE_IMAP "to disable IMAP" OFF) +mark_as_advanced(CURL_DISABLE_IMAP) +option(CURL_DISABLE_SMTP "to disable SMTP" OFF) +mark_as_advanced(CURL_DISABLE_SMTP) +option(CURL_DISABLE_GOPHER "to disable Gopher" OFF) +mark_as_advanced(CURL_DISABLE_GOPHER) + +if(HTTP_ONLY) + set(CURL_DISABLE_FTP ON) + set(CURL_DISABLE_LDAP ON) + set(CURL_DISABLE_LDAPS ON) + set(CURL_DISABLE_TELNET ON) + set(CURL_DISABLE_DICT ON) + set(CURL_DISABLE_FILE ON) + set(CURL_DISABLE_TFTP ON) + set(CURL_DISABLE_RTSP ON) + set(CURL_DISABLE_POP3 ON) + set(CURL_DISABLE_IMAP ON) + set(CURL_DISABLE_SMTP ON) + set(CURL_DISABLE_GOPHER ON) +endif() + +option(CURL_DISABLE_COOKIES "to disable cookies support" OFF) +mark_as_advanced(CURL_DISABLE_COOKIES) + +option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF) +mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH) +option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF) +mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS) +option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON) +mark_as_advanced(ENABLE_IPV6) +if(ENABLE_IPV6 AND NOT WIN32) + include(CheckStructHasMember) + check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h" + HAVE_SOCKADDR_IN6_SIN6_ADDR) + check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h" + HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) + if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR) + message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support") + # Force the feature off as this name is used as guard macro... + set(ENABLE_IPV6 OFF + CACHE BOOL "Define if you want to enable IPv6 support" FORCE) + endif() +endif() + +if(0) # This code not needed for building within CMake. +# Required for building manual, docs, tests +curl_nroff_check() +find_package(Perl) + +cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual" + ON "NROFF_USEFUL;PERL_FOUND" + OFF) + +if(NOT PERL_FOUND) + message(STATUS "Perl not found, testing disabled.") + set(BUILD_TESTING OFF) +endif() +if(ENABLE_MANUAL) + set(USE_MANUAL ON) +endif() +endif() + +# We need ansi c-flags, especially on HP +set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") +set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) + +if(CURL_STATIC_CRT) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") +endif() + +# Disable warnings on Borland to avoid changing 3rd party code. +if(BORLAND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-") +endif() + +# If we are on AIX, do the _ALL_SOURCE magic +if(${CMAKE_SYSTEM_NAME} MATCHES AIX) + set(_ALL_SOURCE 1) +endif() + +# Include all the necessary files for macros +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(CheckSymbolExists) +include(CheckTypeSize) +include(CheckCSourceCompiles) + +# On windows preload settings +if(WIN32) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=") + include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake) +endif() + +if(ENABLE_THREADED_RESOLVER) + find_package(Threads REQUIRED) + if(WIN32) + set(USE_THREADS_WIN32 ON) + else() + set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT}) + set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT}) + endif() + set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif() + +# Check for all needed libraries +if(0) # This code not needed for building within CMake. +check_library_exists_concat("dl" dlopen HAVE_LIBDL) +else() + # Use the cmake-defined dl libs as dl is should not be used + # on HPUX, but rather dld this avoids a warning + list(APPEND CURL_LIBS ${CMAKE_DL_LIBS}) +endif() +check_library_exists_concat("socket" connect HAVE_LIBSOCKET) +check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL) + +# Yellowtab Zeta needs different libraries than BeOS 5. +if(BEOS) + set(NOT_NEED_LIBNSL 1) + check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND) + check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI) +endif() + +check_library_exists_concat("network" recv HAVE_LIBNETWORK) + +if(NOT NOT_NEED_LIBNSL) + check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL) +endif() + +check_function_exists(gethostname HAVE_GETHOSTNAME) + +if(WIN32) + check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32) + check_library_exists_concat("winmm" getch HAVE_LIBWINMM) + list(APPEND CURL_LIBS "advapi32") +endif() + +# check SSL libraries +# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL + +if(APPLE) + option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF) +endif() +if(WIN32) + option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF) + cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON + CMAKE_USE_WINSSL OFF) +endif() +option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF) + +set(openssl_default ON) +if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS) + set(openssl_default OFF) +endif() + +count_true(enabled_ssl_options_count + CMAKE_USE_WINSSL + CMAKE_USE_DARWINSSL + CMAKE_USE_OPENSSL + CMAKE_USE_MBEDTLS +) +if(enabled_ssl_options_count GREATER "1") + set(CURL_WITH_MULTI_SSL ON) +endif() + +if(CMAKE_USE_WINSSL) + set(SSL_ENABLED ON) + set(USE_SCHANNEL ON) # Windows native SSL/TLS support + set(USE_WINDOWS_SSPI ON) # CMAKE_USE_WINSSL implies CURL_WINDOWS_SSPI + list(APPEND CURL_LIBS "crypt32") +endif() +if(CURL_WINDOWS_SSPI) + set(USE_WINDOWS_SSPI ON) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32") +endif() + +if(CMAKE_USE_DARWINSSL) + find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation") + if(NOT COREFOUNDATION_FRAMEWORK) + message(FATAL_ERROR "CoreFoundation framework not found") + endif() + + find_library(SECURITY_FRAMEWORK "Security") + if(NOT SECURITY_FRAMEWORK) + message(FATAL_ERROR "Security framework not found") + endif() + + set(SSL_ENABLED ON) + set(USE_DARWINSSL ON) + list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}") +endif() + +if(CMAKE_USE_OPENSSL) + find_package(OpenSSL REQUIRED) + set(SSL_ENABLED ON) + set(USE_OPENSSL ON) + set(HAVE_LIBCRYPTO ON) + set(HAVE_LIBSSL ON) + list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) + include_directories(${OPENSSL_INCLUDE_DIR}) + + set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H) + check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H) + check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H) + check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H) + check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H) + check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H) + check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H) + check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS) + check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN) + check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD) + + # Optionally build with a specific CA cert bundle. + if(CURL_CA_BUNDLE) + add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}") + endif() + # Optionally build with a specific CA cert dir. + if(CURL_CA_PATH) + add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}") + endif() +endif() + +if(CMAKE_USE_MBEDTLS) + find_package(MbedTLS REQUIRED) + set(SSL_ENABLED ON) + set(USE_MBEDTLS ON) + list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES}) + include_directories(${MBEDTLS_INCLUDE_DIRS}) +endif() + +option(USE_NGHTTP2 "Use Nghttp2 library" OFF) +if(USE_NGHTTP2) + find_package(NGHTTP2 REQUIRED) + include_directories(${NGHTTP2_INCLUDE_DIRS}) + list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES}) +endif() + +if(NOT CURL_DISABLE_LDAP) + if(WIN32) + option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON) + if(USE_WIN32_LDAP) + check_library_exists_concat("wldap32" cldap_open HAVE_WLDAP32) + if(NOT HAVE_WLDAP32) + set(USE_WIN32_LDAP OFF) + endif() + endif() + endif() + + option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF) + mark_as_advanced(CMAKE_USE_OPENLDAP) + set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library") + set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library") + + if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP) + message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at the same time") + endif() + + # Now that we know, we're not using windows LDAP... + if(USE_WIN32_LDAP) + check_include_file_concat("winldap.h" HAVE_WINLDAP_H) + check_include_file_concat("winber.h" HAVE_WINBER_H) + else() + # Check for LDAP + set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) + check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP) + check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER) + + set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES}) + set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory") + if(CMAKE_LDAP_INCLUDE_DIR) + list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR}) + endif() + check_include_file_concat("ldap.h" HAVE_LDAP_H) + check_include_file_concat("lber.h" HAVE_LBER_H) + + if(NOT HAVE_LDAP_H) + message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON") + set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + elseif(NOT HAVE_LIBLDAP) + message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON") + set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + else() + if(CMAKE_USE_OPENLDAP) + set(USE_OPENLDAP ON) + endif() + if(CMAKE_LDAP_INCLUDE_DIR) + include_directories(${CMAKE_LDAP_INCLUDE_DIR}) + endif() + set(NEED_LBER_H ON) + set(_HEADER_LIST) + if(HAVE_WINDOWS_H) + list(APPEND _HEADER_LIST "windows.h") + endif() + if(HAVE_SYS_TYPES_H) + list(APPEND _HEADER_LIST "sys/types.h") + endif() + list(APPEND _HEADER_LIST "ldap.h") + + set(_SRC_STRING "") + foreach(_HEADER ${_HEADER_LIST}) + set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n") + endforeach() + + set(_SRC_STRING + " + ${_INCLUDE_STRING} + int main(int argc, char ** argv) + { + BerValue *bvp = NULL; + BerElement *bep = ber_init(bvp); + ber_free(bep, 1); + return 0; + }" + ) + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1") + list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB}) + if(HAVE_LIBLBER) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB}) + endif() + check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H) + + if(NOT_NEED_LBER_H) + set(NEED_LBER_H OFF) + else() + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H") + endif() + endif() + endif() +endif() + +# No ldap, no ldaps. +if(CURL_DISABLE_LDAP) + if(NOT CURL_DISABLE_LDAPS) + message(STATUS "LDAP needs to be enabled to support LDAPS") + set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE) + endif() +endif() + +if(NOT CURL_DISABLE_LDAPS) + check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H) + check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H) +endif() + +# Check for idn +check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2) + +# Check for symbol dlopen (same as HAVE_LIBDL) +check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) + +if(0) # This code not needed for building within CMake. +option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON) +set(HAVE_LIBZ OFF) +set(HAVE_ZLIB_H OFF) - set(HAVE_ZLIB OFF) ++set(USE_ZLIB OFF) +if(CURL_ZLIB) + find_package(ZLIB QUIET) + if(ZLIB_FOUND) + set(HAVE_ZLIB_H ON) - set(HAVE_ZLIB ON) + set(HAVE_LIBZ ON) - list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) - include_directories(${ZLIB_INCLUDE_DIRS}) ++ set(USE_ZLIB ON) ++ ++ # Depend on ZLIB via imported targets if supported by the running ++ # version of CMake. This allows our dependents to get our dependencies ++ # transitively. ++ if(NOT CMAKE_VERSION VERSION_LESS 3.4) ++ list(APPEND CURL_LIBS ZLIB::ZLIB) ++ else() ++ list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) ++ include_directories(${ZLIB_INCLUDE_DIRS}) ++ endif() + list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) + endif() +endif() +endif() + +#----------------------------------------------------------------------------- +# CMake-specific curl code. + +if(CURL_SPECIAL_LIBZ) + set(CURL_LIBS ${CURL_LIBS} "${CURL_SPECIAL_LIBZ}") + include_directories(${CURL_SPECIAL_LIBZ_INCLUDES}) + set(HAVE_LIBZ 0) + set(HAVE_ZLIB_H 0) +endif() + +option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF) +set(HAVE_BROTLI OFF) +if(CURL_BROTLI) + find_package(BROTLI QUIET) + if(BROTLI_FOUND) + set(HAVE_BROTLI ON) + list(APPEND CURL_LIBS ${BROTLI_LIBRARIES}) + include_directories(${BROTLI_INCLUDE_DIRS}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${BROTLI_INCLUDE_DIRS}) + endif() +endif() + +#libSSH2 +option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON) +mark_as_advanced(CMAKE_USE_LIBSSH2) +set(USE_LIBSSH2 OFF) +set(HAVE_LIBSSH2 OFF) +set(HAVE_LIBSSH2_H OFF) + +if(CMAKE_USE_LIBSSH2) + find_package(LibSSH2) + if(LIBSSH2_FOUND) + list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY}) + set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY}) + list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}") + include_directories("${LIBSSH2_INCLUDE_DIR}") + set(HAVE_LIBSSH2 ON) + set(USE_LIBSSH2 ON) + + # find_package has already found the headers + set(HAVE_LIBSSH2_H ON) + set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h") + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H") + + # now check for specific libssh2 symbols as they were added in different versions + set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h") + check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION) + check_function_exists(libssh2_init HAVE_LIBSSH2_INIT) + check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT) + check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64) + check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE) + set(CMAKE_EXTRA_INCLUDE_FILES "") + endif() +endif() + +option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF) +mark_as_advanced(CMAKE_USE_GSSAPI) + +if(CMAKE_USE_GSSAPI) + find_package(GSS) + + set(HAVE_GSSAPI ${GSS_FOUND}) + if(GSS_FOUND) + + message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"") + + list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRECTORIES}) + check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H) + check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H) + check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H) + + if(GSS_FLAVOUR STREQUAL "Heimdal") + set(HAVE_GSSHEIMDAL ON) + else() # MIT + set(HAVE_GSSMIT ON) + set(_INCLUDE_LIST "") + if(HAVE_GSSAPI_GSSAPI_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi.h") + endif() + if(HAVE_GSSAPI_GSSAPI_GENERIC_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h") + endif() + if(HAVE_GSSAPI_GSSAPI_KRB5_H) + list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h") + endif() + + string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}") + string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}") + + foreach(_dir ${GSS_LINK_DIRECTORIES}) + set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"") + endforeach() + + set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}") + set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES}) + check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE) + if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE) + set(HAVE_OLD_GSSMIT ON) + endif() + + endif() + + include_directories(${GSS_INCLUDE_DIRECTORIES}) + link_directories(${GSS_LINK_DIRECTORIES}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") + list(APPEND CURL_LIBS ${GSS_LIBRARIES}) + + else() + message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.") + endif() +endif() + +option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON) +if(ENABLE_UNIX_SOCKETS) + include(CheckStructHasMember) + check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS) +else() + unset(USE_UNIX_SOCKETS CACHE) +endif() + + +if(0) # This code not needed for building within CMake. +# +# CA handling +# +set(CURL_CA_BUNDLE "auto" CACHE STRING + "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") +set(CURL_CA_FALLBACK OFF CACHE BOOL + "Set ON to use built-in CA store of TLS backend. Defaults to OFF") +set(CURL_CA_PATH "auto" CACHE STRING + "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + +if("${CURL_CA_BUNDLE}" STREQUAL "") + message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.") +elseif("${CURL_CA_BUNDLE}" STREQUAL "none") + unset(CURL_CA_BUNDLE CACHE) +elseif("${CURL_CA_BUNDLE}" STREQUAL "auto") + unset(CURL_CA_BUNDLE CACHE) + set(CURL_CA_BUNDLE_AUTODETECT TRUE) +else() + set(CURL_CA_BUNDLE_SET TRUE) +endif() + +if("${CURL_CA_PATH}" STREQUAL "") + message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.") +elseif("${CURL_CA_PATH}" STREQUAL "none") + unset(CURL_CA_PATH CACHE) +elseif("${CURL_CA_PATH}" STREQUAL "auto") + unset(CURL_CA_PATH CACHE) + set(CURL_CA_PATH_AUTODETECT TRUE) +else() + set(CURL_CA_PATH_SET TRUE) +endif() + +if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT) + # Skip autodetection of unset CA path because CA bundle is set explicitly +elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT) + # Skip autodetection of unset CA bundle because CA path is set explicitly +elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT) + # first try autodetecting a CA bundle, then a CA path + + if(CURL_CA_BUNDLE_AUTODETECT) + set(SEARCH_CA_BUNDLE_PATHS + /etc/ssl/certs/ca-certificates.crt + /etc/pki/tls/certs/ca-bundle.crt + /usr/share/ssl/certs/ca-bundle.crt + /usr/local/share/certs/ca-root-nss.crt + /etc/ssl/cert.pem) + + foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS}) + if(EXISTS "${SEARCH_CA_BUNDLE_PATH}") + message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set") + break() + endif() + endforeach() + endif() + + if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET)) + if(EXISTS "/etc/ssl/certs") + set(CURL_CA_PATH "/etc/ssl/certs") + set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set") + endif() + endif() +endif() + +if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS) + message(FATAL_ERROR + "CA path only supported by OpenSSL, GnuTLS or mbed TLS. " + "Set CURL_CA_PATH=none or enable one of those TLS backends.") +endif() +endif() + +# Check for header files +if(NOT UNIX) + check_include_file_concat("windows.h" HAVE_WINDOWS_H) + check_include_file_concat("winsock.h" HAVE_WINSOCK_H) + check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) + check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H) + if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL) + set(CURL_LIBS ${CURL_LIBS} "crypt32") + endif() +else() + set(HAVE_WINDOWS_H 0) + set(HAVE_WINSOCK_H 0) + set(HAVE_WS2TCPIP_H 0) + set(HAVE_WINSOCK2_H 0) +endif() + +check_include_file_concat("stdio.h" HAVE_STDIO_H) +check_include_file_concat("inttypes.h" HAVE_INTTYPES_H) +check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H) +check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H) +check_include_file_concat("sys/param.h" HAVE_SYS_PARAM_H) +check_include_file_concat("sys/poll.h" HAVE_SYS_POLL_H) +check_include_file_concat("sys/resource.h" HAVE_SYS_RESOURCE_H) +check_include_file_concat("sys/select.h" HAVE_SYS_SELECT_H) +check_include_file_concat("sys/socket.h" HAVE_SYS_SOCKET_H) +check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H) +check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H) +check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H) +check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H) +check_include_file_concat("sys/uio.h" HAVE_SYS_UIO_H) +check_include_file_concat("sys/un.h" HAVE_SYS_UN_H) +check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H) +check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H) +check_include_file_concat("alloca.h" HAVE_ALLOCA_H) +check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H) +check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H) +check_include_file_concat("assert.h" HAVE_ASSERT_H) +check_include_file_concat("crypto.h" HAVE_CRYPTO_H) +check_include_file_concat("des.h" HAVE_DES_H) +check_include_file_concat("err.h" HAVE_ERR_H) +check_include_file_concat("errno.h" HAVE_ERRNO_H) +check_include_file_concat("fcntl.h" HAVE_FCNTL_H) +check_include_file_concat("idn2.h" HAVE_IDN2_H) +check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H) +check_include_file_concat("io.h" HAVE_IO_H) +check_include_file_concat("krb.h" HAVE_KRB_H) +check_include_file_concat("libgen.h" HAVE_LIBGEN_H) +check_include_file_concat("locale.h" HAVE_LOCALE_H) +check_include_file_concat("net/if.h" HAVE_NET_IF_H) +check_include_file_concat("netdb.h" HAVE_NETDB_H) +check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H) +check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H) + +check_include_file_concat("pem.h" HAVE_PEM_H) +check_include_file_concat("poll.h" HAVE_POLL_H) +check_include_file_concat("pwd.h" HAVE_PWD_H) +check_include_file_concat("rsa.h" HAVE_RSA_H) +check_include_file_concat("setjmp.h" HAVE_SETJMP_H) +check_include_file_concat("sgtty.h" HAVE_SGTTY_H) +check_include_file_concat("signal.h" HAVE_SIGNAL_H) +check_include_file_concat("ssl.h" HAVE_SSL_H) +check_include_file_concat("stdbool.h" HAVE_STDBOOL_H) +check_include_file_concat("stdint.h" HAVE_STDINT_H) +check_include_file_concat("stdio.h" HAVE_STDIO_H) +check_include_file_concat("stdlib.h" HAVE_STDLIB_H) +check_include_file_concat("string.h" HAVE_STRING_H) +check_include_file_concat("strings.h" HAVE_STRINGS_H) +check_include_file_concat("stropts.h" HAVE_STROPTS_H) +check_include_file_concat("termio.h" HAVE_TERMIO_H) +check_include_file_concat("termios.h" HAVE_TERMIOS_H) +check_include_file_concat("time.h" HAVE_TIME_H) +check_include_file_concat("unistd.h" HAVE_UNISTD_H) +check_include_file_concat("utime.h" HAVE_UTIME_H) +check_include_file_concat("x509.h" HAVE_X509_H) + +check_include_file_concat("process.h" HAVE_PROCESS_H) +check_include_file_concat("stddef.h" HAVE_STDDEF_H) +check_include_file_concat("dlfcn.h" HAVE_DLFCN_H) +check_include_file_concat("malloc.h" HAVE_MALLOC_H) +check_include_file_concat("memory.h" HAVE_MEMORY_H) +check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H) +check_include_file_concat("stdint.h" HAVE_STDINT_H) +check_include_file_concat("sockio.h" HAVE_SOCKIO_H) +check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H) + +check_type_size(size_t SIZEOF_SIZE_T) +check_type_size(ssize_t SIZEOF_SSIZE_T) +check_type_size("long long" SIZEOF_LONG_LONG) +check_type_size("long" SIZEOF_LONG) +check_type_size("short" SIZEOF_SHORT) +check_type_size("int" SIZEOF_INT) +check_type_size("__int64" SIZEOF___INT64) +check_type_size("time_t" SIZEOF_TIME_T) + +if(HAVE_SIZEOF_LONG_LONG) + set(HAVE_LONGLONG 1) + set(HAVE_LL 1) +endif() + +find_file(RANDOM_FILE urandom /dev) +mark_as_advanced(RANDOM_FILE) + +# Check for some functions that are used +if(HAVE_LIBWS2_32) + set(CMAKE_REQUIRED_LIBRARIES ws2_32) +elseif(HAVE_LIBSOCKET) + set(CMAKE_REQUIRED_LIBRARIES socket) +elseif(HAVE_LIBNETWORK) + set(CMAKE_REQUIRED_LIBRARIES network) +endif() + +check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME) +check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET) +# poll on macOS is unreliable, it first did not exist, then was broken until +# fixed in 10.9 only to break again in 10.12. +if(NOT APPLE) + check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL) +endif() +check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT) +check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP) +check_symbol_exists(strstr "${CURL_INCLUDES}" HAVE_STRSTR) +check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R) +check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME) +check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME) +check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP) +check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP) +check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI) +check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI) +check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM) +if(NOT HAVE_STRNCMPI) + set(HAVE_STRCMPI) +endif() +check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR) +check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R) +check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY) +check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR) +check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA) +check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R) +check_symbol_exists(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR) +check_symbol_exists(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR) +check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR) +check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET) +check_symbol_exists(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF) +check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP) +check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R) +check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT) +check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID) +check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R) +check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID) +check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME) +check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R) +check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R) + +check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME) +check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) + +check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC) +check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO) +if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO) + set(HAVE_SIGNAL 1) +endif() +check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME) +check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL) +check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64) +check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R) +check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT) +check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR) +check_symbol_exists(fork "${CURL_INCLUDES}" HAVE_FORK) +check_symbol_exists(getaddrinfo "${CURL_INCLUDES}" HAVE_GETADDRINFO) +check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO) +check_symbol_exists(freeifaddrs "${CURL_INCLUDES}" HAVE_FREEIFADDRS) +check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE) +check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE) +check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME) +check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT) +check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE) +check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE) +check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT) +check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL) +check_symbol_exists(ioctl "${CURL_INCLUDES}" HAVE_IOCTL) +check_symbol_exists(setsockopt "${CURL_INCLUDES}" HAVE_SETSOCKOPT) +check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME) + +# symbol exists in win32, but function does not. +if(WIN32) + if(ENABLE_INET_PTON) + check_function_exists(inet_pton HAVE_INET_PTON) + # _WIN32_WINNT_VISTA (0x0600) + add_definitions(-D_WIN32_WINNT=0x0600) + else() + # _WIN32_WINNT_WINXP (0x0501) + add_definitions(-D_WIN32_WINNT=0x0501) + endif() +else() + check_function_exists(inet_pton HAVE_INET_PTON) +endif() + +check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR) +if(HAVE_FSETXATTR) + foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6) + curl_internal_test(${CURL_TEST}) + endforeach() +endif() + +# sigaction and sigsetjmp are special. Use special mechanism for +# detecting those, but only if previous attempt failed. +if(HAVE_SIGNAL_H) + check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) +endif() + +if(NOT HAVE_SIGSETJMP) + if(HAVE_SETJMP_H) + check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP) + if(HAVE_MACRO_SIGSETJMP) + set(HAVE_SIGSETJMP 1) + endif() + endif() +endif() + +# If there is no stricmp(), do not allow LDAP to parse URLs +if(NOT HAVE_STRICMP) + set(HAVE_LDAP_URL_PARSE 1) +endif() + +# Do curl specific tests +foreach(CURL_TEST + HAVE_FCNTL_O_NONBLOCK + HAVE_IOCTLSOCKET + HAVE_IOCTLSOCKET_CAMEL + HAVE_IOCTLSOCKET_CAMEL_FIONBIO + HAVE_IOCTLSOCKET_FIONBIO + HAVE_IOCTL_FIONBIO + HAVE_IOCTL_SIOCGIFADDR + HAVE_SETSOCKOPT_SO_NONBLOCK + HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + TIME_WITH_SYS_TIME + HAVE_O_NONBLOCK + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYADDR_R_5_REENTRANT + HAVE_GETHOSTBYADDR_R_7_REENTRANT + HAVE_GETHOSTBYADDR_R_8_REENTRANT + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6 + HAVE_GETHOSTBYNAME_R_3_REENTRANT + HAVE_GETHOSTBYNAME_R_5_REENTRANT + HAVE_GETHOSTBYNAME_R_6_REENTRANT - HAVE_SOCKLEN_T + HAVE_IN_ADDR_T + HAVE_BOOL_T + STDC_HEADERS + RETSIGTYPE_TEST + HAVE_INET_NTOA_R_DECL + HAVE_INET_NTOA_R_DECL_REENTRANT + HAVE_GETADDRINFO + HAVE_FILE_OFFSET_BITS + ) + curl_internal_test(${CURL_TEST}) +endforeach() + +if(HAVE_FILE_OFFSET_BITS) + set(_FILE_OFFSET_BITS 64) + set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64") +endif() +check_type_size("off_t" SIZEOF_OFF_T) + +# include this header to get the type +set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include") +set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h") +check_type_size("curl_off_t" SIZEOF_CURL_OFF_T) +set(CMAKE_EXTRA_INCLUDE_FILES "") + +set(CMAKE_REQUIRED_FLAGS) + +foreach(CURL_TEST + HAVE_GLIBC_STRERROR_R + HAVE_POSIX_STRERROR_R + ) + curl_internal_test(${CURL_TEST}) +endforeach() + +# Check for reentrant +foreach(CURL_TEST + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6 + HAVE_INET_NTOA_R_DECL_REENTRANT) + if(NOT ${CURL_TEST}) + if(${CURL_TEST}_REENTRANT) + set(NEED_REENTRANT 1) + endif() + endif() +endforeach() + +if(NEED_REENTRANT) + foreach(CURL_TEST + HAVE_GETHOSTBYADDR_R_5 + HAVE_GETHOSTBYADDR_R_7 + HAVE_GETHOSTBYADDR_R_8 + HAVE_GETHOSTBYNAME_R_3 + HAVE_GETHOSTBYNAME_R_5 + HAVE_GETHOSTBYNAME_R_6) + set(${CURL_TEST} 0) + if(${CURL_TEST}_REENTRANT) + set(${CURL_TEST} 1) + endif() + endforeach() +endif() + +if(HAVE_INET_NTOA_R_DECL_REENTRANT) + set(HAVE_INET_NTOA_R_DECL 1) + set(NEED_REENTRANT 1) +endif() + ++# Check clock_gettime(CLOCK_MONOTONIC, x) support ++curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC) ++ ++# Check compiler support of __builtin_available() ++curl_internal_test(HAVE_BUILTIN_AVAILABLE) ++ +# Some other minor tests + +if(NOT HAVE_IN_ADDR_T) + set(in_addr_t "unsigned long") +endif() + +# Fix libz / zlib.h + +if(NOT CURL_SPECIAL_LIBZ) + if(NOT HAVE_LIBZ) + set(HAVE_ZLIB_H 0) + endif() + + if(NOT HAVE_ZLIB_H) + set(HAVE_LIBZ 0) + endif() +endif() + +# Check for nonblocking +set(HAVE_DISABLED_NONBLOCKING 1) +if(HAVE_FIONBIO OR + HAVE_IOCTLSOCKET OR + HAVE_IOCTLSOCKET_CASE OR + HAVE_O_NONBLOCK) + set(HAVE_DISABLED_NONBLOCKING) +endif() + +if(RETSIGTYPE_TEST) + set(RETSIGTYPE void) +else() + set(RETSIGTYPE int) +endif() + +if(CMAKE_COMPILER_IS_GNUCC AND APPLE) + include(CheckCCompilerFlag) + check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double) + if(HAVE_C_FLAG_Wno_long_double) + # The Mac version of GCC warns about use of long double. Disable it. + get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS) + if(MPRINTF_COMPILE_FLAGS) + set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double") + else() + set(MPRINTF_COMPILE_FLAGS "-Wno-long-double") + endif() + set_source_files_properties(mprintf.c PROPERTIES + COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS}) + endif() +endif() + - if(HAVE_SOCKLEN_T) - set(CURL_HAVE_SOCKLEN_T 1) - set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t") - if(WIN32) - set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h") - elseif(HAVE_SYS_SOCKET_H) - set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") - endif() - check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T) - set(CMAKE_EXTRA_INCLUDE_FILES) - if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T) - message(FATAL_ERROR - "Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log") - endif() - else() - set(CURL_HAVE_SOCKLEN_T 0) - endif() - +# TODO test which of these headers are required +if(WIN32) + set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H}) +else() + set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H}) + set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H}) + set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H}) +endif() +set(CURL_PULL_STDINT_H ${HAVE_STDINT_H}) +set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H}) + +include(CMake/OtherTests.cmake) + +add_definitions(-DHAVE_CONFIG_H) + +# For Windows, all compilers used by CMake should support large files +if(WIN32) + set(USE_WIN32_LARGE_FILES ON) + + # Use the manifest embedded in the Windows Resource + set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST") +endif() + +if(MSVC) + # Disable default manifest added by CMake + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") + + add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) + if(CMAKE_C_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") + endif() +endif() + +if(CURL_WERROR) + if(MSVC_VERSION) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + else() + # this assumes clang or gcc style options + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif() +endif() + +# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it). +function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE) + file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT) + string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\\\\n" "!?!?!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "!?!?!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${} + string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts. + file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT}) + +endfunction() + - if(WIN32 AND NOT CYGWIN) - set(CURL_INSTALL_CMAKE_DIR CMake) - else() - set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl) - endif() ++include(GNUInstallDirs) ++ ++set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) ++set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") ++set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") ++set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") ++set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") + +if(USE_MANUAL) + add_subdirectory(docs) +endif() + +add_subdirectory(lib) + +if(BUILD_CURL_EXE) + add_subdirectory(src) +endif() + +#----------------------------------------------------------------------------- +# CMake-specific curl code. +add_executable(LIBCURL curltest.c) +target_link_libraries(LIBCURL cmcurl) + +if(BUILD_TESTING AND CMAKE_CURL_TEST_URL) + add_test(curl LIBCURL ${CMAKE_CURL_TEST_URL}) +endif() + +install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl) +#----------------------------------------------------------------------------- + +if(0) # This code not needed for building within CMake. +include(CTest) +if(BUILD_TESTING) + add_subdirectory(tests) +endif() + +# Helper to populate a list (_items) with a label when conditions (the remaining +# args) are satisfied +function(_add_if label) + # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection + if(${ARGN}) + set(_items ${_items} "${label}" PARENT_SCOPE) + endif() +endfunction() + +# Clear list and try to detect available features +set(_items) +_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI) +_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL) +_add_if("DarwinSSL" SSL_ENABLED AND USE_DARWINSSL) +_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS) +_add_if("IPv6" ENABLE_IPV6) +_add_if("unix-sockets" USE_UNIX_SOCKETS) +_add_if("libz" HAVE_LIBZ) +_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) +_add_if("IDN" HAVE_LIBIDN2) +_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND + ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) +# TODO SSP1 (WinSSL) check is missing +_add_if("SSPI" USE_WINDOWS_SSPI) +_add_if("GSS-API" HAVE_GSSAPI) +# TODO SSP1 missing for SPNEGO +_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +_add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +# NTLM support requires crypto function adaptions from various SSL libs +# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS +if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS)) + _add_if("NTLM" 1) + # TODO missing option (autoconf: --enable-ntlm-wb) + _add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED) +endif() +# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP +_add_if("TLS-SRP" USE_TLS_SRP) +# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header +_add_if("HTTP2" USE_NGHTTP2) +string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") +message(STATUS "Enabled features: ${SUPPORT_FEATURES}") + +# Clear list and try to detect available protocols +set(_items) +_add_if("HTTP" NOT CURL_DISABLE_HTTP) +_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED) +_add_if("FTP" NOT CURL_DISABLE_FTP) +_add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED) +_add_if("FILE" NOT CURL_DISABLE_FILE) +_add_if("TELNET" NOT CURL_DISABLE_TELNET) +_add_if("LDAP" NOT CURL_DISABLE_LDAP) +# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS +# TODO check HAVE_LDAP_SSL (in autoconf this is enabled with --enable-ldaps) +_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND + ((USE_OPENLDAP AND SSL_ENABLED) OR + (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) +_add_if("DICT" NOT CURL_DISABLE_DICT) +_add_if("TFTP" NOT CURL_DISABLE_TFTP) +_add_if("GOPHER" NOT CURL_DISABLE_GOPHER) +_add_if("POP3" NOT CURL_DISABLE_POP3) +_add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED) +_add_if("IMAP" NOT CURL_DISABLE_IMAP) +_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED) +_add_if("SMTP" NOT CURL_DISABLE_SMTP) +_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED) +_add_if("SCP" USE_LIBSSH2) +_add_if("SFTP" USE_LIBSSH2) +_add_if("RTSP" NOT CURL_DISABLE_RTSP) +_add_if("RTMP" USE_LIBRTMP) +list(SORT _items) +string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") +message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}") + +# curl-config needs the following options to be set. +set(CC "${CMAKE_C_COMPILER}") +# TODO probably put a -D... options here? +set(CONFIGURE_OPTIONS "") +# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB? +set(CPPFLAG_CURL_STATICLIB "") +set(CURLVERSION "${CURL_VERSION}") +if(BUILD_SHARED_LIBS) + set(ENABLE_SHARED "yes") + set(ENABLE_STATIC "no") +else() + set(ENABLE_SHARED "no") + set(ENABLE_STATIC "yes") +endif() +set(exec_prefix "\${prefix}") +set(includedir "\${prefix}/include") +set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") +set(LIBCURL_LIBS "") +set(libdir "${CMAKE_INSTALL_PREFIX}/lib") +foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS}) + if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-") + set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + else() + set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}") + endif() +endforeach() +# "a" (Linux) or "lib" (Windows) +string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") +set(prefix "${CMAKE_INSTALL_PREFIX}") +# Set this to "yes" to append all libraries on which -lcurl is dependent +set(REQUIRE_LIB_DEPS "no") +# SUPPORT_FEATURES +# SUPPORT_PROTOCOLS +set(VERSIONNUM "${CURL_VERSION_NUM}") + +# Finally generate a "curl-config" matching this config +# Use: +# * ENABLE_SHARED +# * ENABLE_STATIC +configure_file("${CURL_SOURCE_DIR}/curl-config.in" + "${CURL_BINARY_DIR}/curl-config" @ONLY) +install(FILES "${CURL_BINARY_DIR}/curl-config" - DESTINATION bin ++ DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + +# Finally generate a pkg-config file matching this config +configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" + "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) +install(FILES "${CURL_BINARY_DIR}/libcurl.pc" - DESTINATION lib/pkgconfig) - - # This needs to be run very last so other parts of the scripts can take advantage of this. - if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE) - set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before") - endif() ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +# install headers +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" - DESTINATION include ++ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h") + - +include(CMakePackageConfigHelpers) +write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/curl-config-version.cmake" ++ "${version_config}" + VERSION ${CURL_VERSION} + COMPATIBILITY SameMajorVersion +) + - configure_file(CMake/curl-config.cmake.in - "${PROJECT_BINARY_DIR}/curl-config.cmake" - @ONLY ++# Use: ++# * TARGETS_EXPORT_NAME ++# * PROJECT_NAME ++configure_package_config_file(CMake/curl-config.cmake.in ++ "${project_config}" ++ INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR} ++) ++ ++install( ++ EXPORT "${TARGETS_EXPORT_NAME}" ++ NAMESPACE "${PROJECT_NAME}::" ++ DESTINATION ${CURL_INSTALL_CMAKE_DIR} +) + +install( - FILES ${PROJECT_BINARY_DIR}/curl-config.cmake - ${PROJECT_BINARY_DIR}/curl-config-version.cmake ++ FILES ${version_config} ${project_config} + DESTINATION ${CURL_INSTALL_CMAKE_DIR} +) + +# Workaround for MSVS10 to avoid the Dialog Hell +# FIXME: This could be removed with future version of CMake. +if(MSVC_VERSION EQUAL 1600) + set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") + if(EXISTS "${CURL_SLN_FILENAME}") + file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n") + endif() +endif() + +if(NOT TARGET uninstall) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake + IMMEDIATE @ONLY) + + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake) +endif() +endif() diff --cc Utilities/cmcurl/include/curl/curl.h index d9955bd,0000000..63bb291 mode 100644,000000..100644 --- a/Utilities/cmcurl/include/curl/curl.h +++ b/Utilities/cmcurl/include/curl/curl.h @@@ -1,2802 -1,0 +1,2819 @@@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "system.h" /* determine things run-time */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + defined(__CYGWIN__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#if defined __BEOS__ || defined __HAIKU__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_WOLFSSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, - CURLSSLBACKEND_MBEDTLS = 11 ++ CURLSSLBACKEND_MBEDTLS = 11, ++ CURLSSLBACKEND_MESALINK = 12 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL +#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL +#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + +/* This callback will be called when a new resolver request is made */ +typedef int (*curl_resolver_start_callback)(void *resolver_state, + void *reserved, void *userdata); + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ ++ CURLE_OBSOLETE51, /* 51 - NOT USED */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ ++ CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint ++ wasn't verified fine */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from + inside a callback */ + CURL_LAST /* never use! */ +} CURLcode; + ++/* added in 7.62.0 */ ++#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION ++ +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_BEARER - HTTP Bearer token authentication + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ +#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_BEARER (((unsigned long)1)<<6) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS, + CURLKHTYPE_ECDSA, + CURLKHTYPE_ED25519 +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +/* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +#define CURL_HET_DEFAULT 200L + ++/* The default connection upkeep interval in milliseconds. */ ++#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L ++ +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of milliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv6 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), + + /* The request target, instead of extracted from the URL */ + CINIT(REQUEST_TARGET, STRINGPOINT, 266), + + /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ + CINIT(SOCKS5_AUTH, LONG, 267), + + /* Enable/disable SSH compression */ + CINIT(SSH_COMPRESSION, LONG, 268), + + /* Post MIME data. */ + CINIT(MIMEPOST, OBJECTPOINT, 269), + + /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of + seconds since 1 Jan 1970. */ + CINIT(TIMEVALUE_LARGE, OFF_T, 270), + + /* Head start in milliseconds to give happy eyeballs. */ + CINIT(HAPPY_EYEBALLS_TIMEOUT_MS, LONG, 271), + + /* Function that will be called before a resolver request is made */ + CINIT(RESOLVER_START_FUNCTION, FUNCTIONPOINT, 272), + + /* User data to pass to the resolver start callback. */ + CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273), + + /* send HAProxy PROXY protocol header? */ + CINIT(HAPROXYPROTOCOL, LONG, 274), + + /* shuffle addresses before use when DNS returns multiple */ + CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275), + + /* Specify which TLS 1.3 ciphers suites to use */ + CINIT(TLS13_CIPHERS, STRINGPOINT, 276), + CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277), + + /* Disallow specifying username/login in URL. */ + CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278), + ++ /* DNS-over-HTTPS URL */ ++ CINIT(DOH_URL, STRINGPOINT, 279), ++ ++ /* Preferred buffer size to use for uploads */ ++ CINIT(UPLOAD_BUFFERSIZE, LONG, 280), ++ ++ /* Time in ms between connection upkeep calls for long-lived connections. */ ++ CINIT(UPKEEP_INTERVAL_MS, LONG, 281), ++ + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + +/* Special size_t value signaling a zero-terminated string. */ +#define CURL_ZERO_TERMINATED ((size_t) -1) + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + release */ +CURL_EXTERN int curl_strequal(const char *s1, const char *s2); +CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); + +/* Mime/form handling support. */ +typedef struct curl_mime_s curl_mime; /* Mime context. */ +typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */ + +/* + * NAME curl_mime_init() + * + * DESCRIPTION + * + * Create a mime context and return its handle. The easy parameter is the + * target handle. + */ +CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); + +/* + * NAME curl_mime_free() + * + * DESCRIPTION + * + * release a mime handle and its substructures. + */ +CURL_EXTERN void curl_mime_free(curl_mime *mime); + +/* + * NAME curl_mime_addpart() + * + * DESCRIPTION + * + * Append a new empty part to the given mime context and return a handle to + * the created part. + */ +CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); + +/* + * NAME curl_mime_name() + * + * DESCRIPTION + * + * Set mime/form part name. + */ +CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); + +/* + * NAME curl_mime_filename() + * + * DESCRIPTION + * + * Set mime part remote file name. + */ +CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_type() + * + * DESCRIPTION + * + * Set mime part type. + */ +CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); + +/* + * NAME curl_mime_encoder() + * + * DESCRIPTION + * + * Set mime data transfer encoder. + */ +CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, + const char *encoding); + +/* + * NAME curl_mime_data() + * + * DESCRIPTION + * + * Set mime part data source from memory data, + */ +CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, + const char *data, size_t datasize); + +/* + * NAME curl_mime_filedata() + * + * DESCRIPTION + * + * Set mime part data source from named file. + */ +CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_data_cb() + * + * DESCRIPTION + * + * Set mime part data source from callback function. + */ +CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, + curl_off_t datasize, + curl_read_callback readfunc, + curl_seek_callback seekfunc, + curl_free_callback freefunc, + void *arg); + +/* + * NAME curl_mime_subparts() + * + * DESCRIPTION + * + * Set mime part data source from subparts. + */ +CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, + curl_mime *subparts); +/* + * NAME curl_mime_headers() + * + * DESCRIPTION + * + * Set mime part headers. + */ +CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, + struct curl_slist *headers, + int take_ownership); + +/* Old form API. */ +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_global_sslset() + * + * DESCRIPTION + * + * When built with multiple SSL backends, curl_global_sslset() allows to + * choose one. This function can only be called once, and it must be called + * *before* curl_global_init(). + * + * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The + * backend can also be specified via the name parameter (passing -1 as id). + * If both id and name are specified, the name will be ignored. If neither id + * nor name are specified, the function will fail with + * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the + * NULL-terminated list of available backends. + * + * Upon success, the function returns CURLSSLSET_OK. + * + * If the specified SSL backend is not available, the function returns + * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated + * list of available SSL backends. + * + * The SSL backend can be set only once. If it has already been set, a + * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. + */ + +typedef struct { + curl_sslbackend id; + const char *name; +} curl_ssl_backend; + +typedef enum { + CURLSSLSET_OK = 0, + CURLSSLSET_UNKNOWN_BACKEND, + CURLSSLSET_TOO_LATE, + CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ +} CURLsslset; + +CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail); + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_PTR 0x400000 /* same as SLIST */ +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_OFF_T 0x600000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + /* Preferably these would be defined conditionally based on the + sizeof curl_off_t being 64-bits */ + CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, + CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, + CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, + CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, + CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, + CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, + CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, + + CURLINFO_LASTONE = 56 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */ +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_PSL, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_FIFTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FIFTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + + /* These fields were added in CURLVERSION_FIFTH */ + + unsigned int brotli_ver_num; /* Numeric Brotli version + (MAJOR << 24) | (MINOR << 12) | PATCH */ + const char *brotli_version; /* human readable string. */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is supported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ +#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ +#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" ++#include "urlapi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +#if 0 /* Triggers clang -Wdisabled-macro-expansion, skip for CMake. */ +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --cc Utilities/cmcurl/include/curl/curlver.h index e266f18,0000000..3d7b1fb mode 100644,000000..100644 --- a/Utilities/cmcurl/include/curl/curlver.h +++ b/Utilities/cmcurl/include/curl/curlver.h @@@ -1,77 -1,0 +1,77 @@@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2018 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ - #define LIBCURL_VERSION "7.61.1" ++#define LIBCURL_VERSION "7.62.0" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 - #define LIBCURL_VERSION_MINOR 61 - #define LIBCURL_VERSION_PATCH 1 ++#define LIBCURL_VERSION_MINOR 62 ++#define LIBCURL_VERSION_PATCH 0 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ - #define LIBCURL_VERSION_NUM 0x073D01 ++#define LIBCURL_VERSION_NUM 0x073E00 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date follows this template: + * + * "2007-11-23" + */ +#define LIBCURL_TIMESTAMP "[unreleased]" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --cc Utilities/cmcurl/include/curl/urlapi.h index 0000000,90dd56c..90dd56c mode 000000,100644..100644 --- a/Utilities/cmcurl/include/curl/urlapi.h +++ b/Utilities/cmcurl/include/curl/urlapi.h diff --cc Utilities/cmcurl/lib/CMakeLists.txt index 3d52105,0000000..2a6279c mode 100644,000000..100644 --- a/Utilities/cmcurl/lib/CMakeLists.txt +++ b/Utilities/cmcurl/lib/CMakeLists.txt @@@ -1,152 -1,0 +1,147 @@@ +set(LIB_NAME cmcurl) + +if(BUILD_SHARED_LIBS) + set(CURL_STATICLIB NO) +else() + set(CURL_STATICLIB YES) +endif() + +# Use: +# * CURL_STATICLIB +configure_file(curl_config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h) + +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) + +list(APPEND HHEADERS + ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h + ) + +if(MSVC AND NOT CURL_STATICLIB) + list(APPEND CSOURCES libcurl.rc) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127") +endif() + +# SET(CSOURCES +# # memdebug.c -not used +# # nwlib.c - Not used +# # strtok.c - specify later +# # strtoofft.c - specify later +# ) + +# # if we have Kerberos 4, right now this is never on +# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF) +# IF(CURL_KRB4) +# SET(CSOURCES ${CSOURCES} +# krb4.c +# security.c +# ) +# ENDIF(CURL_KRB4) + +# #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF) +# MARK_AS_ADVANCED(CURL_MALLOC_DEBUG) +# IF(CURL_MALLOC_DEBUG) +# SET(CSOURCES ${CSOURCES} +# memdebug.c +# ) +# ENDIF(CURL_MALLOC_DEBUG) + +# # only build compat strtoofft if we need to +# IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) +# SET(CSOURCES ${CSOURCES} +# strtoofft.c +# ) +# ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) + + +# The rest of the build + +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +if(USE_ARES) + include_directories(${CARES_INCLUDE_DIR}) +endif() + +# For windows we want to install OPENSSL_LIBRARIES dlls +# and also copy them into the build tree so that testing +# can find them. +if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND AND WIN32) + find_file(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..) + find_file(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..) + mark_as_advanced(CMAKE_EAY_DLL CMAKE_SSL_DLL) + if(CMAKE_SSL_DLL AND CMAKE_EAY_DLL) + set(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll + ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll) + add_custom_command(OUTPUT + ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll + DEPENDS ${CMAKE_EAY_DLL} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL} + ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll) + add_custom_command(OUTPUT + ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll + DEPENDS ${CMAKE_SSL_DLL} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL} + ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll) + install(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin) + endif() +endif() + +add_library( + ${LIB_NAME} + ${HHEADERS} ${CSOURCES} + ${CMAKE_CURL_SSL_DLLS} + ) + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB) +endif() + +target_link_libraries(${LIB_NAME} ${CURL_LIBS}) + +if(0) # This code not needed for building within CMake. +if(WIN32) + add_definitions(-D_USRDLL) +endif() +endif() + +set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL) + +if(0) # This code not needed for building within CMake. +if(HIDES_CURL_PRIVATE_SYMBOLS) + set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") + set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE}) +endif() + +# Remove the "lib" prefix since the library is already named "libcurl". +set_target_properties(${LIB_NAME} PROPERTIES PREFIX "") +set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "") + +if(WIN32) + if(BUILD_SHARED_LIBS) + # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib" + set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib") + endif() +endif() + +target_include_directories(${LIB_NAME} INTERFACE - $) ++ $ ++ $) + +install(TARGETS ${LIB_NAME} - EXPORT libcurl-target - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin ++ EXPORT ${TARGETS_EXPORT_NAME} ++ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ++ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +export(TARGETS ${LIB_NAME} + APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake + NAMESPACE CURL:: +) + - install(EXPORT libcurl-target - FILE libcurl-target.cmake - NAMESPACE CURL:: - DESTINATION ${CURL_INSTALL_CMAKE_DIR} - ) - +endif() diff --cc Utilities/cmcurl/lib/curl_config.h.cmake index f67188e,0000000..d5e3a90 mode 100644,000000..100644 --- a/Utilities/cmcurl/lib/curl_config.h.cmake +++ b/Utilities/cmcurl/lib/curl_config.h.cmake @@@ -1,1015 -1,0 +1,1018 @@@ +/* lib/curl_config.h.in. Generated somehow by cmake. */ + +/* when building libcurl itself */ +#cmakedefine BUILDING_LIBCURL 1 + +/* to disable cookies support */ +#cmakedefine CURL_DISABLE_COOKIES 1 + +/* to disable cryptographic authentication */ +#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1 + +/* to disable DICT */ +#cmakedefine CURL_DISABLE_DICT 1 + +/* to disable FILE */ +#cmakedefine CURL_DISABLE_FILE 1 + +/* to disable FTP */ +#cmakedefine CURL_DISABLE_FTP 1 + +/* to disable GOPHER */ +#cmakedefine CURL_DISABLE_GOPHER 1 + +/* to disable IMAP */ +#cmakedefine CURL_DISABLE_IMAP 1 + +/* to disable HTTP */ +#cmakedefine CURL_DISABLE_HTTP 1 + +/* to disable LDAP */ +#cmakedefine CURL_DISABLE_LDAP 1 + +/* to disable LDAPS */ +#cmakedefine CURL_DISABLE_LDAPS 1 + +/* to disable POP3 */ +#cmakedefine CURL_DISABLE_POP3 1 + +/* to disable proxies */ +#cmakedefine CURL_DISABLE_PROXY 1 + +/* to disable RTSP */ +#cmakedefine CURL_DISABLE_RTSP 1 + +/* to disable SMB */ +#cmakedefine CURL_DISABLE_SMB 1 + +/* to disable SMTP */ +#cmakedefine CURL_DISABLE_SMTP 1 + +/* to disable TELNET */ +#cmakedefine CURL_DISABLE_TELNET 1 + +/* to disable TFTP */ +#cmakedefine CURL_DISABLE_TFTP 1 + +/* to disable verbose strings */ +#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1 + +/* to make a symbol visible */ +#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL} +/* Ensure using CURL_EXTERN_SYMBOL is possible */ +#ifndef CURL_EXTERN_SYMBOL +#define CURL_EXTERN_SYMBOL +#endif + +/* Use Windows LDAP implementation */ +#cmakedefine USE_WIN32_LDAP 1 + +/* when not building a shared library */ +#cmakedefine CURL_STATICLIB 1 + +/* your Entropy Gathering Daemon socket pathname */ +#cmakedefine EGD_SOCKET ${EGD_SOCKET} + +/* Define if you want to enable IPv6 support */ +#cmakedefine ENABLE_IPV6 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1} + +/* Define to the type of arg 1 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1} + +/* Define to the type of arg 2 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2} + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46} + +/* Define to the type of arg 7 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7} + +/* Specifies the number of arguments to getservbyport_r */ +#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS} + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE} + +/* Define to 1 if you have the alarm function. */ +#cmakedefine HAVE_ALARM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_TFTP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +#cmakedefine HAVE_BASENAME 1 + +/* Define to 1 if bool is an available type. */ +#cmakedefine HAVE_BOOL_T 1 + ++/* Define to 1 if you have the __builtin_available function. */ ++#cmakedefine HAVE_BUILTIN_AVAILABLE 1 ++ +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 + +/* Define to 1 if you have the `closesocket' function. */ +#cmakedefine HAVE_CLOSESOCKET 1 + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERR_H 1 + +/* Define to 1 if you have the fcntl function. */ +#cmakedefine HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#cmakedefine HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the fdopen function. */ +#cmakedefine HAVE_FDOPEN 1 + +/* Define to 1 if you have the `fork' function. */ +#cmakedefine HAVE_FORK 1 + +/* Define to 1 if you have the freeaddrinfo function. */ +#cmakedefine HAVE_FREEADDRINFO 1 + +/* Define to 1 if you have the freeifaddrs function. */ +#cmakedefine HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the ftruncate function. */ +#cmakedefine HAVE_FTRUNCATE 1 + +/* Define to 1 if you have a working getaddrinfo function. */ +#cmakedefine HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `geteuid' function. */ +#cmakedefine HAVE_GETEUID 1 + +/* Define to 1 if you have the gethostbyaddr function. */ +#cmakedefine HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the gethostbyaddr_r function. */ +#cmakedefine HAVE_GETHOSTBYADDR_R 1 + +/* gethostbyaddr_r() takes 5 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_5 1 + +/* gethostbyaddr_r() takes 7 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_7 1 + +/* gethostbyaddr_r() takes 8 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_8 1 + +/* Define to 1 if you have the gethostbyname function. */ +#cmakedefine HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the gethostbyname_r function. */ +#cmakedefine HAVE_GETHOSTBYNAME_R 1 + +/* gethostbyname_r() takes 3 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_3 1 + +/* gethostbyname_r() takes 5 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_5 1 + +/* gethostbyname_r() takes 6 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_6 1 + +/* Define to 1 if you have the gethostname function. */ +#cmakedefine HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have a working getifaddrs function. */ +#cmakedefine HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the getnameinfo function. */ +#cmakedefine HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getpass_r' function. */ +#cmakedefine HAVE_GETPASS_R 1 + +/* Define to 1 if you have the `getppid' function. */ +#cmakedefine HAVE_GETPPID 1 + +/* Define to 1 if you have the `getprotobyname' function. */ +#cmakedefine HAVE_GETPROTOBYNAME 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#cmakedefine HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getpwuid_r' function. */ +#cmakedefine HAVE_GETPWUID_R 1 + +/* Define to 1 if you have the `getrlimit' function. */ +#cmakedefine HAVE_GETRLIMIT 1 + +/* Define to 1 if you have the getservbyport_r function. */ +#cmakedefine HAVE_GETSERVBYPORT_R 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have a working glibc-style strerror_r function. */ +#cmakedefine HAVE_GLIBC_STRERROR_R 1 + +/* Define to 1 if you have a working gmtime_r function. */ +#cmakedefine HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +#cmakedefine HAVE_GSSAPI 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1 + +/* if you have the GNU gssapi libraries */ +#cmakedefine HAVE_GSSGNU 1 + +/* if you have the Heimdal gssapi libraries */ +#cmakedefine HAVE_GSSHEIMDAL 1 + +/* if you have the MIT gssapi libraries */ +#cmakedefine HAVE_GSSMIT 1 + +/* Define to 1 if you have the `idna_strerror' function. */ +#cmakedefine HAVE_IDNA_STRERROR 1 + +/* Define to 1 if you have the `idn_free' function. */ +#cmakedefine HAVE_IDN_FREE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IDN_FREE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_addr' function. */ +#cmakedefine HAVE_INET_ADDR 1 + +/* Define to 1 if you have the inet_ntoa_r function. */ +#cmakedefine HAVE_INET_NTOA_R 1 + +/* inet_ntoa_r() takes 2 args */ +#cmakedefine HAVE_INET_NTOA_R_2 1 + +/* inet_ntoa_r() takes 3 args */ +#cmakedefine HAVE_INET_NTOA_R_3 1 + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#cmakedefine HAVE_INET_NTOP 1 + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#cmakedefine HAVE_INET_PTON 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#cmakedefine HAVE_IOCTL 1 + +/* Define to 1 if you have the ioctlsocket function. */ +#cmakedefine HAVE_IOCTLSOCKET 1 + +/* Define to 1 if you have the IoctlSocket camel case function. */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1 + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1 + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#cmakedefine HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IO_H 1 + +/* if you have the Kerberos4 libraries (including -ldes) */ +#cmakedefine HAVE_KRB4 1 + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_KRB_H 1 + +/* Define to 1 if you have the lber.h header file. */ +#cmakedefine HAVE_LBER_H 1 + +/* Define to 1 if you have the ldapssl.h header file. */ +#cmakedefine HAVE_LDAPSSL_H 1 + +/* Define to 1 if you have the ldap.h header file. */ +#cmakedefine HAVE_LDAP_H 1 + +/* Use LDAPS implementation */ +#cmakedefine HAVE_LDAP_SSL 1 + +/* Define to 1 if you have the ldap_ssl.h header file. */ +#cmakedefine HAVE_LDAP_SSL_H 1 + +/* Define to 1 if you have the `ldap_url_parse' function. */ +#cmakedefine HAVE_LDAP_URL_PARSE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIBGEN_H 1 + +/* Define to 1 if you have the `idn' library (-lidn). */ +#cmakedefine HAVE_LIBIDN 1 + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#cmakedefine HAVE_LIBRESOLV 1 + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +#cmakedefine HAVE_LIBRESOLVE 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#cmakedefine HAVE_LIBSOCKET 1 + +/* Define to 1 if you have the `ssh2' library (-lssh2). */ +#cmakedefine HAVE_LIBSSH2 1 + +/* Define to 1 if libssh2 provides `libssh2_version'. */ +#cmakedefine HAVE_LIBSSH2_VERSION 1 + +/* Define to 1 if libssh2 provides `libssh2_init'. */ +#cmakedefine HAVE_LIBSSH2_INIT 1 + +/* Define to 1 if libssh2 provides `libssh2_exit'. */ +#cmakedefine HAVE_LIBSSH2_EXIT 1 + +/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */ +#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1 + +/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */ +#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIBSSH2_H 1 + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#cmakedefine HAVE_LIBSSL 1 + +/* if zlib is available */ +#cmakedefine HAVE_LIBZ 1 + +/* if brotli is available */ +#cmakedefine HAVE_BROTLI 1 + +/* if your compiler supports LL */ +#cmakedefine HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LOCALE_H 1 + +/* Define to 1 if you have a working localtime_r function. */ +#cmakedefine HAVE_LOCALTIME_R 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#cmakedefine HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +#cmakedefine HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +#cmakedefine HAVE_MSG_NOSIGNAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NET_IF_H 1 + +/* Define to 1 if NI_WITHSCOPEID exists and works. */ +#cmakedefine HAVE_NI_WITHSCOPEID 1 + +/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */ +#cmakedefine HAVE_OLD_GSSMIT 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ENGINE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_PEM_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_PKCS12_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_RSA_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_X509_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PEM_H 1 + +/* Define to 1 if you have the `perror' function. */ +#cmakedefine HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#cmakedefine HAVE_PIPE 1 + +/* Define to 1 if you have a working poll function. */ +#cmakedefine HAVE_POLL 1 + +/* If you have a fine poll */ +#cmakedefine HAVE_POLL_FINE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_POLL_H 1 + +/* Define to 1 if you have a working POSIX-style strerror_r function. */ +#cmakedefine HAVE_POSIX_STRERROR_R 1 + +/* Define to 1 if you have the header file */ +#cmakedefine HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PWD_H 1 + +/* Define to 1 if you have the `RAND_egd' function. */ +#cmakedefine HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +#cmakedefine HAVE_RAND_SCREEN 1 + +/* Define to 1 if you have the `RAND_status' function. */ +#cmakedefine HAVE_RAND_STATUS 1 + +/* Define to 1 if you have the recv function. */ +#cmakedefine HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#cmakedefine HAVE_RECVFROM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_RSA_H 1 + +/* Define to 1 if you have the select function. */ +#cmakedefine HAVE_SELECT 1 + +/* Define to 1 if you have the send function. */ +#cmakedefine HAVE_SEND 1 + +/* Define to 1 if you have the 'fsetxattr' function. */ +#cmakedefine HAVE_FSETXATTR 1 + +/* fsetxattr() takes 5 args */ +#cmakedefine HAVE_FSETXATTR_5 1 + +/* fsetxattr() takes 6 args */ +#cmakedefine HAVE_FSETXATTR_6 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#cmakedefine HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setmode' function. */ +#cmakedefine HAVE_SETMODE 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#cmakedefine HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the setsockopt function. */ +#cmakedefine HAVE_SETSOCKOPT 1 + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SGTTY_H 1 + +/* Define to 1 if you have the sigaction function. */ +#cmakedefine HAVE_SIGACTION 1 + +/* Define to 1 if you have the siginterrupt function. */ +#cmakedefine HAVE_SIGINTERRUPT 1 + +/* Define to 1 if you have the signal function. */ +#cmakedefine HAVE_SIGNAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the sigsetjmp function or macro. */ +#cmakedefine HAVE_SIGSETJMP 1 + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#cmakedefine HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1 + +/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ +#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to 1 if you have the `socket' function. */ +#cmakedefine HAVE_SOCKET 1 + +/* Define to 1 if you have the `SSL_get_shutdown' function. */ +#cmakedefine HAVE_SSL_GET_SHUTDOWN 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the strcasecmp function. */ +#cmakedefine HAVE_STRCASECMP 1 + +/* Define to 1 if you have the strcasestr function. */ +#cmakedefine HAVE_STRCASESTR 1 + +/* Define to 1 if you have the strcmpi function. */ +#cmakedefine HAVE_STRCMPI 1 + +/* Define to 1 if you have the strdup function. */ +#cmakedefine HAVE_STRDUP 1 + +/* Define to 1 if you have the strerror_r function. */ +#cmakedefine HAVE_STRERROR_R 1 + +/* Define to 1 if you have the stricmp function. */ +#cmakedefine HAVE_STRICMP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the strlcat function. */ +#cmakedefine HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#cmakedefine HAVE_STRLCPY 1 + +/* Define to 1 if you have the strncasecmp function. */ +#cmakedefine HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the strncmpi function. */ +#cmakedefine HAVE_STRNCMPI 1 + +/* Define to 1 if you have the strnicmp function. */ +#cmakedefine HAVE_STRNICMP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STROPTS_H 1 + +/* Define to 1 if you have the strstr function. */ +#cmakedefine HAVE_STRSTR 1 + +/* Define to 1 if you have the strtok_r function. */ +#cmakedefine HAVE_STRTOK_R 1 + +/* Define to 1 if you have the strtoll function. */ +#cmakedefine HAVE_STRTOLL 1 + +/* if struct sockaddr_storage is defined */ +#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#cmakedefine HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UTIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TERMIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TLD_H 1 + +/* Define to 1 if you have the `tld_strerror' function. */ +#cmakedefine HAVE_TLD_STRERROR 1 + +/* Define to 1 if you have the `uname' function. */ +#cmakedefine HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#cmakedefine HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UTIME_H 1 + +/* Define to 1 if compiler supports C99 variadic macro style. */ +#cmakedefine HAVE_VARIADIC_MACROS_C99 1 + +/* Define to 1 if compiler supports old gcc variadic macro style. */ +#cmakedefine HAVE_VARIADIC_MACROS_GCC 1 + +/* Define to 1 if you have the winber.h header file. */ +#cmakedefine HAVE_WINBER_H 1 + +/* Define to 1 if you have the windows.h header file. */ +#cmakedefine HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the winldap.h header file. */ +#cmakedefine HAVE_WINLDAP_H 1 + +/* Define to 1 if you have the winsock2.h header file. */ +#cmakedefine HAVE_WINSOCK2_H 1 + +/* Define to 1 if you have the winsock.h header file. */ +#cmakedefine HAVE_WINSOCK_H 1 + +/* Define this symbol if your OS supports changing the contents of argv */ +#cmakedefine HAVE_WRITABLE_ARGV 1 + +/* Define to 1 if you have the writev function. */ +#cmakedefine HAVE_WRITEV 1 + +/* Define to 1 if you have the ws2tcpip.h header file. */ +#cmakedefine HAVE_WS2TCPIP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_X509_H 1 + +/* Define if you have the header file. */ +#cmakedefine HAVE_PROCESS_H 1 + +/* if you have the zlib.h header file */ +#cmakedefine HAVE_ZLIB_H 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#cmakedefine LT_OBJDIR ${LT_OBJDIR} + +/* If you lack a fine basename() prototype */ +#cmakedefine NEED_BASENAME_PROTO 1 + +/* Define to 1 if you need the lber.h header file even with ldap.h */ +#cmakedefine NEED_LBER_H 1 + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +#cmakedefine NEED_MALLOC_H 1 + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#cmakedefine NEED_REENTRANT 1 + +/* cpu-machine-OS */ +#cmakedefine OS ${OS} + +/* Name of package */ +#cmakedefine PACKAGE ${PACKAGE} + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT} + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME ${PACKAGE_NAME} + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING ${PACKAGE_STRING} + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME} + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} + +/* a suitable file to read random data from */ +#cmakedefine RANDOM_FILE "${RANDOM_FILE}" + +/* Define to the type of arg 1 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1} + +/* Define to the type pointed by arg 2 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2} + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1 + +/* Define to the type of arg 3 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3} + +/* Define to the type of arg 4 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4} + +/* Define to the type pointed by arg 5 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5} + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1 + +/* Define to the type pointed by arg 6 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6} + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1 + +/* Define to the function return type for recvfrom. */ +#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV} + +/* Define to the type of arg 1 for recv. */ +#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1} + +/* Define to the type of arg 2 for recv. */ +#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2} + +/* Define to the type of arg 3 for recv. */ +#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3} + +/* Define to the type of arg 4 for recv. */ +#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4} + +/* Define to the function return type for recv. */ +#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV} + +/* Define as the return type of signal handlers (`int' or `void'). */ +#cmakedefine RETSIGTYPE ${RETSIGTYPE} + +/* Define to the type qualifier of arg 5 for select. */ +#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5} + +/* Define to the type of arg 1 for select. */ +#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1} + +/* Define to the type of args 2, 3 and 4 for select. */ +#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234} + +/* Define to the type of arg 5 for select. */ +#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5} + +/* Define to the function return type for select. */ +#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV} + +/* Define to the type qualifier of arg 2 for send. */ +#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2} + +/* Define to the type of arg 1 for send. */ +#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1} + +/* Define to the type of arg 2 for send. */ +#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2} + +/* Define to the type of arg 3 for send. */ +#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3} + +/* Define to the type of arg 4 for send. */ +#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4} + +/* Define to the function return type for send. */ +#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV} + +/* The size of `int', as computed by sizeof. */ + at SIZEOF_INT_CODE@ + +/* The size of `short', as computed by sizeof. */ + at SIZEOF_SHORT_CODE@ + +/* The size of `long', as computed by sizeof. */ + at SIZEOF_LONG_CODE@ + +/* The size of `long long', as computed by sizeof. */ + at SIZEOF_LONG_LONG_CODE@ + +/* The size of `__int64', as computed by sizeof. */ + at SIZEOF___INT64_CODE@ + +/* The size of `off_t', as computed by sizeof. */ + at SIZEOF_OFF_T_CODE@ + +/* The size of `curl_off_t', as computed by sizeof. */ + at SIZEOF_CURL_OFF_T_CODE@ + +/* The size of `size_t', as computed by sizeof. */ + at SIZEOF_SIZE_T_CODE@ + +/* The size of `ssize_t', as computed by sizeof. */ + at SIZEOF_SSIZE_T_CODE@ + +/* The size of `time_t', as computed by sizeof. */ + at SIZEOF_TIME_T_CODE@ + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Define to the type of arg 3 for strerror_r. */ +#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3} + +/* Define to 1 if you can safely include both and . */ +#cmakedefine TIME_WITH_SYS_TIME 1 + +/* Define if you want to enable c-ares support */ +#cmakedefine USE_ARES 1 + +/* Define if you want to enable POSIX threaded DNS lookup */ +#cmakedefine USE_THREADS_POSIX 1 + +/* Define if you want to enable WIN32 threaded DNS lookup */ +#cmakedefine USE_THREADS_WIN32 1 + +/* Define to disable non-blocking sockets. */ +#cmakedefine USE_BLOCKING_SOCKETS 1 + +/* if GnuTLS is enabled */ +#cmakedefine USE_GNUTLS 1 + +/* if PolarSSL is enabled */ +#cmakedefine USE_POLARSSL 1 + +/* if DarwinSSL is enabled */ +#cmakedefine USE_DARWINSSL 1 + +/* if mbedTLS is enabled */ +#cmakedefine USE_MBEDTLS 1 + +/* if libSSH2 is in use */ +#cmakedefine USE_LIBSSH2 1 + +/* If you want to build curl with the built-in manual */ +#cmakedefine USE_MANUAL 1 + +/* if NSS is enabled */ +#cmakedefine USE_NSS 1 + +/* if you want to use OpenLDAP code instead of legacy ldap implementation */ +#cmakedefine USE_OPENLDAP 1 + +/* if OpenSSL is in use */ +#cmakedefine USE_OPENSSL 1 + +/* to enable NGHTTP2 */ +#cmakedefine USE_NGHTTP2 1 + +/* if Unix domain sockets are enabled */ +#cmakedefine USE_UNIX_SOCKETS + +/* to enable SSPI support */ +#cmakedefine USE_WINDOWS_SSPI 1 + +/* to enable Windows SSL */ +#cmakedefine USE_SCHANNEL 1 + +/* enable multiple SSL backends */ +#cmakedefine CURL_WITH_MULTI_SSL 1 + +/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ +#cmakedefine USE_YASSLEMUL 1 + +/* Version number of package */ +#cmakedefine VERSION ${VERSION} + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} + +/* Define for large files, on AIX-style hosts. */ +#cmakedefine _LARGE_FILES ${_LARGE_FILES} + +/* define this if you need it to compile thread-safe code */ +#cmakedefine _THREAD_SAFE ${_THREAD_SAFE} + +/* Define to empty if `const' does not conform to ANSI C. */ +#cmakedefine const ${const} + +/* Type to use in place of in_addr_t when system does not provide it. */ +#cmakedefine in_addr_t ${in_addr_t} + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t ${size_t} + +/* the signed version of size_t */ +#ifndef SIZEOF_SSIZE_T +# if SIZEOF_LONG == SIZEOF_SIZE_T + typedef long ssize_t; +# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T + typedef long long ssize_t; +# elif SIZEOF___INT64 == SIZEOF_SIZE_T + typedef __int64 ssize_t; +# else + typedef int ssize_t; +# endif +#endif + +/* Define to 1 if you have the mach_absolute_time function. */ +#cmakedefine HAVE_MACH_ABSOLUTE_TIME 1 diff --cc Utilities/cmcurl/lib/curl_setup.h index b056126,0000000..5cdbc592 mode 100644,000000..100644 --- a/Utilities/cmcurl/lib/curl_setup.h +++ b/Utilities/cmcurl/lib/curl_setup.h @@@ -1,831 -1,0 +1,834 @@@ +#ifndef HEADER_CURL_SETUP_H +#define HEADER_CURL_SETUP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES) +#define CURL_NO_OLDIES +#endif + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \ + !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#ifdef WIN32 +/* + * Don't include unneeded stuff in Windows headers to avoid compiler + * warnings and macro clashes. + * Make sure to define this macro before including any Windows headers. + */ +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif ++# ifndef NOGDI ++# define NOGDI ++# endif +#endif + +/* + * Include configuration script results or hand-crafted + * configuration file for platforms which lack config tool. + */ + +#ifdef HAVE_CONFIG_H + +#include "curl_config.h" + +#else /* HAVE_CONFIG_H */ + +#ifdef _WIN32_WCE +# include "config-win32ce.h" +#else +# ifdef WIN32 +# include "config-win32.h" +# endif +#endif + +#if defined(macintosh) && defined(__MRC__) +# include "config-mac.h" +#endif + +#ifdef __riscos__ +# include "config-riscos.h" +#endif + +#ifdef __AMIGA__ +# include "config-amigaos.h" +#endif + +#ifdef __SYMBIAN32__ +# include "config-symbian.h" +#endif + +#ifdef __OS400__ +# include "config-os400.h" +#endif + +#ifdef TPF +# include "config-tpf.h" +#endif + +#ifdef __VXWORKS__ +# include "config-vxworks.h" +#endif + +#endif /* HAVE_CONFIG_H */ + +#if defined(_MSC_VER) +# pragma warning(push,1) +#endif + +/* ================================================================ */ +/* Definition of preprocessor macros/symbols which modify compiler */ +/* behavior or generated code characteristics must be done here, */ +/* as appropriate, before any system header file is included. It is */ +/* also possible to have them defined in the config file included */ +/* before this point. As a result of all this we frown inclusion of */ +/* system header files in our config files, avoid this at any cost. */ +/* ================================================================ */ + +/* + * AIX 4.3 and newer needs _THREAD_SAFE defined to build + * proper reentrant code. Others may also need it. + */ + +#ifdef NEED_THREAD_SAFE +# ifndef _THREAD_SAFE +# define _THREAD_SAFE +# endif +#endif + +/* + * Tru64 needs _REENTRANT set for a few function prototypes and + * things to appear in the system header files. Unixware needs it + * to build proper reentrant code. Others may also need it. + */ + +#ifdef NEED_REENTRANT +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +/* Solaris needs this to get a POSIX-conformant getpwuid_r */ +#if defined(sun) || defined(__sun) +# ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +# endif +#endif + +/* ================================================================ */ +/* If you need to include a system header file for your platform, */ +/* please, do it beyond the point further indicated in this file. */ +/* ================================================================ */ + +#include + +#define CURL_SIZEOF_CURL_OFF_T SIZEOF_CURL_OFF_T + +/* + * Disable other protocols when http is the only one desired. + */ + +#ifdef HTTP_ONLY +# ifndef CURL_DISABLE_TFTP +# define CURL_DISABLE_TFTP +# endif +# ifndef CURL_DISABLE_FTP +# define CURL_DISABLE_FTP +# endif +# ifndef CURL_DISABLE_LDAP +# define CURL_DISABLE_LDAP +# endif +# ifndef CURL_DISABLE_TELNET +# define CURL_DISABLE_TELNET +# endif +# ifndef CURL_DISABLE_DICT +# define CURL_DISABLE_DICT +# endif +# ifndef CURL_DISABLE_FILE +# define CURL_DISABLE_FILE +# endif +# ifndef CURL_DISABLE_RTSP +# define CURL_DISABLE_RTSP +# endif +# ifndef CURL_DISABLE_POP3 +# define CURL_DISABLE_POP3 +# endif +# ifndef CURL_DISABLE_IMAP +# define CURL_DISABLE_IMAP +# endif +# ifndef CURL_DISABLE_SMTP +# define CURL_DISABLE_SMTP +# endif +# ifndef CURL_DISABLE_GOPHER +# define CURL_DISABLE_GOPHER +# endif +# ifndef CURL_DISABLE_SMB +# define CURL_DISABLE_SMB +# endif +#endif + +/* + * When http is disabled rtsp is not supported. + */ + +#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP) +# define CURL_DISABLE_RTSP +#endif + +/* ================================================================ */ +/* No system header file shall be included in this file before this */ +/* point. The only allowed ones are those included from curl/system.h */ +/* ================================================================ */ + +/* + * OS/400 setup file includes some system headers. + */ + +#ifdef __OS400__ +# include "setup-os400.h" +#endif + +/* + * VMS setup file includes some system headers. + */ + +#ifdef __VMS +# include "setup-vms.h" +#endif + +/* + * Use getaddrinfo to resolve the IPv4 address literal. If the current network + * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64, + * performing this task will result in a synthesized IPv6 address. + */ +#ifdef __APPLE__ +#define USE_RESOLVE_ON_IPS 1 +#endif + +/* + * Include header files for windows builds before redefining anything. + * Use this preprocessor block only to include or exclude windows.h, + * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs + * to any other further and independent block. Under Cygwin things work + * just as under linux (e.g. ) and the winsock headers should + * never be included when __CYGWIN__ is defined. configure script takes + * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, + * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. + */ + +#ifdef HAVE_WINDOWS_H +# if defined(UNICODE) && !defined(_UNICODE) +# define _UNICODE +# endif +# if defined(_UNICODE) && !defined(UNICODE) +# define UNICODE +# endif +# include +# include +# ifdef HAVE_WINSOCK2_H +# include +# ifdef HAVE_WS2TCPIP_H +# include +# endif +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +# include +# ifdef UNICODE + typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str); +# endif +#endif + +/* + * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else + * define USE_WINSOCK to 1 if we have and use WINSOCK API, else + * undefine USE_WINSOCK. + */ + +#undef USE_WINSOCK + +#ifdef HAVE_WINSOCK2_H +# define USE_WINSOCK 2 +#else +# ifdef HAVE_WINSOCK_H +# define USE_WINSOCK 1 +# endif +#endif + +#ifdef USE_LWIPSOCK +# include +# include +# include +#endif + +#ifdef HAVE_EXTRA_STRICMP_H +# include +#endif + +#ifdef HAVE_EXTRA_STRDUP_H +# include +#endif + +#ifdef TPF +# include /* for bzero, strcasecmp, and strncasecmp */ +# include /* for strcpy and strlen */ +# include /* for rand and srand */ +# include /* for select and ioctl*/ +# include /* for in_addr_t definition */ +# include /* for tpf_process_signals */ + /* change which select is used for libcurl */ +# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e) +#endif + +#ifdef __VXWORKS__ +# include /* for generic BSD socket functions */ +# include /* for basic I/O interface functions */ +#endif + +#ifdef __AMIGA__ +# ifndef __ixemul__ +# include +# include +# include +# include +# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) +# endif +#endif + +#include +#ifdef HAVE_ASSERT_H +#include +#endif + +#ifdef __TANDEM /* for nsr-tandem-nsk systems */ +#include +#endif + +#ifndef STDC_HEADERS /* no standard C headers! */ +#include +#endif + +#ifdef __POCC__ +# include +# include +# define sys_nerr EILSEQ +#endif + +/* + * Salford-C kludge section (mostly borrowed from wxWidgets). + */ +#ifdef __SALFORDC__ + #pragma suppress 353 /* Possible nested comments */ + #pragma suppress 593 /* Define not used */ + #pragma suppress 61 /* enum has no name */ + #pragma suppress 106 /* unnamed, unused parameter */ + #include +#endif + +/* Default Windows file API selection. */ +#ifdef _WIN32 +# if defined(_MSC_VER) && (_INTEGRAL_MAX_BITS >= 64) +# define USE_WIN32_LARGE_FILES +# elif defined(__MINGW32__) +# define USE_WIN32_LARGE_FILES +# else +# define USE_WIN32_SMALL_FILES +# endif +#endif + +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef USE_WIN32_LARGE_FILES +# include +# include +# include +# undef lseek +# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence) +# undef fstat +# define fstat(fdes,stp) _fstati64(fdes, stp) +# undef stat +# define stat(fname,stp) _stati64(fname, stp) +# define struct_stat struct _stati64 +# define LSEEK_ERROR (__int64)-1 +#endif + +/* + * Small file (<2Gb) support using WIN32 functions. + */ + +#ifdef USE_WIN32_SMALL_FILES +# include +# include +# include +# ifndef _WIN32_WCE +# undef lseek +# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence) +# define fstat(fdes,stp) _fstat(fdes, stp) +# define stat(fname,stp) _stat(fname, stp) +# define struct_stat struct _stat +# endif +# define LSEEK_ERROR (long)-1 +#endif + +#ifndef struct_stat +# define struct_stat struct stat +#endif + +#ifndef LSEEK_ERROR +# define LSEEK_ERROR (off_t)-1 +#endif + +#ifndef SIZEOF_TIME_T +/* assume default size of time_t to be 32 bit */ +#define SIZEOF_TIME_T 4 +#endif + +/* + * Default sizeof(off_t) in case it hasn't been defined in config file. + */ + +#ifndef SIZEOF_OFF_T +# if defined(__VMS) && !defined(__VAX) +# if defined(_LARGEFILE) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__OS400__) && defined(__ILEC400__) +# if defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__MVS__) && defined(__IBMC__) +# if defined(_LP64) || defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__370__) && defined(__IBMC__) +# if defined(_LP64) || defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# endif +# ifndef SIZEOF_OFF_T +# define SIZEOF_OFF_T 4 +# endif +#endif + +#if (SIZEOF_CURL_OFF_T == 4) +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) +#else + /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +#endif +#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) + +#if (SIZEOF_TIME_T == 4) +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX UINT_MAX +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX INT_MAX +# define TIME_T_MIN INT_MIN +# endif +#else +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF +# define TIME_T_MIN (-TIME_T_MAX - 1) +# endif +#endif + +#ifndef SIZE_T_MAX +/* some limits.h headers have this defined, some don't */ +#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) +#define SIZE_T_MAX 18446744073709551615U +#else +#define SIZE_T_MAX 4294967295U +#endif +#endif + +/* + * Arg 2 type for gethostname in case it hasn't been defined in config file. + */ + +#ifndef GETHOSTNAME_TYPE_ARG2 +# ifdef USE_WINSOCK +# define GETHOSTNAME_TYPE_ARG2 int +# else +# define GETHOSTNAME_TYPE_ARG2 size_t +# endif +#endif + +/* Below we define some functions. They should + + 4. set the SIGALRM signal timeout + 5. set dir/file naming defines + */ + +#ifdef WIN32 + +# define DIR_CHAR "\\" +# define DOT_CHAR "_" + +#else /* WIN32 */ + +# ifdef MSDOS /* Watt-32 */ + +# include +# define select(n,r,w,x,t) select_s(n,r,w,x,t) +# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) +# include +# ifdef word +# undef word +# endif +# ifdef byte +# undef byte +# endif + +# endif /* MSDOS */ + +# ifdef __minix + /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */ + extern char *strtok_r(char *s, const char *delim, char **last); + extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp); +# endif + +# define DIR_CHAR "/" +# ifndef DOT_CHAR +# define DOT_CHAR "." +# endif + +# ifdef MSDOS +# undef DOT_CHAR +# define DOT_CHAR "_" +# endif + +# ifndef fileno /* sunos 4 have this as a macro! */ + int fileno(FILE *stream); +# endif + +#endif /* WIN32 */ + +/* + * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN + * defined in ws2tcpip.h as well as to provide IPv6 support. + * Does not apply if lwIP is used. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK) +# if !defined(HAVE_WS2TCPIP_H) || \ + ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN)) +# undef HAVE_GETADDRINFO_THREADSAFE +# undef HAVE_FREEADDRINFO +# undef HAVE_GETADDRINFO +# undef HAVE_GETNAMEINFO +# undef ENABLE_IPV6 +# endif +#endif + +/* ---------------------------------------------------------------- */ +/* resolver specialty compile-time defines */ +/* CURLRES_* defines to use in the host*.c sources */ +/* ---------------------------------------------------------------- */ + +/* + * lcc-win32 doesn't have _beginthreadex(), lacks threads support. + */ + +#if defined(__LCC__) && defined(WIN32) +# undef USE_THREADS_POSIX +# undef USE_THREADS_WIN32 +#endif + +/* + * MSVC threads support requires a multi-threaded runtime library. + * _beginthreadex() is not available in single-threaded ones. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT) +# undef USE_THREADS_POSIX +# undef USE_THREADS_WIN32 +#endif + +/* + * Mutually exclusive CURLRES_* definitions. + */ + +#ifdef USE_ARES +# define CURLRES_ASYNCH +# define CURLRES_ARES +/* now undef the stock libc functions just to avoid them being used */ +# undef HAVE_GETADDRINFO +# undef HAVE_FREEADDRINFO +# undef HAVE_GETHOSTBYNAME +#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +# define CURLRES_ASYNCH +# define CURLRES_THREADED +#else +# define CURLRES_SYNCH +#endif + +#ifdef ENABLE_IPV6 +# define CURLRES_IPV6 +#else +# define CURLRES_IPV4 +#endif + +/* ---------------------------------------------------------------- */ + +/* + * When using WINSOCK, TELNET protocol requires WINSOCK2 API. + */ + +#if defined(USE_WINSOCK) && (USE_WINSOCK != 2) +# define CURL_DISABLE_TELNET 1 +#endif + +/* + * msvc 6.0 does not have struct sockaddr_storage and + * does not define IPPROTO_ESP in winsock2.h. But both + * are available if PSDK is properly installed. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) +# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP)) +# undef HAVE_STRUCT_SOCKADDR_STORAGE +# endif +#endif + +/* + * Intentionally fail to build when using msvc 6.0 without PSDK installed. + * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK + * in lib/config-win32.h although absolutely discouraged and unsupported. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) +# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_)) +# if !defined(ALLOW_MSVC6_WITHOUT_PSDK) +# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \ + "Windows Server 2003 PSDK" +# else +# define CURL_DISABLE_LDAP 1 +# endif +# endif +#endif + +#ifdef NETWARE +int netware_init(void); +#ifndef __NOVELL_LIBC__ +#include +#include +#endif +#endif + +#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN) +/* The lib and header are present */ +#define USE_LIBIDN2 +#endif + +#if defined(USE_LIBIDN2) && defined(USE_WIN32_IDN) +#error "Both libidn2 and WinIDN are enabled, choose one." +#endif + +#define LIBIDN_REQUIRED_VERSION "0.4.1" + +#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ + defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \ + defined(USE_CYASSL) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_GSKIT) ++ defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK) +#define USE_SSL /* SSL support has been enabled */ +#endif + +/* Single point where USE_SPNEGO definition might be defined */ +#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ + (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) +#define USE_SPNEGO +#endif + +/* Single point where USE_KERBEROS5 definition might be defined */ +#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ + (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) +#define USE_KERBEROS5 +#endif + +/* Single point where USE_NTLM definition might be defined */ +#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) +#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \ + defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \ + defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ + defined(USE_MBEDTLS) + +#define USE_NTLM + +# if defined(USE_MBEDTLS) +/* Get definition of MBEDTLS_MD4_C */ +# include +# endif + +#endif +#endif + +#ifdef CURL_WANTS_CA_BUNDLE_ENV +#error "No longer supported. Set CURLOPT_CAINFO at runtime instead." +#endif + +/* + * Provide a mechanism to silence picky compilers, such as gcc 4.6+. + * Parameters should of course normally not be unused, but for example when + * we have multiple implementations of the same interface it may happen. + */ + +#if defined(__GNUC__) && ((__GNUC__ >= 3) || \ + ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7))) +# define UNUSED_PARAM __attribute__((__unused__)) +# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define UNUSED_PARAM /*NOTHING*/ +# define WARN_UNUSED_RESULT +#endif + +/* + * Include macros and defines that should only be processed once. + */ + +#ifndef HEADER_CURL_SETUP_ONCE_H +#include "curl_setup_once.h" +#endif + +/* + * Definition of our NOP statement Object-like macro + */ + +#ifndef Curl_nop_stmt +# define Curl_nop_stmt do { } WHILE_FALSE +#endif + +/* + * Ensure that Winsock and lwIP TCP/IP stacks are not mixed. + */ + +#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H) +# if defined(SOCKET) || \ + defined(USE_WINSOCK) || \ + defined(HAVE_WINSOCK_H) || \ + defined(HAVE_WINSOCK2_H) || \ + defined(HAVE_WS2TCPIP_H) +# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" +# endif +#endif + +/* + * Portable symbolic names for Winsock shutdown() mode flags. + */ + +#ifdef USE_WINSOCK +# define SHUT_RD 0x00 +# define SHUT_WR 0x01 +# define SHUT_RDWR 0x02 +#endif + +/* Define S_ISREG if not defined by system headers, f.e. MSVC */ +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +/* Define S_ISDIR if not defined by system headers, f.e. MSVC */ +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +/* In Windows the default file mode is text but an application can override it. +Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 +*/ +#if defined(WIN32) || defined(MSDOS) +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "wt" +#define FOPEN_APPENDTEXT "at" +#elif defined(__CYGWIN__) +/* Cygwin has specific behavior we need to address when WIN32 is not defined. +https://cygwin.com/cygwin-ug-net/using-textbinary.html +For write we want our output to have line endings of LF and be compatible with +other Cygwin utilities. For read we want to handle input that may have line +endings either CRLF or LF so 't' is appropriate. +*/ +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#else +#define FOPEN_READTEXT "r" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#endif + +/* WinSock destroys recv() buffer when send() failed. + * Enabled automatically for Windows and for Cygwin as Cygwin sockets are + * wrappers for WinSock sockets. https://github.com/curl/curl/issues/657 + * Define DONT_USE_RECV_BEFORE_SEND_WORKAROUND to force disable workaround. + */ +#if !defined(DONT_USE_RECV_BEFORE_SEND_WORKAROUND) +# if defined(WIN32) || defined(__CYGWIN__) +# define USE_RECV_BEFORE_SEND_WORKAROUND +# endif +#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ +# ifdef USE_RECV_BEFORE_SEND_WORKAROUND +# undef USE_RECV_BEFORE_SEND_WORKAROUND +# endif +#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ + +/* Detect Windows App environment which has a restricted access + * to the Win32 APIs. */ +# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ + defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define CURL_WINDOWS_APP +# endif +# endif + +/* for systems that don't detect this in configure, use a sensible default */ +#ifndef CURL_SA_FAMILY_T +#define CURL_SA_FAMILY_T unsigned short +#endif + +/* Some convenience macros to get the larger/smaller value out of two given. + We prefix with CURL to prevent name collisions. */ +#define CURLMAX(x,y) ((x)>(y)?(x):(y)) +#define CURLMIN(x,y) ((x)<(y)?(x):(y)) + +/* Some versions of the Android SDK is missing the declaration */ +#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING) +struct passwd; +int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, + size_t buflen, struct passwd **result); +#endif + +#endif /* HEADER_CURL_SETUP_H */ diff --cc Utilities/cmcurl/lib/doh.c index 0000000,ef6013d..ef6013d mode 000000,100644..100644 --- a/Utilities/cmcurl/lib/doh.c +++ b/Utilities/cmcurl/lib/doh.c diff --cc Utilities/cmcurl/lib/doh.h index 0000000,83c79bc..83c79bc mode 000000,100644..100644 --- a/Utilities/cmcurl/lib/doh.h +++ b/Utilities/cmcurl/lib/doh.h diff --cc Utilities/cmcurl/lib/ftp.c index 63f32cf,0000000..ce889ab mode 100644,000000..100644 --- a/Utilities/cmcurl/lib/ftp.c +++ b/Utilities/cmcurl/lib/ftp.c @@@ -1,4446 -1,0 +1,4452 @@@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "if2ip.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "socks.h" +#include "ftp.h" +#include "fileinfo.h" +#include "ftplistparser.h" +#include "curl_range.h" +#include "curl_sec.h" +#include "strtoofft.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "inet_pton.h" +#include "select.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "multiif.h" +#include "url.h" +#include "strcase.h" +#include "speedcheck.h" +#include "warnless.h" +#include "http_proxy.h" +#include "non-ascii.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt +#endif + +/* Local API functions */ +#ifndef DEBUGBUILD +static void _state(struct connectdata *conn, + ftpstate newstate); +#define state(x,y) _state(x,y) +#else +static void _state(struct connectdata *conn, + ftpstate newstate, + int lineno); +#define state(x,y) _state(x,y,__LINE__) +#endif + +static CURLcode ftp_sendquote(struct connectdata *conn, + struct curl_slist *quote); +static CURLcode ftp_quit(struct connectdata *conn); +static CURLcode ftp_parse_url_path(struct connectdata *conn); +static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done); +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void ftp_pasv_verbose(struct connectdata *conn, + Curl_addrinfo *ai, + char *newhost, /* ascii version */ + int port); +#endif +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn); +static CURLcode ftp_state_mdtm(struct connectdata *conn); +static CURLcode ftp_state_quote(struct connectdata *conn, + bool init, ftpstate instate); +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate newstate); +static int ftp_need_type(struct connectdata *conn, + bool ascii); +static CURLcode ftp_do(struct connectdata *conn, bool *done); +static CURLcode ftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode ftp_connect(struct connectdata *conn, bool *done); +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); +static CURLcode ftp_do_more(struct connectdata *conn, int *completed); +static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); +static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode ftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode ftp_setup_connection(struct connectdata * conn); + +static CURLcode init_wc_data(struct connectdata *conn); +static CURLcode wc_statemach(struct connectdata *conn); + +static void wc_data_dtor(void *ptr); + +static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize); + +static CURLcode ftp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *ftpcode, + size_t *size); +static CURLcode ftp_dophase_done(struct connectdata *conn, + bool connected); + +/* easy-to-use macro: */ +#define PPSENDF(x,y,z) result = Curl_pp_sendf(x,y,z); \ + if(result) \ + return result + + +/* + * FTP protocol handler. + */ + +const struct Curl_handler Curl_handler_ftp = { + "FTP", /* scheme */ + ftp_setup_connection, /* setup_connection */ + ftp_do, /* do_it */ + ftp_done, /* done */ + ftp_do_more, /* do_more */ + ftp_connect, /* connect_it */ + ftp_multi_statemach, /* connecting */ + ftp_doing, /* doing */ + ftp_getsock, /* proto_getsock */ + ftp_getsock, /* doing_getsock */ + ftp_domore_getsock, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_FTP, /* defport */ + CURLPROTO_FTP, /* protocol */ + PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | + PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | + PROTOPT_WILDCARD /* flags */ +}; + + +#ifdef USE_SSL +/* + * FTPS protocol handler. + */ + +const struct Curl_handler Curl_handler_ftps = { + "FTPS", /* scheme */ + ftp_setup_connection, /* setup_connection */ + ftp_do, /* do_it */ + ftp_done, /* done */ + ftp_do_more, /* do_more */ + ftp_connect, /* connect_it */ + ftp_multi_statemach, /* connecting */ + ftp_doing, /* doing */ + ftp_getsock, /* proto_getsock */ + ftp_getsock, /* doing_getsock */ + ftp_domore_getsock, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_FTPS, /* defport */ + CURLPROTO_FTPS, /* protocol */ + PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | + PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */ +}; +#endif + +static void close_secondarysocket(struct connectdata *conn) +{ + if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) { + Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; + } + conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; +} + +/* + * NOTE: back in the old days, we added code in the FTP code that made NOBODY + * requests on files respond with headers passed to the client/stdout that + * looked like HTTP ones. + * + * This approach is not very elegant, it causes confusion and is error-prone. + * It is subject for removal at the next (or at least a future) soname bump. + * Until then you can test the effects of the removal by undefining the + * following define named CURL_FTP_HTTPSTYLE_HEAD. + */ +#define CURL_FTP_HTTPSTYLE_HEAD 1 + +static void freedirs(struct ftp_conn *ftpc) +{ + if(ftpc->dirs) { + int i; + for(i = 0; i < ftpc->dirdepth; i++) { + free(ftpc->dirs[i]); + ftpc->dirs[i] = NULL; + } + free(ftpc->dirs); + ftpc->dirs = NULL; + ftpc->dirdepth = 0; + } + Curl_safefree(ftpc->file); + + /* no longer of any use */ + Curl_safefree(ftpc->newhost); +} + +/* Returns non-zero if the given string contains CR (\r) or LF (\n), + which are not allowed within RFC 959 . + Note: The input string is in the client's encoding which might + not be ASCII, so escape sequences \r & \n must be used instead + of hex values 0x0d & 0x0a. +*/ +static bool isBadFtpString(const char *string) +{ + return ((NULL != strchr(string, '\r')) || + (NULL != strchr(string, '\n'))) ? TRUE : FALSE; +} + +/*********************************************************************** + * + * AcceptServerConnect() + * + * After connection request is received from the server this function is + * called to accept the connection and close the listening socket + * + */ +static CURLcode AcceptServerConnect(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sock = conn->sock[SECONDARYSOCKET]; + curl_socket_t s = CURL_SOCKET_BAD; +#ifdef ENABLE_IPV6 + struct Curl_sockaddr_storage add; +#else + struct sockaddr_in add; +#endif + curl_socklen_t size = (curl_socklen_t) sizeof(add); + + if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) { + size = sizeof(add); + + s = accept(sock, (struct sockaddr *) &add, &size); + } + Curl_closesocket(conn, sock); /* close the first socket */ + + if(CURL_SOCKET_BAD == s) { + failf(data, "Error accept()ing server connect"); + return CURLE_FTP_PORT_FAILED; + } + infof(data, "Connection accepted from server\n"); + /* when this happens within the DO state it is important that we mark us as + not needing DO_MORE anymore */ + conn->bits.do_more = FALSE; + + conn->sock[SECONDARYSOCKET] = s; + (void)curlx_nonblock(s, TRUE); /* enable non-blocking */ + conn->sock_accepted[SECONDARYSOCKET] = TRUE; + + if(data->set.fsockopt) { + int error = 0; + + /* activate callback for setting socket options */ + Curl_set_in_callback(data, true); + error = data->set.fsockopt(data->set.sockopt_client, + s, + CURLSOCKTYPE_ACCEPT); + Curl_set_in_callback(data, false); + + if(error) { + close_secondarysocket(conn); + return CURLE_ABORTED_BY_CALLBACK; + } + } + + return CURLE_OK; + +} + +/* + * ftp_timeleft_accept() returns the amount of milliseconds left allowed for + * waiting server to connect. If the value is negative, the timeout time has + * already elapsed. + * + * The start time is stored in progress.t_acceptdata - as set with + * Curl_pgrsTime(..., TIMER_STARTACCEPT); + * + */ +static timediff_t ftp_timeleft_accept(struct Curl_easy *data) +{ + timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT; + timediff_t other; + struct curltime now; + + if(data->set.accepttimeout > 0) + timeout_ms = data->set.accepttimeout; + + now = Curl_now(); + + /* check if the generic timeout possibly is set shorter */ + other = Curl_timeleft(data, &now, FALSE); + if(other && (other < timeout_ms)) + /* note that this also works fine for when other happens to be negative + due to it already having elapsed */ + timeout_ms = other; + else { + /* subtract elapsed time */ + timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata); + if(!timeout_ms) + /* avoid returning 0 as that means no timeout! */ + return -1; + } + + return timeout_ms; +} + + +/*********************************************************************** + * + * ReceivedServerConnect() + * + * After allowing server to connect to us from data port, this function + * checks both data connection for connection establishment and ctrl + * connection for a negative response regarding a failure in connecting + * + */ +static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received) +{ + struct Curl_easy *data = conn->data; + curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET]; + curl_socket_t data_sock = conn->sock[SECONDARYSOCKET]; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + int result; + time_t timeout_ms; + ssize_t nread; + int ftpcode; + + *received = FALSE; + + timeout_ms = ftp_timeleft_accept(data); + infof(data, "Checking for server connect\n"); + if(timeout_ms < 0) { + /* if a timeout was already reached, bail out */ + failf(data, "Accept timeout occurred while waiting server connect"); + return CURLE_FTP_ACCEPT_TIMEOUT; + } + + /* First check whether there is a cached response from server */ + if(pp->cache_size && pp->cache && pp->cache[0] > '3') { + /* Data connection could not be established, let's return */ + infof(data, "There is negative response in cache while serv connect\n"); + Curl_GetFTPResponse(&nread, conn, &ftpcode); + return CURLE_FTP_ACCEPT_FAILED; + } + + result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0); + + /* see if the connection request is already here */ + switch(result) { + case -1: /* error */ + /* let's die here */ + failf(data, "Error while waiting for server connect"); + return CURLE_FTP_ACCEPT_FAILED; + case 0: /* Server connect is not received yet */ + break; /* loop */ + default: + + if(result & CURL_CSELECT_IN2) { + infof(data, "Ready to accept data connection from server\n"); + *received = TRUE; + } + else if(result & CURL_CSELECT_IN) { + infof(data, "Ctrl conn has data while waiting for data conn\n"); + Curl_GetFTPResponse(&nread, conn, &ftpcode); + + if(ftpcode/100 > 3) + return CURLE_FTP_ACCEPT_FAILED; + + return CURLE_WEIRD_SERVER_REPLY; + } + + break; + } /* switch() */ + + return CURLE_OK; +} + + +/*********************************************************************** + * + * InitiateTransfer() + * + * After connection from server is accepted this function is called to + * setup transfer parameters and initiate the data transfer. + * + */ +static CURLcode InitiateTransfer(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + CURLcode result = CURLE_OK; + + if(conn->bits.ftp_use_data_ssl) { + /* since we only have a plaintext TCP connection here, we must now + * do the TLS stuff */ + infof(data, "Doing the SSL/TLS handshake on the data stream\n"); + result = Curl_ssl_connect(conn, SECONDARYSOCKET); + if(result) + return result; + } + + if(conn->proto.ftpc.state_saved == FTP_STOR) { + *(ftp->bytecountp) = 0; + + /* When we know we're uploading a specified file, we can get the file + size prior to the actual upload. */ + + Curl_pgrsSetUploadSize(data, data->state.infilesize); + + /* set the SO_SNDBUF for the secondary socket for those who need it */ + Curl_sndbufset(conn->sock[SECONDARYSOCKET]); + + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ + SECONDARYSOCKET, ftp->bytecountp); + } + else { + /* FTP download: */ + Curl_setup_transfer(conn, SECONDARYSOCKET, + conn->proto.ftpc.retr_size_saved, FALSE, + ftp->bytecountp, -1, NULL); /* no upload here */ + } + + conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ + state(conn, FTP_STOP); + + return CURLE_OK; +} + +/*********************************************************************** + * + * AllowServerConnect() + * + * When we've issue the PORT command, we have told the server to connect to + * us. This function checks whether data connection is established if so it is + * accepted. + * + */ +static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) +{ + struct Curl_easy *data = conn->data; + time_t timeout_ms; + CURLcode result = CURLE_OK; + + *connected = FALSE; + infof(data, "Preparing for accepting server on data port\n"); + + /* Save the time we start accepting server connect */ + Curl_pgrsTime(data, TIMER_STARTACCEPT); + + timeout_ms = ftp_timeleft_accept(data); + if(timeout_ms < 0) { + /* if a timeout was already reached, bail out */ + failf(data, "Accept timeout occurred while waiting server connect"); + return CURLE_FTP_ACCEPT_TIMEOUT; + } + + /* see if the connection request is already here */ + result = ReceivedServerConnect(conn, connected); + if(result) + return result; + + if(*connected) { + result = AcceptServerConnect(conn); + if(result) + return result; + + result = InitiateTransfer(conn); + if(result) + return result; + } + else { + /* Add timeout to multi handle and break out of the loop */ + if(!result && *connected == FALSE) { + Curl_expire(data, data->set.accepttimeout > 0 ? + data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0); + } + } + + return result; +} + +/* macro to check for a three-digit ftp status code at the start of the + given string */ +#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \ + ISDIGIT(line[2])) + +/* macro to check for the last line in an FTP server response */ +#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3])) + +static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len, + int *code) +{ + (void)conn; + + if((len > 3) && LASTLINE(line)) { + *code = curlx_sltosi(strtol(line, NULL, 10)); + return TRUE; + } + + return FALSE; +} + +static CURLcode ftp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *ftpcode, /* return the ftp-code if done */ + size_t *size) /* size of the response */ +{ + struct connectdata *conn = pp->conn; + struct Curl_easy *data = conn->data; +#ifdef HAVE_GSSAPI + char * const buf = data->state.buffer; +#endif + CURLcode result = CURLE_OK; + int code; + + result = Curl_pp_readresp(sockfd, pp, &code, size); + +#if defined(HAVE_GSSAPI) + /* handle the security-oriented responses 6xx ***/ + /* FIXME: some errorchecking perhaps... ***/ + switch(code) { + case 631: + code = Curl_sec_read_msg(conn, buf, PROT_SAFE); + break; + case 632: + code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE); + break; + case 633: + code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL); + break; + default: + /* normal ftp stuff we pass through! */ + break; + } +#endif + + /* store the latest code for later retrieval */ + data->info.httpcode = code; + + if(ftpcode) + *ftpcode = code; + + if(421 == code) { + /* 421 means "Service not available, closing control connection." and FTP + * servers use it to signal that idle session timeout has been exceeded. + * If we ignored the response, it could end up hanging in some cases. + * + * This response code can come at any point so having it treated + * generically is a good idea. + */ + infof(data, "We got a 421 - timeout!\n"); + state(conn, FTP_STOP); + return CURLE_OPERATION_TIMEDOUT; + } + + return result; +} + +/* --- parse FTP server responses --- */ + +/* + * Curl_GetFTPResponse() is a BLOCKING function to read the full response + * from a server after a command. + * + */ + +CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ + struct connectdata *conn, + int *ftpcode) /* return the ftp-code */ +{ + /* + * We cannot read just one byte per read() and then go back to select() as + * the OpenSSL read() doesn't grok that properly. + * + * Alas, read as much as possible, split up into lines, use the ending + * line in a response or continue reading. */ + + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + size_t nread; + int cache_skip = 0; + int value_to_be_ignored = 0; + + if(ftpcode) + *ftpcode = 0; /* 0 for errors */ + else + /* make the pointer point to something for the rest of this function */ + ftpcode = &value_to_be_ignored; + + *nreadp = 0; + + while(!*ftpcode && !result) { + /* check and reset timeout value every lap */ + time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */ + time_t interval_ms; + + if(timeout <= 0) { + failf(data, "FTP response timeout"); + return CURLE_OPERATION_TIMEDOUT; /* already too little time */ + } + + interval_ms = 1000; /* use 1 second timeout intervals */ + if(timeout < interval_ms) + interval_ms = timeout; + + /* + * Since this function is blocking, we need to wait here for input on the + * connection and only then we call the response reading function. We do + * timeout at least every second to make the timeout check run. + * + * A caution here is that the ftp_readresp() function has a cache that may + * contain pieces of a response from the previous invoke and we need to + * make sure we don't just wait for input while there is unhandled data in + * that cache. But also, if the cache is there, we call ftp_readresp() and + * the cache wasn't good enough to continue we must not just busy-loop + * around this function. + * + */ + + if(pp->cache && (cache_skip < 2)) { + /* + * There's a cache left since before. We then skipping the wait for + * socket action, unless this is the same cache like the previous round + * as then the cache was deemed not enough to act on and we then need to + * wait for more data anyway. + */ + } + else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) { + switch(SOCKET_READABLE(sockfd, interval_ms)) { + case -1: /* select() error, stop reading */ + failf(data, "FTP response aborted due to select/poll error: %d", + SOCKERRNO); + return CURLE_RECV_ERROR; + + case 0: /* timeout */ + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + continue; /* just continue in our loop for the timeout duration */ + + default: /* for clarity */ + break; + } + } + result = ftp_readresp(sockfd, pp, ftpcode, &nread); + if(result) + break; + + if(!nread && pp->cache) + /* bump cache skip counter as on repeated skips we must wait for more + data */ + cache_skip++; + else + /* when we got data or there is no cache left, we reset the cache skip + counter */ + cache_skip = 0; + + *nreadp += nread; + + } /* while there's buffer left and loop is requested */ + + pp->pending_resp = FALSE; + + return result; +} + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ +static const char * const ftp_state_names[]={ + "STOP", + "WAIT220", + "AUTH", + "USER", + "PASS", + "ACCT", + "PBSZ", + "PROT", + "CCC", + "PWD", + "SYST", + "NAMEFMT", + "QUOTE", + "RETR_PREQUOTE", + "STOR_PREQUOTE", + "POSTQUOTE", + "CWD", + "MKD", + "MDTM", + "TYPE", + "LIST_TYPE", + "RETR_TYPE", + "STOR_TYPE", + "SIZE", + "RETR_SIZE", + "STOR_SIZE", + "REST", + "RETR_REST", + "PORT", + "PRET", + "PASV", + "LIST", + "RETR", + "STOR", + "QUIT" +}; +#endif + +/* This is the ONLY way to change FTP state! */ +static void _state(struct connectdata *conn, + ftpstate newstate +#ifdef DEBUGBUILD + , int lineno +#endif + ) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + +#if defined(DEBUGBUILD) + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) lineno; +#else + if(ftpc->state != newstate) + infof(conn->data, "FTP %p (line %d) state change from %s to %s\n", + (void *)ftpc, lineno, ftp_state_names[ftpc->state], + ftp_state_names[newstate]); +#endif +#endif + + ftpc->state = newstate; +} + +static CURLcode ftp_state_user(struct connectdata *conn) +{ + CURLcode result; + struct FTP *ftp = conn->data->req.protop; + /* send USER */ + PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:""); + + state(conn, FTP_USER); + conn->data->state.ftp_trying_alternative = FALSE; + + return CURLE_OK; +} + +static CURLcode ftp_state_pwd(struct connectdata *conn) +{ + CURLcode result; + + /* send PWD to discover our entry point */ + PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD"); + state(conn, FTP_PWD); + + return CURLE_OK; +} + +/* For the FTP "protocol connect" and "doing" phases only */ +static int ftp_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); +} + +/* For the FTP "DO_MORE" phase only */ +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(!numsocks) + return GETSOCK_BLANK; + + /* When in DO_MORE state, we could be either waiting for us to connect to a + * remote site, or we could wait for that site to connect to us. Or just + * handle ordinary commands. + */ + + if(FTP_STOP == ftpc->state) { + int bits = GETSOCK_READSOCK(0); + + /* if stopped and still in this state, then we're also waiting for a + connect on the secondary connection */ + socks[0] = conn->sock[FIRSTSOCKET]; + + if(!conn->data->set.ftp_use_port) { + int s; + int i; + /* PORT is used to tell the server to connect to us, and during that we + don't do happy eyeballs, but we do if we connect to the server */ + for(s = 1, i = 0; i<2; i++) { + if(conn->tempsock[i] != CURL_SOCKET_BAD) { + socks[s] = conn->tempsock[i]; + bits |= GETSOCK_WRITESOCK(s++); + } + } + } + else { + socks[1] = conn->sock[SECONDARYSOCKET]; + bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1); + } + + return bits; + } + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); +} + +/* This is called after the FTP_QUOTE state is passed. + + ftp_state_cwd() sends the range of CWD commands to the server to change to + the correct directory. It may also need to send MKD commands to create + missing ones, if that option is enabled. +*/ +static CURLcode ftp_state_cwd(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(ftpc->cwddone) + /* already done and fine */ + result = ftp_state_mdtm(conn); + else { + ftpc->count2 = 0; /* count2 counts failed CWDs */ + + /* count3 is set to allow a MKD to fail once. In the case when first CWD + fails and then MKD fails (due to another session raced it to create the + dir) this then allows for a second try to CWD to it */ + ftpc->count3 = (conn->data->set.ftp_create_missing_dirs == 2)?1:0; + + if((conn->data->set.ftp_filemethod == FTPFILE_NOCWD) && !ftpc->cwdcount) + /* No CWD necessary */ + result = ftp_state_mdtm(conn); + else if(conn->bits.reuse && ftpc->entrypath) { + /* This is a re-used connection. Since we change directory to where the + transfer is taking place, we must first get back to the original dir + where we ended up after login: */ + ftpc->cwdcount = 0; /* we count this as the first path, then we add one + for all upcoming ones in the ftp->dirs[] array */ + PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath); + state(conn, FTP_CWD); + } + else { + if(ftpc->dirdepth) { + ftpc->cwdcount = 1; + /* issue the first CWD, the rest is sent when the CWD responses are + received... */ + PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]); + state(conn, FTP_CWD); + } + else { + /* No CWD necessary */ + result = ftp_state_mdtm(conn); + } + } + } + return result; +} + +typedef enum { + EPRT, + PORT, + DONE +} ftpport; + +static CURLcode ftp_state_use_port(struct connectdata *conn, + ftpport fcmd) /* start with this */ + +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct Curl_easy *data = conn->data; + curl_socket_t portsock = CURL_SOCKET_BAD; + char myhost[256] = ""; + + struct Curl_sockaddr_storage ss; + Curl_addrinfo *res, *ai; + curl_socklen_t sslen; + char hbuf[NI_MAXHOST]; + struct sockaddr *sa = (struct sockaddr *)&ss; + struct sockaddr_in * const sa4 = (void *)sa; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 * const sa6 = (void *)sa; +#endif + char tmp[1024]; + static const char mode[][5] = { "EPRT", "PORT" }; + int rc; + int error; + char *host = NULL; + char *string_ftpport = data->set.str[STRING_FTPPORT]; + struct Curl_dns_entry *h = NULL; + unsigned short port_min = 0; + unsigned short port_max = 0; + unsigned short port; + bool possibly_non_local = TRUE; + + char *addr = NULL; + + /* Step 1, figure out what is requested, + * accepted format : + * (ipv4|ipv6|domain|interface)?(:port(-range)?)? + */ + + if(data->set.str[STRING_FTPPORT] && + (strlen(data->set.str[STRING_FTPPORT]) > 1)) { + +#ifdef ENABLE_IPV6 + size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ? + INET6_ADDRSTRLEN : strlen(string_ftpport); +#else + size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ? + INET_ADDRSTRLEN : strlen(string_ftpport); +#endif + char *ip_start = string_ftpport; + char *ip_end = NULL; + char *port_start = NULL; + char *port_sep = NULL; + + addr = calloc(addrlen + 1, 1); + if(!addr) + return CURLE_OUT_OF_MEMORY; + +#ifdef ENABLE_IPV6 + if(*string_ftpport == '[') { + /* [ipv6]:port(-range) */ + ip_start = string_ftpport + 1; + ip_end = strchr(string_ftpport, ']'); + if(ip_end) + strncpy(addr, ip_start, ip_end - ip_start); + } + else +#endif + if(*string_ftpport == ':') { + /* :port */ + ip_end = string_ftpport; + } + else { + ip_end = strchr(string_ftpport, ':'); + if(ip_end) { + /* either ipv6 or (ipv4|domain|interface):port(-range) */ +#ifdef ENABLE_IPV6 + if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) { + /* ipv6 */ + port_min = port_max = 0; + strcpy(addr, string_ftpport); + ip_end = NULL; /* this got no port ! */ + } + else +#endif + /* (ipv4|domain|interface):port(-range) */ + strncpy(addr, string_ftpport, ip_end - ip_start); + } + else + /* ipv4|interface */ + strcpy(addr, string_ftpport); + } + + /* parse the port */ + if(ip_end != NULL) { + port_start = strchr(ip_end, ':'); + if(port_start) { + port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10)); + port_sep = strchr(port_start, '-'); + if(port_sep) { + port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10)); + } + else + port_max = port_min; + } + } + + /* correct errors like: + * :1234-1230 + * :-4711, in this case port_min is (unsigned)-1, + * therefore port_min > port_max for all cases + * but port_max = (unsigned)-1 + */ + if(port_min > port_max) + port_min = port_max = 0; + + + if(*addr != '\0') { + /* attempt to get the address of the given interface name */ + switch(Curl_if2ip(conn->ip_addr->ai_family, + Curl_ipv6_scope(conn->ip_addr->ai_addr), + conn->scope_id, addr, hbuf, sizeof(hbuf))) { + case IF2IP_NOT_FOUND: + /* not an interface, use the given string as host name instead */ + host = addr; + break; + case IF2IP_AF_NOT_SUPPORTED: + return CURLE_FTP_PORT_FAILED; + case IF2IP_FOUND: + host = hbuf; /* use the hbuf for host name */ + } + } + else + /* there was only a port(-range) given, default the host */ + host = NULL; + } /* data->set.ftpport */ + + if(!host) { + /* not an interface and not a host name, get default by extracting + the IP from the control connection */ + + sslen = sizeof(ss); + if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(conn, SOCKERRNO) ); + free(addr); + return CURLE_FTP_PORT_FAILED; + } + switch(sa->sa_family) { +#ifdef ENABLE_IPV6 + case AF_INET6: + Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf)); + break; +#endif + default: + Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf)); + break; + } + host = hbuf; /* use this host name */ + possibly_non_local = FALSE; /* we know it is local now */ + } + + /* resolv ip/host to ip */ + rc = Curl_resolv(conn, host, 0, &h); + if(rc == CURLRESOLV_PENDING) + (void)Curl_resolver_wait_resolv(conn, &h); + if(h) { + res = h->addr; + /* when we return from this function, we can forget about this entry + to we can unlock it now already */ + Curl_resolv_unlock(data, h); + } /* (h) */ + else + res = NULL; /* failure! */ + + if(res == NULL) { + failf(data, "failed to resolve the address provided to PORT: %s", host); + free(addr); + return CURLE_FTP_PORT_FAILED; + } + + free(addr); + host = NULL; + + /* step 2, create a socket for the requested address */ + + portsock = CURL_SOCKET_BAD; + error = 0; + for(ai = res; ai; ai = ai->ai_next) { + result = Curl_socket(conn, ai, NULL, &portsock); + if(result) { + error = SOCKERRNO; + continue; + } + break; + } + if(!ai) { + failf(data, "socket failure: %s", Curl_strerror(conn, error)); + return CURLE_FTP_PORT_FAILED; + } + + /* step 3, bind to a suitable local address */ + + memcpy(sa, ai->ai_addr, ai->ai_addrlen); + sslen = ai->ai_addrlen; + + for(port = port_min; port <= port_max;) { + if(sa->sa_family == AF_INET) + sa4->sin_port = htons(port); +#ifdef ENABLE_IPV6 + else + sa6->sin6_port = htons(port); +#endif + /* Try binding the given address. */ + if(bind(portsock, sa, sslen) ) { + /* It failed. */ + error = SOCKERRNO; + if(possibly_non_local && (error == EADDRNOTAVAIL)) { + /* The requested bind address is not local. Use the address used for + * the control connection instead and restart the port loop + */ + + infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, + Curl_strerror(conn, error) ); + + sslen = sizeof(ss); + if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(conn, SOCKERRNO) ); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + port = port_min; + possibly_non_local = FALSE; /* don't try this again */ + continue; + } + if(error != EADDRINUSE && error != EACCES) { + failf(data, "bind(port=%hu) failed: %s", port, + Curl_strerror(conn, error) ); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + } + else + break; + + port++; + } + + /* maybe all ports were in use already*/ + if(port > port_max) { + failf(data, "bind() failed, we ran out of ports!"); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* get the name again after the bind() so that we can extract the + port number it uses now */ + sslen = sizeof(ss); + if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(conn, SOCKERRNO) ); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* step 4, listen on the socket */ + + if(listen(portsock, 1)) { + failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO)); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* step 5, send the proper FTP command */ + + /* get a plain printable version of the numerical address to work with + below */ + Curl_printable_address(ai, myhost, sizeof(myhost)); + +#ifdef ENABLE_IPV6 + if(!conn->bits.ftp_use_eprt && conn->bits.ipv6) + /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the + request and enable EPRT again! */ + conn->bits.ftp_use_eprt = TRUE; +#endif + + for(; fcmd != DONE; fcmd++) { + + if(!conn->bits.ftp_use_eprt && (EPRT == fcmd)) + /* if disabled, goto next */ + continue; + + if((PORT == fcmd) && sa->sa_family != AF_INET) + /* PORT is IPv4 only */ + continue; + + switch(sa->sa_family) { + case AF_INET: + port = ntohs(sa4->sin_port); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + port = ntohs(sa6->sin6_port); + break; +#endif + default: + continue; /* might as well skip this */ + } + + if(EPRT == fcmd) { + /* + * Two fine examples from RFC2428; + * + * EPRT |1|132.235.1.2|6275| + * + * EPRT |2|1080::8:800:200C:417A|5282| + */ + + result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd], + sa->sa_family == AF_INET?1:2, + myhost, port); + if(result) { + failf(data, "Failure sending EPRT command: %s", + curl_easy_strerror(result)); + Curl_closesocket(conn, portsock); + /* don't retry using PORT */ + ftpc->count1 = PORT; + /* bail out */ + state(conn, FTP_STOP); + return result; + } + break; + } + if(PORT == fcmd) { + char *source = myhost; + char *dest = tmp; + + /* translate x.x.x.x to x,x,x,x */ + while(source && *source) { + if(*source == '.') + *dest = ','; + else + *dest = *source; + dest++; + source++; + } + *dest = 0; + snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff)); + + result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp); + if(result) { + failf(data, "Failure sending PORT command: %s", + curl_easy_strerror(result)); + Curl_closesocket(conn, portsock); + /* bail out */ + state(conn, FTP_STOP); + return result; + } + break; + } + } + + /* store which command was sent */ + ftpc->count1 = fcmd; + + close_secondarysocket(conn); + + /* we set the secondary socket variable to this for now, it is only so that + the cleanup function will close it in case we fail before the true + secondary stuff is made */ + conn->sock[SECONDARYSOCKET] = portsock; + + /* this tcpconnect assignment below is a hackish work-around to make the + multi interface with active FTP work - as it will not wait for a + (passive) connect in Curl_is_connected(). + + The *proper* fix is to make sure that the active connection from the + server is done in a non-blocking way. Currently, it is still BLOCKING. + */ + conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE; + + state(conn, FTP_PORT); + return result; +} + +static CURLcode ftp_state_use_pasv(struct connectdata *conn) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = CURLE_OK; + /* + Here's the excecutive summary on what to do: + + PASV is RFC959, expect: + 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) + + LPSV is RFC1639, expect: + 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2) + + EPSV is RFC2428, expect: + 229 Entering Extended Passive Mode (|||port|) + + */ + + static const char mode[][5] = { "EPSV", "PASV" }; + int modeoff; + +#ifdef PF_INET6 + if(!conn->bits.ftp_use_epsv && conn->bits.ipv6) + /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the + request and enable EPSV again! */ + conn->bits.ftp_use_epsv = TRUE; +#endif + + modeoff = conn->bits.ftp_use_epsv?0:1; + + PPSENDF(&ftpc->pp, "%s", mode[modeoff]); + + ftpc->count1 = modeoff; + state(conn, FTP_PASV); + infof(conn->data, "Connect data stream passively\n"); + + return result; +} + +/* + * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc. + * + * REST is the last command in the chain of commands when a "head"-like + * request is made. Thus, if an actual transfer is to be made this is where we + * take off for real. + */ +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + + if(ftp->transfer != FTPTRANSFER_BODY) { + /* doesn't transfer any data */ + + /* still possibly do PRE QUOTE jobs */ + state(conn, FTP_RETR_PREQUOTE); + result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); + } + else if(data->set.ftp_use_port) { + /* We have chosen to use the PORT (or similar) command */ + result = ftp_state_use_port(conn, EPRT); + } + else { + /* We have chosen (this is default) to use the PASV (or similar) command */ + if(data->set.ftp_use_pret) { + /* The user has requested that we send a PRET command + to prepare the server for the upcoming PASV */ + if(!conn->proto.ftpc.file) { + PPSENDF(&conn->proto.ftpc.pp, "PRET %s", + data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST")); + } + else if(data->set.upload) { + PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); + } + else { + PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file); + } + state(conn, FTP_PRET); + } + else { + result = ftp_state_use_pasv(conn); + } + } + return result; +} + +static CURLcode ftp_state_rest(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) { + /* if a "head"-like request is being made (on a file) */ + + /* Determine if server can respond to REST command and therefore + whether it supports range */ + PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0); + + state(conn, FTP_REST); + } + else + result = ftp_state_prepare_transfer(conn); + + return result; +} + +static CURLcode ftp_state_size(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) { + /* if a "head"-like request is being made (on a file) */ + + /* we know ftpc->file is a valid pointer to a file name */ + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + + state(conn, FTP_SIZE); + } + else + result = ftp_state_rest(conn); + + return result; +} + +static CURLcode ftp_state_list(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; ++ struct FTP *ftp = data->req.protop; + + /* If this output is to be machine-parsed, the NLST command might be better + to use, since the LIST command output is not specified or standard in any + way. It has turned out that the NLST list output is not the same on all + servers either... */ + + /* + if FTPFILE_NOCWD was specified, we are currently in + the user's home directory, so we should add the path + as argument for the LIST / NLST / or custom command. + Whether the server will support this, is uncertain. + + The other ftp_filemethods will CWD into dir/dir/ first and + then just do LIST (in that case: nothing to do here) + */ + char *cmd, *lstArg, *slashPos; - const char *inpath = data->state.path; ++ const char *inpath = ftp->path; + + lstArg = NULL; + if((data->set.ftp_filemethod == FTPFILE_NOCWD) && + inpath && inpath[0] && strchr(inpath, '/')) { + size_t n = strlen(inpath); + + /* Check if path does not end with /, as then we cut off the file part */ + if(inpath[n - 1] != '/') { + /* chop off the file part if format is dir/dir/file */ + slashPos = strrchr(inpath, '/'); + n = slashPos - inpath; + } + result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE); + if(result) + return result; + } + + cmd = aprintf("%s%s%s", + data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST"), + lstArg? " ": "", + lstArg? lstArg: ""); + + if(!cmd) { + free(lstArg); + return CURLE_OUT_OF_MEMORY; + } + + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd); + + free(lstArg); + free(cmd); + + if(result) + return result; + + state(conn, FTP_LIST); + + return result; +} + +static CURLcode ftp_state_retr_prequote(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + /* We've sent the TYPE, now we must send the list of prequote strings */ + + result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); + + return result; +} + +static CURLcode ftp_state_stor_prequote(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + /* We've sent the TYPE, now we must send the list of prequote strings */ + + result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE); + + return result; +} + +static CURLcode ftp_state_type(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + /* If we have selected NOBODY and HEADER, it means that we only want file + information. Which in FTP can't be much more than the file size and + date. */ + if(data->set.opt_no_body && ftpc->file && + ftp_need_type(conn, data->set.prefer_ascii)) { + /* The SIZE command is _not_ RFC 959 specified, and therefore many servers + may not support it! It is however the only way we have to get a file's + size! */ + + ftp->transfer = FTPTRANSFER_INFO; + /* this means no actual transfer will be made */ + + /* Some servers return different sizes for different modes, and thus we + must set the proper type before we check the size */ + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE); + if(result) + return result; + } + else + result = ftp_state_size(conn); + + return result; +} + +/* This is called after the CWD commands have been done in the beginning of + the DO phase */ +static CURLcode ftp_state_mdtm(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + /* Requested time of file or time-depended transfer? */ + if((data->set.get_filetime || data->set.timecondition) && ftpc->file) { + + /* we have requested to get the modified-time of the file, this is a white + spot as the MDTM is not mentioned in RFC959 */ + PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file); + + state(conn, FTP_MDTM); + } + else + result = ftp_state_type(conn); + + return result; +} + + +/* This is called after the TYPE and possible quote commands have been sent */ +static CURLcode ftp_state_ul_setup(struct connectdata *conn, + bool sizechecked) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((data->state.resume_from && !sizechecked) || + ((data->state.resume_from > 0) && sizechecked)) { + /* we're about to continue the uploading of a file */ + /* 1. get already existing file's size. We use the SIZE command for this + which may not exist in the server! The SIZE command is not in + RFC959. */ + + /* 2. This used to set REST. But since we can do append, we + don't another ftp command. We just skip the source file + offset and then we APPEND the rest on the file instead */ + + /* 3. pass file-size number of bytes in the source file */ + /* 4. lower the infilesize counter */ + /* => transfer as usual */ + int seekerr = CURL_SEEKFUNC_OK; + + if(data->state.resume_from < 0) { + /* Got no given size to start from, figure it out */ + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + state(conn, FTP_STOR_SIZE); + return result; + } + + /* enable append */ + data->set.ftp_append = TRUE; + + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, readthisamountnow, + data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + return CURLE_FTP_COULDNT_USE_REST; + } + } while(passed < data->state.resume_from); + } + /* now, decrease the size of the read */ + if(data->state.infilesize>0) { + data->state.infilesize -= data->state.resume_from; + + if(data->state.infilesize <= 0) { + infof(data, "File already completely uploaded\n"); + + /* no data to transfer */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + + /* Set ->transfer so that we won't get any error in + * ftp_done() because we didn't transfer anything! */ + ftp->transfer = FTPTRANSFER_NONE; + + state(conn, FTP_STOP); + return CURLE_OK; + } + } + /* we've passed, proceed as normal */ + } /* resume_from */ + + PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s", + ftpc->file); + + state(conn, FTP_STOR); + + return result; +} + +static CURLcode ftp_state_quote(struct connectdata *conn, + bool init, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + bool quote = FALSE; + struct curl_slist *item; + + switch(instate) { + case FTP_QUOTE: + default: + item = data->set.quote; + break; + case FTP_RETR_PREQUOTE: + case FTP_STOR_PREQUOTE: + item = data->set.prequote; + break; + case FTP_POSTQUOTE: + item = data->set.postquote; + break; + } + + /* + * This state uses: + * 'count1' to iterate over the commands to send + * 'count2' to store whether to allow commands to fail + */ + + if(init) + ftpc->count1 = 0; + else + ftpc->count1++; + + if(item) { + int i = 0; + + /* Skip count1 items in the linked list */ + while((i< ftpc->count1) && item) { + item = item->next; + i++; + } + if(item) { + char *cmd = item->data; + if(cmd[0] == '*') { + cmd++; + ftpc->count2 = 1; /* the sent command is allowed to fail */ + } + else + ftpc->count2 = 0; /* failure means cancel operation */ + + PPSENDF(&ftpc->pp, "%s", cmd); + state(conn, instate); + quote = TRUE; + } + } + + if(!quote) { + /* No more quote to send, continue to ... */ + switch(instate) { + case FTP_QUOTE: + default: + result = ftp_state_cwd(conn); + break; + case FTP_RETR_PREQUOTE: + if(ftp->transfer != FTPTRANSFER_BODY) + state(conn, FTP_STOP); + else { + if(ftpc->known_filesize != -1) { + Curl_pgrsSetDownloadSize(data, ftpc->known_filesize); + result = ftp_state_retr(conn, ftpc->known_filesize); + } + else { + if(data->set.ignorecl) { + /* This code is to support download of growing files. It prevents + the state machine from requesting the file size from the + server. With an unknown file size the download continues until + the server terminates it, otherwise the client stops if the + received byte count exceeds the reported file size. Set option + CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/ + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + else { + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + state(conn, FTP_RETR_SIZE); + } + } + } + break; + case FTP_STOR_PREQUOTE: + result = ftp_state_ul_setup(conn, FALSE); + break; + case FTP_POSTQUOTE: + break; + } + } + + return result; +} + +/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV + problems */ +static CURLcode ftp_epsv_disable(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) { + /* We can't disable EPSV when doing IPv6, so this is instead a fail */ + failf(conn->data, "Failed EPSV attempt, exiting\n"); + return CURLE_WEIRD_SERVER_REPLY; + } + + infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n"); + /* disable it for next transfer */ + conn->bits.ftp_use_epsv = FALSE; + conn->data->state.errorbuf = FALSE; /* allow error message to get + rewritten */ + PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV"); + conn->proto.ftpc.count1++; + /* remain in/go to the FTP_PASV state */ + state(conn, FTP_PASV); + return result; +} + + +static char *control_address(struct connectdata *conn) +{ + /* Returns the control connection IP address. + If a proxy tunnel is used, returns the original host name instead, because + the effective control connection address is the proxy address, + not the ftp host. */ + if(conn->bits.tunnel_proxy || conn->bits.socksproxy) + return conn->host.name; + + return conn->ip_addr_str; +} + +static CURLcode ftp_state_pasv_resp(struct connectdata *conn, + int ftpcode) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result; + struct Curl_easy *data = conn->data; + struct Curl_dns_entry *addr = NULL; + int rc; + unsigned short connectport; /* the local port connect() should use! */ + char *str = &data->state.buffer[4]; /* start on the first letter */ + + /* if we come here again, make sure the former name is cleared */ + Curl_safefree(ftpc->newhost); + + if((ftpc->count1 == 0) && + (ftpcode == 229)) { + /* positive EPSV response */ + char *ptr = strchr(str, '('); + if(ptr) { + unsigned int num; + char separator[4]; + ptr++; + if(5 == sscanf(ptr, "%c%c%c%u%c", + &separator[0], + &separator[1], + &separator[2], + &num, + &separator[3])) { + const char sep1 = separator[0]; + int i; + + /* The four separators should be identical, or else this is an oddly + formatted reply and we bail out immediately. */ + for(i = 1; i<4; i++) { + if(separator[i] != sep1) { + ptr = NULL; /* set to NULL to signal error */ + break; + } + } + if(num > 0xffff) { + failf(data, "Illegal port number in EPSV reply"); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + if(ptr) { + ftpc->newport = (unsigned short)(num & 0xffff); + ftpc->newhost = strdup(control_address(conn)); + if(!ftpc->newhost) + return CURLE_OUT_OF_MEMORY; + } + } + else + ptr = NULL; + } + if(!ptr) { + failf(data, "Weirdly formatted EPSV reply"); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + } + else if((ftpc->count1 == 1) && + (ftpcode == 227)) { + /* positive PASV response */ + unsigned int ip[4]; + unsigned int port[2]; + + /* + * Scan for a sequence of six comma-separated numbers and use them as + * IP+port indicators. + * + * Found reply-strings include: + * "227 Entering Passive Mode (127,0,0,1,4,51)" + * "227 Data transfer will passively listen to 127,0,0,1,4,51" + * "227 Entering passive mode. 127,0,0,1,4,51" + */ + while(*str) { + if(6 == sscanf(str, "%u,%u,%u,%u,%u,%u", + &ip[0], &ip[1], &ip[2], &ip[3], + &port[0], &port[1])) + break; + str++; + } + + if(!*str || (ip[0] > 255) || (ip[1] > 255) || (ip[2] > 255) || + (ip[3] > 255) || (port[0] > 255) || (port[1] > 255) ) { + failf(data, "Couldn't interpret the 227-response"); + return CURLE_FTP_WEIRD_227_FORMAT; + } + + /* we got OK from server */ + if(data->set.ftp_skip_ip) { + /* told to ignore the remotely given IP but instead use the host we used + for the control connection */ + infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead\n", + ip[0], ip[1], ip[2], ip[3], + conn->host.name); + ftpc->newhost = strdup(control_address(conn)); + } + else + ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + + if(!ftpc->newhost) + return CURLE_OUT_OF_MEMORY; + + ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff); + } + else if(ftpc->count1 == 0) { + /* EPSV failed, move on to PASV */ + return ftp_epsv_disable(conn); + } + else { + failf(data, "Bad PASV/EPSV response: %03d", ftpcode); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + + if(conn->bits.proxy) { + /* + * This connection uses a proxy and we need to connect to the proxy again + * here. We don't want to rely on a former host lookup that might've + * expired now, instead we remake the lookup here and now! + */ + const char * const host_name = conn->bits.socksproxy ? + conn->socks_proxy.host.name : conn->http_proxy.host.name; + rc = Curl_resolv(conn, host_name, (int)conn->port, &addr); + if(rc == CURLRESOLV_PENDING) + /* BLOCKING, ignores the return code but 'addr' will be NULL in + case of failure */ + (void)Curl_resolver_wait_resolv(conn, &addr); + + connectport = + (unsigned short)conn->port; /* we connect to the proxy's port */ + + if(!addr) { + failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport); + return CURLE_COULDNT_RESOLVE_PROXY; + } + } + else { + /* normal, direct, ftp connection */ + rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr); + if(rc == CURLRESOLV_PENDING) + /* BLOCKING */ + (void)Curl_resolver_wait_resolv(conn, &addr); + + connectport = ftpc->newport; /* we connect to the remote port */ + + if(!addr) { + failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport); + return CURLE_FTP_CANT_GET_HOST; + } + } + + conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; + result = Curl_connecthost(conn, addr); + + if(result) { + Curl_resolv_unlock(data, addr); /* we're done using this address */ + if(ftpc->count1 == 0 && ftpcode == 229) + return ftp_epsv_disable(conn); + + return result; + } + + + /* + * When this is used from the multi interface, this might've returned with + * the 'connected' set to FALSE and thus we are now awaiting a non-blocking + * connect to connect. + */ + + if(data->set.verbose) + /* this just dumps information about this second connection */ + ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport); + + Curl_resolv_unlock(data, addr); /* we're done using this address */ + + Curl_safefree(conn->secondaryhostname); + conn->secondary_port = ftpc->newport; + conn->secondaryhostname = strdup(ftpc->newhost); + if(!conn->secondaryhostname) + return CURLE_OUT_OF_MEMORY; + + conn->bits.do_more = TRUE; + state(conn, FTP_STOP); /* this phase is completed */ + + return result; +} + +static CURLcode ftp_state_port_resp(struct connectdata *conn, + int ftpcode) +{ + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + ftpport fcmd = (ftpport)ftpc->count1; + CURLcode result = CURLE_OK; + + /* The FTP spec tells a positive response should have code 200. + Be more permissive here to tolerate deviant servers. */ + if(ftpcode / 100 != 2) { + /* the command failed */ + + if(EPRT == fcmd) { + infof(data, "disabling EPRT usage\n"); + conn->bits.ftp_use_eprt = FALSE; + } + fcmd++; + + if(fcmd == DONE) { + failf(data, "Failed to do PORT"); + result = CURLE_FTP_PORT_FAILED; + } + else + /* try next */ + result = ftp_state_use_port(conn, fcmd); + } + else { + infof(data, "Connect data stream actively\n"); + state(conn, FTP_STOP); /* end of DO phase */ + result = ftp_dophase_done(conn, FALSE); + } + + return result; +} + +static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, + int ftpcode) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + switch(ftpcode) { + case 213: + { + /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the + last .sss part is optional and means fractions of a second */ + int year, month, day, hour, minute, second; + if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d", + &year, &month, &day, &hour, &minute, &second)) { + /* we have a time, reformat it */ + char timebuf[24]; + time_t secs = time(NULL); + + snprintf(timebuf, sizeof(timebuf), + "%04d%02d%02d %02d:%02d:%02d GMT", + year, month, day, hour, minute, second); + /* now, convert this into a time() value: */ + data->info.filetime = curl_getdate(timebuf, &secs); + } + +#ifdef CURL_FTP_HTTPSTYLE_HEAD + /* If we asked for a time of the file and we actually got one as well, + we "emulate" a HTTP-style header in our output. */ + + if(data->set.opt_no_body && + ftpc->file && + data->set.get_filetime && + (data->info.filetime >= 0) ) { + char headerbuf[128]; + time_t filetime = data->info.filetime; + struct tm buffer; + const struct tm *tm = &buffer; + + result = Curl_gmtime(filetime, &buffer); + if(result) + return result; + + /* format: "Tue, 15 Nov 1994 12:45:26" */ + snprintf(headerbuf, sizeof(headerbuf), + "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0); + if(result) + return result; + } /* end of a ridiculous amount of conditionals */ +#endif + } + break; + default: + infof(data, "unsupported MDTM reply format\n"); + break; + case 550: /* "No such file or directory" */ + failf(data, "Given file does not exist"); + result = CURLE_FTP_COULDNT_RETR_FILE; + break; + } + + if(data->set.timecondition) { + if((data->info.filetime > 0) && (data->set.timevalue > 0)) { + switch(data->set.timecondition) { + case CURL_TIMECOND_IFMODSINCE: + default: + if(data->info.filetime <= data->set.timevalue) { + infof(data, "The requested document is not new enough\n"); + ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + data->info.timecond = TRUE; + state(conn, FTP_STOP); + return CURLE_OK; + } + break; + case CURL_TIMECOND_IFUNMODSINCE: + if(data->info.filetime > data->set.timevalue) { + infof(data, "The requested document is not old enough\n"); + ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + data->info.timecond = TRUE; + state(conn, FTP_STOP); + return CURLE_OK; + } + break; + } /* switch */ + } + else { + infof(data, "Skipping time comparison\n"); + } + } + + if(!result) + result = ftp_state_type(conn); + + return result; +} + +static CURLcode ftp_state_type_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + if(ftpcode/100 != 2) { + /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a + successful 'TYPE I'. While that is not as RFC959 says, it is still a + positive response code and we allow that. */ + failf(data, "Couldn't set desired mode"); + return CURLE_FTP_COULDNT_SET_TYPE; + } + if(ftpcode != 200) + infof(data, "Got a %03d response code instead of the assumed 200\n", + ftpcode); + + if(instate == FTP_TYPE) + result = ftp_state_size(conn); + else if(instate == FTP_LIST_TYPE) + result = ftp_state_list(conn); + else if(instate == FTP_RETR_TYPE) + result = ftp_state_retr_prequote(conn); + else if(instate == FTP_STOR_TYPE) + result = ftp_state_stor_prequote(conn); + + return result; +} + +static CURLcode ftp_state_retr(struct connectdata *conn, + curl_off_t filesize) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(data->set.max_filesize && (filesize > data->set.max_filesize)) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; + } + ftp->downloadsize = filesize; + + if(data->state.resume_from) { + /* We always (attempt to) get the size of downloads, so it is done before + this even when not doing resumes. */ + if(filesize == -1) { + infof(data, "ftp server doesn't support SIZE\n"); + /* We couldn't get the size and therefore we can't know if there really + is a part of the file left to get, although the server will just + close the connection when we start the connection so it won't cause + us any harm, just not make us exit as nicely. */ + } + else { + /* We got a file size report, so we check that there actually is a + part of the file left to get, or else we go home. */ + if(data->state.resume_from< 0) { + /* We're supposed to download the last abs(from) bytes */ + if(filesize < -data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* convert to size to download */ + ftp->downloadsize = -data->state.resume_from; + /* download from where? */ + data->state.resume_from = filesize - ftp->downloadsize; + } + else { + if(filesize < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* Now store the number of bytes we are expected to download */ + ftp->downloadsize = filesize-data->state.resume_from; + } + } + + if(ftp->downloadsize == 0) { + /* no data to transfer */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + infof(data, "File already completely downloaded\n"); + + /* Set ->transfer so that we won't get any error in ftp_done() + * because we didn't transfer the any file */ + ftp->transfer = FTPTRANSFER_NONE; + state(conn, FTP_STOP); + return CURLE_OK; + } + + /* Set resume file transfer offset */ + infof(data, "Instructs server to resume from offset %" + CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + + PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, + data->state.resume_from); + + state(conn, FTP_RETR_REST); + } + else { + /* no resume */ + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + + return result; +} + +static CURLcode ftp_state_size_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + curl_off_t filesize = -1; + char *buf = data->state.buffer; + + /* get the size from the ascii string: */ + if(ftpcode == 213) + /* ignores parsing errors, which will make the size remain unknown */ + (void)curlx_strtoofft(buf + 4, NULL, 0, &filesize); + + if(instate == FTP_SIZE) { +#ifdef CURL_FTP_HTTPSTYLE_HEAD + if(-1 != filesize) { + char clbuf[128]; + snprintf(clbuf, sizeof(clbuf), + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0); + if(result) + return result; + } +#endif + Curl_pgrsSetDownloadSize(data, filesize); + result = ftp_state_rest(conn); + } + else if(instate == FTP_RETR_SIZE) { + Curl_pgrsSetDownloadSize(data, filesize); + result = ftp_state_retr(conn, filesize); + } + else if(instate == FTP_STOR_SIZE) { + data->state.resume_from = filesize; + result = ftp_state_ul_setup(conn, TRUE); + } + + return result; +} + +static CURLcode ftp_state_rest_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + switch(instate) { + case FTP_REST: + default: +#ifdef CURL_FTP_HTTPSTYLE_HEAD + if(ftpcode == 350) { + char buffer[24]= { "Accept-ranges: bytes\r\n" }; + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0); + if(result) + return result; + } +#endif + result = ftp_state_prepare_transfer(conn); + break; + + case FTP_RETR_REST: + if(ftpcode != 350) { + failf(conn->data, "Couldn't use REST"); + result = CURLE_FTP_COULDNT_USE_REST; + } + else { + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + break; + } + + return result; +} + +static CURLcode ftp_state_stor_resp(struct connectdata *conn, + int ftpcode, ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + if(ftpcode >= 400) { + failf(data, "Failed FTP upload: %0d", ftpcode); + state(conn, FTP_STOP); + /* oops, we never close the sockets! */ + return CURLE_UPLOAD_FAILED; + } + + conn->proto.ftpc.state_saved = instate; + + /* PORT means we are now awaiting the server to connect to us. */ + if(data->set.ftp_use_port) { + bool connected; + + state(conn, FTP_STOP); /* no longer in STOR state */ + + result = AllowServerConnect(conn, &connected); + if(result) + return result; + + if(!connected) { + struct ftp_conn *ftpc = &conn->proto.ftpc; + infof(data, "Data conn was not available immediately\n"); + ftpc->wait_data_conn = TRUE; + } + + return CURLE_OK; + } + return InitiateTransfer(conn); +} + +/* for LIST and RETR responses */ +static CURLcode ftp_state_get_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + + if((ftpcode == 150) || (ftpcode == 125)) { + + /* + A; + 150 Opening BINARY mode data connection for /etc/passwd (2241 + bytes). (ok, the file is being transferred) + + B: + 150 Opening ASCII mode data connection for /bin/ls + + C: + 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes). + + D: + 150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes) + + E: + 125 Data connection already open; Transfer starting. */ + + curl_off_t size = -1; /* default unknown size */ + + + /* + * It appears that there are FTP-servers that return size 0 for files when + * SIZE is used on the file while being in BINARY mode. To work around + * that (stupid) behavior, we attempt to parse the RETR response even if + * the SIZE returned size zero. + * + * Debugging help from Salvatore Sorrentino on February 26, 2003. + */ + + if((instate != FTP_LIST) && + !data->set.prefer_ascii && + (ftp->downloadsize < 1)) { + /* + * It seems directory listings either don't show the size or very + * often uses size 0 anyway. ASCII transfers may very well turn out + * that the transferred amount of data is not the same as this line + * tells, why using this number in those cases only confuses us. + * + * Example D above makes this parsing a little tricky */ + char *bytes; + char *buf = data->state.buffer; + bytes = strstr(buf, " bytes"); + if(bytes) { + long in = (long)(--bytes-buf); + /* this is a hint there is size information in there! ;-) */ + while(--in) { + /* scan for the left parenthesis and break there */ + if('(' == *bytes) + break; + /* skip only digits */ + if(!ISDIGIT(*bytes)) { + bytes = NULL; + break; + } + /* one more estep backwards */ + bytes--; + } + /* if we have nothing but digits: */ + if(bytes++) { + /* get the number! */ + (void)curlx_strtoofft(bytes, NULL, 0, &size); + } + } + } + else if(ftp->downloadsize > -1) + size = ftp->downloadsize; + + if(size > data->req.maxdownload && data->req.maxdownload > 0) + size = data->req.size = data->req.maxdownload; + else if((instate != FTP_LIST) && (data->set.prefer_ascii)) + size = -1; /* kludge for servers that understate ASCII mode file size */ + + infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n", + data->req.maxdownload); + + if(instate != FTP_LIST) + infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n", + size); + + /* FTP download: */ + conn->proto.ftpc.state_saved = instate; + conn->proto.ftpc.retr_size_saved = size; + + if(data->set.ftp_use_port) { + bool connected; + + result = AllowServerConnect(conn, &connected); + if(result) + return result; + + if(!connected) { + struct ftp_conn *ftpc = &conn->proto.ftpc; + infof(data, "Data conn was not available immediately\n"); + state(conn, FTP_STOP); + ftpc->wait_data_conn = TRUE; + } + } + else + return InitiateTransfer(conn); + } + else { + if((instate == FTP_LIST) && (ftpcode == 450)) { + /* simply no matching files in the dir listing */ + ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */ + state(conn, FTP_STOP); /* this phase is over */ + } + else { + failf(data, "RETR response: %03d", ftpcode); + return instate == FTP_RETR && ftpcode == 550? + CURLE_REMOTE_FILE_NOT_FOUND: + CURLE_FTP_COULDNT_RETR_FILE; + } + } + + return result; +} + +/* after USER, PASS and ACCT */ +static CURLcode ftp_state_loggedin(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->ssl[FIRSTSOCKET].use) { + /* PBSZ = PROTECTION BUFFER SIZE. + + The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: + + Specifically, the PROT command MUST be preceded by a PBSZ + command and a PBSZ command MUST be preceded by a successful + security data exchange (the TLS negotiation in this case) + + ... (and on page 8): + + Thus the PBSZ command must still be issued, but must have a + parameter of '0' to indicate that no buffering is taking place + and the data connection should not be encapsulated. + */ + PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0); + state(conn, FTP_PBSZ); + } + else { + result = ftp_state_pwd(conn); + } + return result; +} + +/* for USER and PASS responses */ +static CURLcode ftp_state_user_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + (void)instate; /* no use for this yet */ + + /* some need password anyway, and others just return 2xx ignored */ + if((ftpcode == 331) && (ftpc->state == FTP_USER)) { + /* 331 Password required for ... + (the server requires to send the user's password too) */ + PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:""); + state(conn, FTP_PASS); + } + else if(ftpcode/100 == 2) { + /* 230 User ... logged in. + (the user logged in with or without password) */ + result = ftp_state_loggedin(conn); + } + else if(ftpcode == 332) { + if(data->set.str[STRING_FTP_ACCOUNT]) { + PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]); + state(conn, FTP_ACCT); + } + else { + failf(data, "ACCT requested but none available"); + result = CURLE_LOGIN_DENIED; + } + } + else { + /* All other response codes, like: + + 530 User ... access denied + (the server denies to log the specified user) */ + + if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && + !conn->data->state.ftp_trying_alternative) { + /* Ok, USER failed. Let's try the supplied command. */ + PPSENDF(&conn->proto.ftpc.pp, "%s", + conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); + conn->data->state.ftp_trying_alternative = TRUE; + state(conn, FTP_USER); + result = CURLE_OK; + } + else { + failf(data, "Access denied: %03d", ftpcode); + result = CURLE_LOGIN_DENIED; + } + } + return result; +} + +/* for ACCT response */ +static CURLcode ftp_state_acct_resp(struct connectdata *conn, + int ftpcode) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + if(ftpcode != 230) { + failf(data, "ACCT rejected by server: %03d", ftpcode); + result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */ + } + else + result = ftp_state_loggedin(conn); + + return result; +} + + +static CURLcode ftp_statemach_act(struct connectdata *conn) +{ + CURLcode result; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + int ftpcode; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + static const char ftpauth[][4] = { "SSL", "TLS" }; + size_t nread = 0; + + if(pp->sendleft) + return Curl_pp_flushsend(pp); + + result = ftp_readresp(sock, pp, &ftpcode, &nread); + if(result) + return result; + + if(ftpcode) { + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: + if(ftpcode == 230) + /* 230 User logged in - already! */ + return ftp_state_user_resp(conn, ftpcode, ftpc->state); + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); + return CURLE_WEIRD_SERVER_REPLY; + } + + /* We have received a 220 response fine, now we proceed. */ +#ifdef HAVE_GSSAPI + if(data->set.krb) { + /* If not anonymous login, try a secure login. Note that this + procedure is still BLOCKING. */ + + Curl_sec_request_prot(conn, "private"); + /* We set private first as default, in case the line below fails to + set a valid level */ + Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]); + + if(Curl_sec_login(conn)) + infof(data, "Logging in with password in cleartext!\n"); + else + infof(data, "Authentication successful\n"); + } +#endif + + if(data->set.use_ssl && + (!conn->ssl[FIRSTSOCKET].use || + (conn->bits.proxy_ssl_connected[FIRSTSOCKET] && + !conn->proxy_ssl[FIRSTSOCKET].use))) { + /* We don't have a SSL/TLS connection yet, but FTPS is + requested. Try a FTPS connection now */ + + ftpc->count3 = 0; + switch(data->set.ftpsslauth) { + case CURLFTPAUTH_DEFAULT: + case CURLFTPAUTH_SSL: + ftpc->count2 = 1; /* add one to get next */ + ftpc->count1 = 0; + break; + case CURLFTPAUTH_TLS: + ftpc->count2 = -1; /* subtract one to get next */ + ftpc->count1 = 1; + break; + default: + failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d", + (int)data->set.ftpsslauth); + return CURLE_UNKNOWN_OPTION; /* we don't know what to do */ + } + PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); + state(conn, FTP_AUTH); + } + else { + result = ftp_state_user(conn); + if(result) + return result; + } + + break; + + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, + * and does not require any security data, it must respond with + * reply code 234/334. + */ + + if((ftpcode == 234) || (ftpcode == 334)) { + /* Curl_ssl_connect is BLOCKING */ + result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(!result) { + conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */ + result = ftp_state_user(conn); + } + } + else if(ftpc->count3 < 1) { + ftpc->count3++; + ftpc->count1 += ftpc->count2; /* get next attempt */ + result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); + /* remain in this same state */ + } + else { + if(data->set.use_ssl > CURLUSESSL_TRY) + /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */ + result = CURLE_USE_SSL_FAILED; + else + /* ignore the failure and continue */ + result = ftp_state_user(conn); + } + + if(result) + return result; + break; + + case FTP_USER: + case FTP_PASS: + result = ftp_state_user_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_ACCT: + result = ftp_state_acct_resp(conn, ftpcode); + break; + + case FTP_PBSZ: + PPSENDF(&ftpc->pp, "PROT %c", + data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); + state(conn, FTP_PROT); + + break; + + case FTP_PROT: + if(ftpcode/100 == 2) + /* We have enabled SSL for the data connection! */ + conn->bits.ftp_use_data_ssl = + (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE; + /* FTP servers typically responds with 500 if they decide to reject + our 'P' request */ + else if(data->set.use_ssl > CURLUSESSL_CONTROL) + /* we failed and bails out */ + return CURLE_USE_SSL_FAILED; + + if(data->set.ftp_ccc) { + /* CCC - Clear Command Channel + */ + PPSENDF(&ftpc->pp, "%s", "CCC"); + state(conn, FTP_CCC); + } + else { + result = ftp_state_pwd(conn); + if(result) + return result; + } + break; + + case FTP_CCC: + if(ftpcode < 500) { + /* First shut down the SSL layer (note: this call will block) */ + result = Curl_ssl_shutdown(conn, FIRSTSOCKET); + + if(result) { + failf(conn->data, "Failed to clear the command channel (CCC)"); + return result; + } + } + + /* Then continue as normal */ + result = ftp_state_pwd(conn); + if(result) + return result; + break; + + case FTP_PWD: + if(ftpcode == 257) { + char *ptr = &data->state.buffer[4]; /* start on the first letter */ + const size_t buf_size = data->set.buffer_size; + char *dir; + bool entry_extracted = FALSE; + + dir = malloc(nread + 1); + if(!dir) + return CURLE_OUT_OF_MEMORY; + + /* Reply format is like + 257[rubbish]"" and the + RFC959 says + + The directory name can contain any character; embedded + double-quotes should be escaped by double-quotes (the + "quote-doubling" convention). + */ + + /* scan for the first double-quote for non-standard responses */ + while(ptr < &data->state.buffer[buf_size] + && *ptr != '\n' && *ptr != '\0' && *ptr != '"') + ptr++; + + if('\"' == *ptr) { + /* it started good */ + char *store; + ptr++; + for(store = dir; *ptr;) { + if('\"' == *ptr) { + if('\"' == ptr[1]) { + /* "quote-doubling" */ + *store = ptr[1]; + ptr++; + } + else { + /* end of path */ + entry_extracted = TRUE; + break; /* get out of this loop */ + } + } + else + *store = *ptr; + store++; + ptr++; + } + *store = '\0'; /* zero terminate */ + } + if(entry_extracted) { + /* If the path name does not look like an absolute path (i.e.: it + does not start with a '/'), we probably need some server-dependent + adjustments. For example, this is the case when connecting to + an OS400 FTP server: this server supports two name syntaxes, + the default one being incompatible with standard paths. In + addition, this server switches automatically to the regular path + syntax when one is encountered in a command: this results in + having an entrypath in the wrong syntax when later used in CWD. + The method used here is to check the server OS: we do it only + if the path name looks strange to minimize overhead on other + systems. */ + + if(!ftpc->server_os && dir[0] != '/') { + + result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST"); + if(result) { + free(dir); + return result; + } + Curl_safefree(ftpc->entrypath); + ftpc->entrypath = dir; /* remember this */ + infof(data, "Entry path is '%s'\n", ftpc->entrypath); + /* also save it where getinfo can access it: */ + data->state.most_recent_ftp_entrypath = ftpc->entrypath; + state(conn, FTP_SYST); + break; + } + + Curl_safefree(ftpc->entrypath); + ftpc->entrypath = dir; /* remember this */ + infof(data, "Entry path is '%s'\n", ftpc->entrypath); + /* also save it where getinfo can access it: */ + data->state.most_recent_ftp_entrypath = ftpc->entrypath; + } + else { + /* couldn't get the path */ + free(dir); + infof(data, "Failed to figure out path\n"); + } + } + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_SYST: + if(ftpcode == 215) { + char *ptr = &data->state.buffer[4]; /* start on the first letter */ + char *os; + char *store; + + os = malloc(nread + 1); + if(!os) + return CURLE_OUT_OF_MEMORY; + + /* Reply format is like + 215 + */ + while(*ptr == ' ') + ptr++; + for(store = os; *ptr && *ptr != ' ';) + *store++ = *ptr++; + *store = '\0'; /* zero terminate */ + + /* Check for special servers here. */ + + if(strcasecompare(os, "OS/400")) { + /* Force OS400 name format 1. */ + result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1"); + if(result) { + free(os); + return result; + } + /* remember target server OS */ + Curl_safefree(ftpc->server_os); + ftpc->server_os = os; + state(conn, FTP_NAMEFMT); + break; + } + /* Nothing special for the target server. */ + /* remember target server OS */ + Curl_safefree(ftpc->server_os); + ftpc->server_os = os; + } + else { + /* Cannot identify server OS. Continue anyway and cross fingers. */ + } + + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_NAMEFMT: + if(ftpcode == 250) { + /* Name format change successful: reload initial path. */ + ftp_state_pwd(conn); + break; + } + + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_QUOTE: + case FTP_POSTQUOTE: + case FTP_RETR_PREQUOTE: + case FTP_STOR_PREQUOTE: + if((ftpcode >= 400) && !ftpc->count2) { + /* failure response code, and not allowed to fail */ + failf(conn->data, "QUOT command failed with %03d", ftpcode); + return CURLE_QUOTE_ERROR; + } + result = ftp_state_quote(conn, FALSE, ftpc->state); + if(result) + return result; + + break; + + case FTP_CWD: + if(ftpcode/100 != 2) { + /* failure to CWD there */ + if(conn->data->set.ftp_create_missing_dirs && + ftpc->cwdcount && !ftpc->count2) { + /* try making it */ + ftpc->count2++; /* counter to prevent CWD-MKD loops */ + PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]); + state(conn, FTP_MKD); + } + else { + /* return failure */ + failf(data, "Server denied you to change to the given directory"); + ftpc->cwdfail = TRUE; /* don't remember this path as we failed + to enter it */ + return CURLE_REMOTE_ACCESS_DENIED; + } + } + else { + /* success */ + ftpc->count2 = 0; + if(++ftpc->cwdcount <= ftpc->dirdepth) { + /* send next CWD */ + PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); + } + else { + result = ftp_state_mdtm(conn); + if(result) + return result; + } + } + break; + + case FTP_MKD: + if((ftpcode/100 != 2) && !ftpc->count3--) { + /* failure to MKD the dir */ + failf(data, "Failed to MKD dir: %03d", ftpcode); + return CURLE_REMOTE_ACCESS_DENIED; + } + state(conn, FTP_CWD); + /* send CWD */ + PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); + break; + + case FTP_MDTM: + result = ftp_state_mdtm_resp(conn, ftpcode); + break; + + case FTP_TYPE: + case FTP_LIST_TYPE: + case FTP_RETR_TYPE: + case FTP_STOR_TYPE: + result = ftp_state_type_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_SIZE: + case FTP_RETR_SIZE: + case FTP_STOR_SIZE: + result = ftp_state_size_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_REST: + case FTP_RETR_REST: + result = ftp_state_rest_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_PRET: + if(ftpcode != 200) { + /* there only is this one standard OK return code. */ + failf(data, "PRET command not accepted: %03d", ftpcode); + return CURLE_FTP_PRET_FAILED; + } + result = ftp_state_use_pasv(conn); + break; + + case FTP_PASV: + result = ftp_state_pasv_resp(conn, ftpcode); + break; + + case FTP_PORT: + result = ftp_state_port_resp(conn, ftpcode); + break; + + case FTP_LIST: + case FTP_RETR: + result = ftp_state_get_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_STOR: + result = ftp_state_stor_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + state(conn, FTP_STOP); + break; + } + } /* if(ftpcode) */ + + return result; +} + + +/* called repeatedly until done from multi.c */ +static CURLcode ftp_multi_statemach(struct connectdata *conn, + bool *done) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE); + + /* Check for the state outside of the Curl_socket_check() return code checks + since at times we are in fact already in this state when this function + gets called. */ + *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE; + + return result; +} + +static CURLcode ftp_block_statemach(struct connectdata *conn) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + CURLcode result = CURLE_OK; + + while(ftpc->state != FTP_STOP) { + result = Curl_pp_statemach(pp, TRUE); + if(result) + break; + } + + return result; +} + +/* + * ftp_connect() should do everything that is to be considered a part of + * the connection phase. + * + * The variable 'done' points to will be TRUE if the protocol-layer connect + * phase is done when this function returns, or FALSE if not. + * + */ +static CURLcode ftp_connect(struct connectdata *conn, + bool *done) /* see description above */ +{ + CURLcode result; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + *done = FALSE; /* default to not done yet */ + + /* We always support persistent connections on ftp */ + connkeep(conn, "FTP default"); + + pp->response_time = RESP_TIMEOUT; /* set default response time-out */ + pp->statemach_act = ftp_statemach_act; + pp->endofresp = ftp_endofresp; + pp->conn = conn; + + if(conn->handler->flags & PROTOPT_SSL) { + /* BLOCKING */ + result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(result) + return result; + } + + Curl_pp_init(pp); /* init the generic pingpong data */ + + /* When we connect, we start in the state where we await the 220 + response */ + state(conn, FTP_WAIT220); + + result = ftp_multi_statemach(conn, done); + + return result; +} + +/*********************************************************************** + * + * ftp_done() + * + * The DONE function. This does what needs to be done after a single DO has + * performed. + * + * Input argument is already checked for validity. + */ +static CURLcode ftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + ssize_t nread; + int ftpcode; + CURLcode result = CURLE_OK; + char *path = NULL; - const char *path_to_use = data->state.path; + + if(!ftp) + return CURLE_OK; + + switch(status) { + case CURLE_BAD_DOWNLOAD_RESUME: + case CURLE_FTP_WEIRD_PASV_REPLY: + case CURLE_FTP_PORT_FAILED: + case CURLE_FTP_ACCEPT_FAILED: + case CURLE_FTP_ACCEPT_TIMEOUT: + case CURLE_FTP_COULDNT_SET_TYPE: + case CURLE_FTP_COULDNT_RETR_FILE: + case CURLE_PARTIAL_FILE: + case CURLE_UPLOAD_FAILED: + case CURLE_REMOTE_ACCESS_DENIED: + case CURLE_FILESIZE_EXCEEDED: + case CURLE_REMOTE_FILE_NOT_FOUND: + case CURLE_WRITE_ERROR: + /* the connection stays alive fine even though this happened */ + /* fall-through */ + case CURLE_OK: /* doesn't affect the control connection's status */ + if(!premature) + break; + + /* until we cope better with prematurely ended requests, let them + * fallback as if in complete failure */ + /* FALLTHROUGH */ + default: /* by default, an error means the control connection is + wedged and should not be used anymore */ + ftpc->ctl_valid = FALSE; + ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the + current path, as this connection is going */ + connclose(conn, "FTP ended with bad error code"); + result = status; /* use the already set error code */ + break; + } + + /* now store a copy of the directory we are in */ + free(ftpc->prevpath); + + if(data->state.wildcardmatch) { + if(data->set.chunk_end && ftpc->file) { + Curl_set_in_callback(data, true); + data->set.chunk_end(data->wildcard.customptr); + Curl_set_in_callback(data, false); + } + ftpc->known_filesize = -1; + } + + if(!result) + /* get the "raw" path */ - result = Curl_urldecode(data, path_to_use, 0, &path, NULL, TRUE); ++ result = Curl_urldecode(data, ftp->path, 0, &path, NULL, TRUE); + if(result) { + /* We can limp along anyway (and should try to since we may already be in + * the error path) */ + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "FTP: out of memory!"); /* mark for connection closure */ + ftpc->prevpath = NULL; /* no path remembering */ + } + else { + size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */ + size_t dlen = strlen(path)-flen; + if(!ftpc->cwdfail) { + ftpc->prevmethod = data->set.ftp_filemethod; + if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) { + ftpc->prevpath = path; + if(flen) + /* if 'path' is not the whole string */ + ftpc->prevpath[dlen] = 0; /* terminate */ + } + else { ++ free(path); + /* we never changed dir */ + ftpc->prevpath = strdup(""); - free(path); ++ if(!ftpc->prevpath) ++ return CURLE_OUT_OF_MEMORY; + } + if(ftpc->prevpath) + infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath); + } + else { + ftpc->prevpath = NULL; /* no path */ + free(path); + } + } + /* free the dir tree and file parts */ + freedirs(ftpc); + + /* shut down the socket to inform the server we're done */ + +#ifdef _WIN32_WCE + shutdown(conn->sock[SECONDARYSOCKET], 2); /* SD_BOTH */ +#endif + + if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) { + if(!result && ftpc->dont_check && data->req.maxdownload > 0) { + /* partial download completed */ + result = Curl_pp_sendf(pp, "%s", "ABOR"); + if(result) { + failf(data, "Failure sending ABOR command: %s", + curl_easy_strerror(result)); + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "ABOR command failed"); /* connection closure */ + } + } + + if(conn->ssl[SECONDARYSOCKET].use) { + /* The secondary socket is using SSL so we must close down that part + first before we close the socket for real */ + Curl_ssl_close(conn, SECONDARYSOCKET); + + /* Note that we keep "use" set to TRUE since that (next) connection is + still requested to use SSL */ + } + close_secondarysocket(conn); + } + + if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid && + pp->pending_resp && !premature) { + /* + * Let's see what the server says about the transfer we just performed, + * but lower the timeout as sometimes this connection has died while the + * data has been transferred. This happens when doing through NATs etc that + * abandon old silent connections. + */ + long old_time = pp->response_time; + + pp->response_time = 60*1000; /* give it only a minute for now */ + pp->response = Curl_now(); /* timeout relative now */ + + result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + + pp->response_time = old_time; /* set this back to previous value */ + + if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) { + failf(data, "control connection looks dead"); + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */ + } + + if(result) + return result; + + if(ftpc->dont_check && data->req.maxdownload > 0) { + /* we have just sent ABOR and there is no reliable way to check if it was + * successful or not; we have to close the connection now */ + infof(data, "partial download completed, closing connection\n"); + connclose(conn, "Partial download with no ability to check"); + return result; + } + + if(!ftpc->dont_check) { + /* 226 Transfer complete, 250 Requested file action okay, completed. */ + if((ftpcode != 226) && (ftpcode != 250)) { + failf(data, "server did not report OK, got %d", ftpcode); + result = CURLE_PARTIAL_FILE; + } + } + } + + if(result || premature) + /* the response code from the transfer showed an error already so no + use checking further */ + ; + else if(data->set.upload) { + if((-1 != data->state.infilesize) && + (data->state.infilesize != *ftp->bytecountp) && + !data->set.crlf && + (ftp->transfer == FTPTRANSFER_BODY)) { + failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T + " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", + *ftp->bytecountp, data->state.infilesize); + result = CURLE_PARTIAL_FILE; + } + } + else { + if((-1 != data->req.size) && + (data->req.size != *ftp->bytecountp) && +#ifdef CURL_DO_LINEEND_CONV + /* Most FTP servers don't adjust their file SIZE response for CRLFs, so + * we'll check to see if the discrepancy can be explained by the number + * of CRLFs we've changed to LFs. + */ + ((data->req.size + data->state.crlf_conversions) != + *ftp->bytecountp) && +#endif /* CURL_DO_LINEEND_CONV */ + (data->req.maxdownload != *ftp->bytecountp)) { + failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T + " bytes", *ftp->bytecountp); + result = CURLE_PARTIAL_FILE; + } + else if(!ftpc->dont_check && + !*ftp->bytecountp && + (data->req.size>0)) { + failf(data, "No data was received!"); + result = CURLE_FTP_COULDNT_RETR_FILE; + } + } + + /* clear these for next connection */ + ftp->transfer = FTPTRANSFER_BODY; + ftpc->dont_check = FALSE; + + /* Send any post-transfer QUOTE strings? */ + if(!status && !result && !premature && data->set.postquote) + result = ftp_sendquote(conn, data->set.postquote); - ++ Curl_safefree(ftp->pathalloc); + return result; +} + +/*********************************************************************** + * + * ftp_sendquote() + * + * Where a 'quote' means a list of custom commands to send to the server. + * The quote list is passed as an argument. + * + * BLOCKING + */ + +static +CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) +{ + struct curl_slist *item; + ssize_t nread; + int ftpcode; + CURLcode result; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + item = quote; + while(item) { + if(item->data) { + char *cmd = item->data; + bool acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal FTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + acceptfail = TRUE; + } + + PPSENDF(&conn->proto.ftpc.pp, "%s", cmd); + + pp->response = Curl_now(); /* timeout relative now */ + + result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + if(result) + return result; + + if(!acceptfail && (ftpcode >= 400)) { + failf(conn->data, "QUOT string not accepted: %s", cmd); + return CURLE_QUOTE_ERROR; + } + } + + item = item->next; + } + + return CURLE_OK; +} + +/*********************************************************************** + * + * ftp_need_type() + * + * Returns TRUE if we in the current situation should send TYPE + */ +static int ftp_need_type(struct connectdata *conn, + bool ascii_wanted) +{ + return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I'); +} + +/*********************************************************************** + * + * ftp_nb_type() + * + * Set TYPE. We only deal with ASCII or BINARY so this function + * sets one of them. + * If the transfer type is not sent, simulate on OK response in newstate + */ +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate newstate) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result; + char want = (char)(ascii?'A':'I'); + + if(ftpc->transfertype == want) { + state(conn, newstate); + return ftp_state_type_resp(conn, 200, newstate); + } + + PPSENDF(&ftpc->pp, "TYPE %c", want); + state(conn, newstate); + + /* keep track of our current transfer type */ + ftpc->transfertype = want; + return CURLE_OK; +} + +/*************************************************************************** + * + * ftp_pasv_verbose() + * + * This function only outputs some informationals about this second connection + * when we've issued a PASV command before and thus we have connected to a + * possibly new IP address. + * + */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void +ftp_pasv_verbose(struct connectdata *conn, + Curl_addrinfo *ai, + char *newhost, /* ascii version */ + int port) +{ + char buf[256]; + Curl_printable_address(ai, buf, sizeof(buf)); + infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port); +} +#endif + +/* + * ftp_do_more() + * + * This function shall be called when the second FTP (data) connection is + * connected. + * + * 'complete' can return 0 for incomplete, 1 for done and -1 for go back + * (which basically is only for when PASV is being sent to retry a failed + * EPSV). + */ + +static CURLcode ftp_do_more(struct connectdata *conn, int *completep) +{ + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = CURLE_OK; + bool connected = FALSE; + bool complete = FALSE; + + /* the ftp struct is inited in ftp_connect() */ + struct FTP *ftp = data->req.protop; + + /* if the second connection isn't done yet, wait for it */ + if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { + if(Curl_connect_ongoing(conn)) { + /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port + aren't used so we blank their arguments. TODO: make this nicer */ + result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0); + + return result; + } + + result = Curl_is_connected(conn, SECONDARYSOCKET, &connected); + + /* Ready to do more? */ + if(connected) { + DEBUGF(infof(data, "DO-MORE connected phase starts\n")); + } + else { + if(result && (ftpc->count1 == 0)) { + *completep = -1; /* go back to DOING please */ + /* this is a EPSV connect failing, try PASV instead */ + return ftp_epsv_disable(conn); + } + return result; + } + } + + result = Curl_proxy_connect(conn, SECONDARYSOCKET); + if(result) + return result; + + if(CONNECT_SECONDARYSOCKET_PROXY_SSL()) + return result; + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy && + Curl_connect_ongoing(conn)) + return result; + + + if(ftpc->state) { + /* already in a state so skip the initial commands. + They are only done to kickstart the do_more state */ + result = ftp_multi_statemach(conn, &complete); + + *completep = (int)complete; + + /* if we got an error or if we don't wait for a data connection return + immediately */ + if(result || (ftpc->wait_data_conn != TRUE)) + return result; + + if(ftpc->wait_data_conn) + /* if we reach the end of the FTP state machine here, *complete will be + TRUE but so is ftpc->wait_data_conn, which says we need to wait for + the data connection and therefore we're not actually complete */ + *completep = 0; + } + + if(ftp->transfer <= FTPTRANSFER_INFO) { + /* a transfer is about to take place, or if not a file name was given + so we'll do a SIZE on it later and then we need the right TYPE first */ + + if(ftpc->wait_data_conn == TRUE) { + bool serv_conned; + + result = ReceivedServerConnect(conn, &serv_conned); + if(result) + return result; /* Failed to accept data connection */ + + if(serv_conned) { + /* It looks data connection is established */ + result = AcceptServerConnect(conn); + ftpc->wait_data_conn = FALSE; + if(!result) + result = InitiateTransfer(conn); + + if(result) + return result; + + *completep = 1; /* this state is now complete when the server has + connected back to us */ + } + } + else if(data->set.upload) { + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE); + if(result) + return result; + + result = ftp_multi_statemach(conn, &complete); + if(ftpc->wait_data_conn) + /* if we reach the end of the FTP state machine here, *complete will be + TRUE but so is ftpc->wait_data_conn, which says we need to wait for + the data connection and therefore we're not actually complete */ + *completep = 0; + else + *completep = (int)complete; + } + else { + /* download */ + ftp->downloadsize = -1; /* unknown as of yet */ + + result = Curl_range(conn); + + if(result == CURLE_OK && data->req.maxdownload >= 0) { + /* Don't check for successful transfer */ + ftpc->dont_check = TRUE; + } + + if(result) + ; + else if(data->set.ftp_list_only || !ftpc->file) { + /* The specified path ends with a slash, and therefore we think this + is a directory that is requested, use LIST. But before that we + need to set ASCII transfer mode. */ + + /* But only if a body transfer was requested. */ + if(ftp->transfer == FTPTRANSFER_BODY) { + result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE); + if(result) + return result; + } + /* otherwise just fall through */ + } + else { + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE); + if(result) + return result; + } + + result = ftp_multi_statemach(conn, &complete); + *completep = (int)complete; + } + return result; + } + + if(!result && (ftp->transfer != FTPTRANSFER_BODY)) + /* no data to transfer. FIX: it feels like a kludge to have this here + too! */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + + if(!ftpc->wait_data_conn) { + /* no waiting for the data connection so this is now complete */ + *completep = 1; + DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result)); + } + + return result; +} + + + +/*********************************************************************** + * + * ftp_perform() + * + * This is the actual DO function for FTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode ftp_perform(struct connectdata *conn, + bool *connected, /* connect status after PASV / PORT */ + bool *dophase_done) +{ + /* this is FTP and no proxy */ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + if(conn->data->set.opt_no_body) { + /* requested no body means no transfer... */ + struct FTP *ftp = conn->data->req.protop; + ftp->transfer = FTPTRANSFER_INFO; + } + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + result = ftp_state_quote(conn, TRUE, FTP_QUOTE); + if(result) + return result; + + /* run the state-machine */ + result = ftp_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[SECONDARYSOCKET]; + + infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete1\n")); + } + + return result; +} + +static void wc_data_dtor(void *ptr) +{ + struct ftp_wc *ftpwc = ptr; + if(ftpwc && ftpwc->parser) + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); +} + +static CURLcode init_wc_data(struct connectdata *conn) +{ + char *last_slash; - char *path = conn->data->state.path; ++ struct FTP *ftp = conn->data->req.protop; ++ char *path = ftp->path; + struct WildcardData *wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + struct ftp_wc *ftpwc = NULL; + - last_slash = strrchr(conn->data->state.path, '/'); ++ last_slash = strrchr(ftp->path, '/'); + if(last_slash) { + last_slash++; + if(last_slash[0] == '\0') { + wildcard->state = CURLWC_CLEAN; + result = ftp_parse_url_path(conn); + return result; + } + wildcard->pattern = strdup(last_slash); + if(!wildcard->pattern) + return CURLE_OUT_OF_MEMORY; + last_slash[0] = '\0'; /* cut file from path */ + } + else { /* there is only 'wildcard pattern' or nothing */ + if(path[0]) { + wildcard->pattern = strdup(path); + if(!wildcard->pattern) + return CURLE_OUT_OF_MEMORY; + path[0] = '\0'; + } + else { /* only list */ + wildcard->state = CURLWC_CLEAN; + result = ftp_parse_url_path(conn); + return result; + } + } + + /* program continues only if URL is not ending with slash, allocate needed + resources for wildcard transfer */ + + /* allocate ftp protocol specific wildcard data */ + ftpwc = calloc(1, sizeof(struct ftp_wc)); + if(!ftpwc) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* INITIALIZE parselist structure */ + ftpwc->parser = Curl_ftp_parselist_data_alloc(); + if(!ftpwc->parser) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + wildcard->protdata = ftpwc; /* put it to the WildcardData tmp pointer */ + wildcard->dtor = wc_data_dtor; + + /* wildcard does not support NOCWD option (assert it?) */ + if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD) + conn->data->set.ftp_filemethod = FTPFILE_MULTICWD; + + /* try to parse ftp url */ + result = ftp_parse_url_path(conn); + if(result) { + goto fail; + } + - wildcard->path = strdup(conn->data->state.path); ++ wildcard->path = strdup(ftp->path); + if(!wildcard->path) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* backup old write_function */ + ftpwc->backup.write_function = conn->data->set.fwrite_func; + /* parsing write function */ + conn->data->set.fwrite_func = Curl_ftp_parselist; + /* backup old file descriptor */ + ftpwc->backup.file_descriptor = conn->data->set.out; + /* let the writefunc callback know what curl pointer is working with */ + conn->data->set.out = conn; + + infof(conn->data, "Wildcard - Parsing started\n"); + return CURLE_OK; + + fail: + if(ftpwc) { + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); + } + Curl_safefree(wildcard->pattern); + wildcard->dtor = ZERO_NULL; + wildcard->protdata = NULL; + return result; +} + +/* This is called recursively */ +static CURLcode wc_statemach(struct connectdata *conn) +{ + struct WildcardData * const wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + + switch(wildcard->state) { + case CURLWC_INIT: + result = init_wc_data(conn); + if(wildcard->state == CURLWC_CLEAN) + /* only listing! */ + break; + wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; + break; + + case CURLWC_MATCHING: { + /* In this state is LIST response successfully parsed, so lets restore + previous WRITEFUNCTION callback and WRITEDATA pointer */ + struct ftp_wc *ftpwc = wildcard->protdata; + conn->data->set.fwrite_func = ftpwc->backup.write_function; + conn->data->set.out = ftpwc->backup.file_descriptor; + ftpwc->backup.write_function = ZERO_NULL; + ftpwc->backup.file_descriptor = NULL; + wildcard->state = CURLWC_DOWNLOADING; + + if(Curl_ftp_parselist_geterror(ftpwc->parser)) { + /* error found in LIST parsing */ + wildcard->state = CURLWC_CLEAN; + return wc_statemach(conn); + } + if(wildcard->filelist.size == 0) { + /* no corresponding file */ + wildcard->state = CURLWC_CLEAN; + return CURLE_REMOTE_FILE_NOT_FOUND; + } + return wc_statemach(conn); + } + + case CURLWC_DOWNLOADING: { + /* filelist has at least one file, lets get first one */ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; ++ struct FTP *ftp = conn->data->req.protop; + + char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); + if(!tmp_path) + return CURLE_OUT_OF_MEMORY; + - /* switch default "state.pathbuffer" and tmp_path, good to see - ftp_parse_url_path function to understand this trick */ - Curl_safefree(conn->data->state.pathbuffer); - conn->data->state.pathbuffer = tmp_path; - conn->data->state.path = tmp_path; ++ /* switch default ftp->path and tmp_path */ ++ free(ftp->pathalloc); ++ ftp->pathalloc = ftp->path = tmp_path; + + infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); + if(conn->data->set.chunk_bgn) { + long userresponse; + Curl_set_in_callback(conn->data, true); + userresponse = conn->data->set.chunk_bgn( + finfo, wildcard->customptr, (int)wildcard->filelist.size); + Curl_set_in_callback(conn->data, false); + switch(userresponse) { + case CURL_CHUNK_BGN_FUNC_SKIP: + infof(conn->data, "Wildcard - \"%s\" skipped by user\n", + finfo->filename); + wildcard->state = CURLWC_SKIP; + return wc_statemach(conn); + case CURL_CHUNK_BGN_FUNC_FAIL: + return CURLE_CHUNK_FAILED; + } + } + + if(finfo->filetype != CURLFILETYPE_FILE) { + wildcard->state = CURLWC_SKIP; + return wc_statemach(conn); + } + + if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) + ftpc->known_filesize = finfo->size; + + result = ftp_parse_url_path(conn); + if(result) + return result; + + /* we don't need the Curl_fileinfo of first file anymore */ + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + + if(wildcard->filelist.size == 0) { /* remains only one file to down. */ + wildcard->state = CURLWC_CLEAN; + /* after that will be ftp_do called once again and no transfer + will be done because of CURLWC_CLEAN state */ + return CURLE_OK; + } + } break; + + case CURLWC_SKIP: { + if(conn->data->set.chunk_end) { + Curl_set_in_callback(conn->data, true); + conn->data->set.chunk_end(conn->data->wildcard.customptr); + Curl_set_in_callback(conn->data, false); + } + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + wildcard->state = (wildcard->filelist.size == 0) ? + CURLWC_CLEAN : CURLWC_DOWNLOADING; + return wc_statemach(conn); + } + + case CURLWC_CLEAN: { + struct ftp_wc *ftpwc = wildcard->protdata; + result = CURLE_OK; + if(ftpwc) + result = Curl_ftp_parselist_geterror(ftpwc->parser); + + wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; + } break; + + case CURLWC_DONE: + case CURLWC_ERROR: + case CURLWC_CLEAR: + if(wildcard->dtor) + wildcard->dtor(wildcard->protdata); + break; + } + + return result; +} + +/*********************************************************************** + * + * ftp_do() + * + * This function is registered as 'curl_do' function. It decodes the path + * parts etc as a wrapper to the actual DO function (ftp_perform). + * + * The input argument is already checked for validity. + */ +static CURLcode ftp_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + *done = FALSE; /* default to false */ + ftpc->wait_data_conn = FALSE; /* default to no such wait */ + + if(conn->data->state.wildcardmatch) { + result = wc_statemach(conn); + if(conn->data->wildcard.state == CURLWC_SKIP || + conn->data->wildcard.state == CURLWC_DONE) { + /* do not call ftp_regular_transfer */ + return CURLE_OK; + } + if(result) /* error, loop or skipping the file */ + return result; + } + else { /* no wildcard FSM needed */ + result = ftp_parse_url_path(conn); + if(result) + return result; + } + + result = ftp_regular_transfer(conn, done); + + return result; +} + + +CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd) +{ + ssize_t bytes_written; +#define SBUF_SIZE 1024 + char s[SBUF_SIZE]; + size_t write_len; + char *sptr = s; + CURLcode result = CURLE_OK; +#ifdef HAVE_GSSAPI + enum protection_level data_sec = conn->data_prot; +#endif + ++ if(!cmd) ++ return CURLE_BAD_FUNCTION_ARGUMENT; ++ + write_len = strlen(cmd); - if(write_len > (sizeof(s) -3)) ++ if(!write_len || write_len > (sizeof(s) -3)) + return CURLE_BAD_FUNCTION_ARGUMENT; + ++ memcpy(&s, cmd, write_len); + strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ + write_len += 2; + bytes_written = 0; + + result = Curl_convert_to_network(conn->data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + + for(;;) { +#ifdef HAVE_GSSAPI + conn->data_prot = PROT_CMD; +#endif + result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, + &bytes_written); +#ifdef HAVE_GSSAPI + DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); + conn->data_prot = data_sec; +#endif + + if(result) + break; + + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written); + + if(bytes_written != (ssize_t)write_len) { + write_len -= bytes_written; + sptr += bytes_written; + } + else + break; + } + + return result; +} + +/*********************************************************************** + * + * ftp_quit() + * + * This should be called before calling sclose() on an ftp control connection + * (not data connections). We should then wait for the response from the + * server before returning. The calling code should then try to close the + * connection. + * + */ +static CURLcode ftp_quit(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->proto.ftpc.ctl_valid) { + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT"); + if(result) { + failf(conn->data, "Failure sending QUIT command: %s", + curl_easy_strerror(result)); + conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "QUIT command failed"); /* mark for connection closure */ + state(conn, FTP_STOP); + return result; + } + + state(conn, FTP_QUIT); + + result = ftp_block_statemach(conn); + } + + return result; +} + +/*********************************************************************** + * + * ftp_disconnect() + * + * Disconnect from an FTP server. Cleanup protocol-specific per-connection + * resources. BLOCKING. + */ +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. + + ftp_quit() will check the state of ftp->ctl_valid. If it's ok it + will try to send the QUIT command, otherwise it will just return. + */ + if(dead_connection) + ftpc->ctl_valid = FALSE; + + /* The FTP session may or may not have been allocated/setup at this point! */ + (void)ftp_quit(conn); /* ignore errors on the QUIT */ + + if(ftpc->entrypath) { + struct Curl_easy *data = conn->data; + if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { + data->state.most_recent_ftp_entrypath = NULL; + } + free(ftpc->entrypath); + ftpc->entrypath = NULL; + } + + freedirs(ftpc); + free(ftpc->prevpath); + ftpc->prevpath = NULL; + free(ftpc->server_os); + ftpc->server_os = NULL; + + Curl_pp_disconnect(pp); + +#ifdef HAVE_GSSAPI + Curl_sec_end(conn); +#endif + + return CURLE_OK; +} + +/*********************************************************************** + * + * ftp_parse_url_path() + * + * Parse the URL path into separate path components. + * + */ +static +CURLcode ftp_parse_url_path(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + /* the ftp struct is already inited in ftp_connect() */ + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + const char *slash_pos; /* position of the first '/' char in curpos */ - const char *path_to_use = data->state.path; ++ const char *path_to_use = ftp->path; + const char *cur_pos; + const char *filename = NULL; + + cur_pos = path_to_use; /* current position in path. point at the begin of + next path component */ + + ftpc->ctl_valid = FALSE; + ftpc->cwdfail = FALSE; + + switch(data->set.ftp_filemethod) { + case FTPFILE_NOCWD: + /* fastest, but less standard-compliant */ + + /* + The best time to check whether the path is a file or directory is right + here. so: + + the first condition in the if() right here, is there just in case + someone decides to set path to NULL one day + */ + if(path_to_use[0] && + (path_to_use[strlen(path_to_use) - 1] != '/') ) + filename = path_to_use; /* this is a full file path */ + /* + else { + ftpc->file is not used anywhere other than for operations on a file. + In other words, never for directory operations. + So we can safely leave filename as NULL here and use it as a + argument in dir/file decisions. + } + */ + break; + + case FTPFILE_SINGLECWD: + /* get the last slash */ + if(!path_to_use[0]) { + /* no dir, no file */ + ftpc->dirdepth = 0; + break; + } + slash_pos = strrchr(cur_pos, '/'); + if(slash_pos || !*cur_pos) { + size_t dirlen = slash_pos-cur_pos; + CURLcode result; + + ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0])); + if(!ftpc->dirs) + return CURLE_OUT_OF_MEMORY; + + if(!dirlen) + dirlen++; + + result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/", + slash_pos ? dirlen : 1, + &ftpc->dirs[0], NULL, + TRUE); + if(result) { + freedirs(ftpc); + return result; + } + ftpc->dirdepth = 1; /* we consider it to be a single dir */ + filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */ + } + else + filename = cur_pos; /* this is a file name only */ + break; + + default: /* allow pretty much anything */ + case FTPFILE_MULTICWD: + ftpc->dirdepth = 0; + ftpc->diralloc = 5; /* default dir depth to allocate */ + ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0])); + if(!ftpc->dirs) + return CURLE_OUT_OF_MEMORY; + + /* we have a special case for listing the root dir only */ + if(!strcmp(path_to_use, "/")) { + cur_pos++; /* make it point to the zero byte */ + ftpc->dirs[0] = strdup("/"); + ftpc->dirdepth++; + } + else { + /* parse the URL path into separate path components */ + while((slash_pos = strchr(cur_pos, '/')) != NULL) { + /* 1 or 0 pointer offset to indicate absolute directory */ - ssize_t absolute_dir = ((cur_pos - data->state.path > 0) && ++ ssize_t absolute_dir = ((cur_pos - ftp->path > 0) && + (ftpc->dirdepth == 0))?1:0; + + /* seek out the next path component */ + if(slash_pos-cur_pos) { + /* we skip empty path components, like "x//y" since the FTP command + CWD requires a parameter and a non-existent parameter a) doesn't + work on many servers and b) has no effect on the others. */ + size_t len = slash_pos - cur_pos + absolute_dir; + CURLcode result = + Curl_urldecode(conn->data, cur_pos - absolute_dir, len, + &ftpc->dirs[ftpc->dirdepth], NULL, + TRUE); + if(result) { + freedirs(ftpc); + return result; + } + } + else { + cur_pos = slash_pos + 1; /* jump to the rest of the string */ + if(!ftpc->dirdepth) { + /* path starts with a slash, add that as a directory */ + ftpc->dirs[ftpc->dirdepth] = strdup("/"); + if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */ + failf(data, "no memory"); + freedirs(ftpc); + return CURLE_OUT_OF_MEMORY; + } + } + continue; + } + + cur_pos = slash_pos + 1; /* jump to the rest of the string */ + if(++ftpc->dirdepth >= ftpc->diralloc) { + /* enlarge array */ + char **bigger; + ftpc->diralloc *= 2; /* double the size each time */ + bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0])); + if(!bigger) { + freedirs(ftpc); + return CURLE_OUT_OF_MEMORY; + } + ftpc->dirs = bigger; + } + } + } + filename = cur_pos; /* the rest is the file name */ + break; + } /* switch */ + + if(filename && *filename) { + CURLcode result = + Curl_urldecode(conn->data, filename, 0, &ftpc->file, NULL, TRUE); + + if(result) { + freedirs(ftpc); + return result; + } + } + else + ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL + pointer */ + + if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { + /* We need a file name when uploading. Return error! */ + failf(data, "Uploading to a URL without a file name!"); + return CURLE_URL_MALFORMAT; + } + + ftpc->cwddone = FALSE; /* default to not done */ + + if(ftpc->prevpath) { + /* prevpath is "raw" so we convert the input path before we compare the + strings */ + size_t dlen; + char *path; + CURLcode result = - Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, TRUE); ++ Curl_urldecode(conn->data, ftp->path, 0, &path, &dlen, TRUE); + if(result) { + freedirs(ftpc); + return result; + } + + dlen -= ftpc->file?strlen(ftpc->file):0; + if((dlen == strlen(ftpc->prevpath)) && + !strncmp(path, ftpc->prevpath, dlen) && + (ftpc->prevmethod == data->set.ftp_filemethod)) { + infof(data, "Request has same path as previous transfer\n"); + ftpc->cwddone = TRUE; + } + free(path); + } + + return CURLE_OK; +} + +/* call this when the DO phase has completed */ +static CURLcode ftp_dophase_done(struct connectdata *conn, + bool connected) +{ + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(connected) { + int completed; + CURLcode result = ftp_do_more(conn, &completed); + + if(result) { + close_secondarysocket(conn); + return result; + } + } + + if(ftp->transfer != FTPTRANSFER_BODY) + /* no data to transfer */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + else if(!connected) + /* since we didn't connect now, we want do_more to get called */ + conn->bits.do_more = TRUE; + + ftpc->ctl_valid = TRUE; /* seems good */ + + return CURLE_OK; +} + +/* called from multi.c while DOing */ +static CURLcode ftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = ftp_multi_statemach(conn, dophase_done); + + if(result) + DEBUGF(infof(conn->data, "DO phase failed\n")); + else if(*dophase_done) { + result = ftp_dophase_done(conn, FALSE /* not connected */); + + DEBUGF(infof(conn->data, "DO phase is complete2\n")); + } + return result; +} + +/*********************************************************************** + * + * ftp_regular_transfer() + * + * The input argument is already checked for validity. + * + * Performs all commands done before a regular transfer between a local and a + * remote host. + * + * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the + * ftp_done() function without finding any major problem. + */ +static +CURLcode ftp_regular_transfer(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + bool connected = FALSE; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + data->req.size = -1; /* make sure this is unknown at this point */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + ftpc->ctl_valid = TRUE; /* starts good */ + + result = ftp_perform(conn, + &connected, /* have we connected after PASV/PORT */ + dophase_done); /* all commands in the DO-phase done? */ + + if(!result) { + + if(!*dophase_done) + /* the DO phase has not completed yet */ + return CURLE_OK; + + result = ftp_dophase_done(conn, connected); + + if(result) + return result; + } + else + freedirs(ftpc); + + return result; +} + +static CURLcode ftp_setup_connection(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + char *type; + struct FTP *ftp; + - conn->data->req.protop = ftp = malloc(sizeof(struct FTP)); ++ conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1); + if(NULL == ftp) + return CURLE_OUT_OF_MEMORY; + - data->state.path++; /* don't include the initial slash */ ++ ftp->path = &data->state.up.path[1]; /* don't include the initial slash */ + data->state.slash_removed = TRUE; /* we've skipped the slash */ + + /* FTP URLs support an extension like ";type=" that + * we'll try to get now! */ - type = strstr(data->state.path, ";type="); ++ type = strstr(ftp->path, ";type="); + + if(!type) + type = strstr(conn->host.rawalloc, ";type="); + + if(type) { + char command; + *type = 0; /* it was in the middle of the hostname */ + command = Curl_raw_toupper(type[6]); + conn->bits.type_set = TRUE; + + switch(command) { + case 'A': /* ASCII mode */ + data->set.prefer_ascii = TRUE; + break; + + case 'D': /* directory mode */ + data->set.ftp_list_only = TRUE; + break; + + case 'I': /* binary mode */ + default: + /* switch off ASCII */ + data->set.prefer_ascii = FALSE; + break; + } + } + + /* get some initial data into the ftp struct */ + ftp->bytecountp = &conn->data->req.bytecount; + ftp->transfer = FTPTRANSFER_BODY; + ftp->downloadsize = 0; + + /* No need to duplicate user+password, the connectdata struct won't change + during a session, but we re-init them here since on subsequent inits + since the conn struct may have changed or been replaced. + */ + ftp->user = conn->user; + ftp->passwd = conn->passwd; + if(isBadFtpString(ftp->user)) + return CURLE_URL_MALFORMAT; + if(isBadFtpString(ftp->passwd)) + return CURLE_URL_MALFORMAT; + + conn->proto.ftpc.known_filesize = -1; /* unknown size for now */ + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_FTP */ diff --cc Utilities/cmcurl/lib/urlapi.c index 0000000,c53e523..c53e523 mode 000000,100644..100644 --- a/Utilities/cmcurl/lib/urlapi.c +++ b/Utilities/cmcurl/lib/urlapi.c diff --cc Utilities/cmcurl/lib/vtls/mesalink.c index 0000000,6a2b67e..6a2b67e mode 000000,100644..100644 --- a/Utilities/cmcurl/lib/vtls/mesalink.c +++ b/Utilities/cmcurl/lib/vtls/mesalink.c https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9835e9075037db3d23ade0ef865c562b08cf6023 commit 9835e9075037db3d23ade0ef865c562b08cf6023 Author: Curl Upstream AuthorDate: Tue Oct 30 17:54:00 2018 +0100 Commit: Brad King CommitDate: Wed Oct 31 09:41:28 2018 -0400 curl 2018-10-30 (19667715) Code extracted from: https://github.com/curl/curl.git at commit 196677150f711a96c38ed123e621f1d4e995b2e5 (curl-7_62_0). diff --git a/CMake/CMakeConfigurableFile.in b/CMake/CMakeConfigurableFile.in index 4cf74a1..df2c382 100644 --- a/CMake/CMakeConfigurableFile.in +++ b/CMake/CMakeConfigurableFile.in @@ -1,2 +1 @@ @CMAKE_CONFIGURABLE_FILE_CONTENT@ - diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c index ab244ac..9388c83 100644 --- a/CMake/CurlTests.c +++ b/CMake/CurlTests.c @@ -549,3 +549,19 @@ main() { return 0; } #endif +#ifdef HAVE_CLOCK_GETTIME_MONOTONIC +#include +int +main() { + struct timespec ts = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &ts); + return 0; +} +#endif +#ifdef HAVE_BUILTIN_AVAILABLE +int +main() { + if(__builtin_available(macOS 10.12, *)) {} + return 0; +} +#endif diff --git a/CMake/curl-config.cmake.in b/CMake/curl-config.cmake.in index 73e04c6..1294e17 100644 --- a/CMake/curl-config.cmake.in +++ b/CMake/curl-config.cmake.in @@ -1,64 +1,12 @@ - -get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - -if(NOT CURL_FIND_COMPONENTS) - set(CURL_FIND_COMPONENTS curl libcurl) - if(CURL_FIND_REQUIRED) - set(CURL_FIND_REQUIRED_curl TRUE) - set(CURL_FIND_REQUIRED_libcurl TRUE) - endif() -endif() + at PACKAGE_INIT@ include(CMakeFindDependencyMacro) -if(CURL_FIND_REQUIRED_libcurl) - find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@") +if(@USE_OPENSSL@) + find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@) endif() - -set(_curl_missing_components) -foreach(_comp ${CURL_FIND_COMPONENTS}) - if(EXISTS "${_DIR}/${_comp}-target.cmake") - include("${_DIR}/${_comp}-target.cmake") - set(CURL_${_comp}_FOUND TRUE) - else() - set(CURL_${_comp}_FOUND FALSE) - if(CURL_FIND_REQUIRED_${_comp}) - set(CURL_FOUND FALSE) - list(APPEND _curl_missing_components ${_comp}) - endif() - endif() -endforeach() - -if(_curl_missing_components) - set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components}) -else() - if(TARGET CURL::libcurl) - string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config) - if(NOT _curl_current_config) - set(_curl_current_config "NOCONFIG") - endif() - get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS) - list(FIND _curl_configurations "${_curl_current_config}" _i) - if(_i LESS 0) - set(_curl_config "RELEASE") - list(FIND _curl_configurations "${_curl_current_config}" _i) - if(_i LESS 0) - set(_curl_config "NOCONFIG") - list(FIND _curl_configurations "${_curl_current_config}" _i) - endif() - endif() - - if(_i LESS 0) - set(_curl_current_config "") # let CMake pick config at random - else() - set(_curl_current_config "_${_curl_current_config}") - endif() - - get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES) - get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}") - set(_curl_current_config) - set(_curl_configurations) - set(_i) - endif() +if(@USE_ZLIB@) + find_dependency(ZLIB @ZLIB_VERSION_MAJOR@) endif() -unset(_curl_missing_components) +include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME at .cmake") +check_required_components("@PROJECT_NAME@") diff --git a/CMakeLists.txt b/CMakeLists.txt index e6dbb73..a3c17c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ # To check: # (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not. # (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options. -cmake_minimum_required(VERSION 3.4 FATAL_ERROR) +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") include(Utilities) include(Macros) @@ -92,7 +92,7 @@ option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OF if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) if(PICKY_COMPILER) - foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers) + foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers -Wno-pedantic-ms-format) # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new # test result in. check_c_compiler_flag(${_CCOPT} OPT${_CCOPT}) @@ -352,7 +352,16 @@ if(CMAKE_USE_OPENSSL) set(USE_OPENSSL ON) set(HAVE_LIBCRYPTO ON) set(HAVE_LIBSSL ON) - list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto) + + # Depend on OpenSSL via imported targets if supported by the running + # version of CMake. This allows our dependents to get our dependencies + # transitively. + if(NOT CMAKE_VERSION VERSION_LESS 3.4) + list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto) + else() + list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) + include_directories(${OPENSSL_INCLUDE_DIR}) + endif() set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H) @@ -499,15 +508,23 @@ check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON) set(HAVE_LIBZ OFF) set(HAVE_ZLIB_H OFF) -set(HAVE_ZLIB OFF) +set(USE_ZLIB OFF) if(CURL_ZLIB) find_package(ZLIB QUIET) if(ZLIB_FOUND) set(HAVE_ZLIB_H ON) - set(HAVE_ZLIB ON) set(HAVE_LIBZ ON) - list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) - include_directories(${ZLIB_INCLUDE_DIRS}) + set(USE_ZLIB ON) + + # Depend on ZLIB via imported targets if supported by the running + # version of CMake. This allows our dependents to get our dependencies + # transitively. + if(NOT CMAKE_VERSION VERSION_LESS 3.4) + list(APPEND CURL_LIBS ZLIB::ZLIB) + else() + list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) + include_directories(${ZLIB_INCLUDE_DIRS}) + endif() list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) endif() endif() @@ -947,7 +964,6 @@ foreach(CURL_TEST HAVE_GETHOSTBYNAME_R_3_REENTRANT HAVE_GETHOSTBYNAME_R_5_REENTRANT HAVE_GETHOSTBYNAME_R_6_REENTRANT - HAVE_SOCKLEN_T HAVE_IN_ADDR_T HAVE_BOOL_T STDC_HEADERS @@ -1017,6 +1033,12 @@ if(HAVE_INET_NTOA_R_DECL_REENTRANT) set(NEED_REENTRANT 1) endif() +# Check clock_gettime(CLOCK_MONOTONIC, x) support +curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC) + +# Check compiler support of __builtin_available() +curl_internal_test(HAVE_BUILTIN_AVAILABLE) + # Some other minor tests if(NOT HAVE_IN_ADDR_T) @@ -1066,24 +1088,6 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE) endif() endif() -if(HAVE_SOCKLEN_T) - set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t") - if(WIN32) - set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h") - elseif(HAVE_SYS_SOCKET_H) - set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") - endif() - check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T) - set(CMAKE_EXTRA_INCLUDE_FILES) - if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T) - message(FATAL_ERROR - "Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log") - endif() -else() - set(CURL_TYPEOF_CURL_SOCKLEN_T int) - set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT}) -endif() - # TODO test which of these headers are required if(WIN32) set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H}) @@ -1144,11 +1148,13 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE) endfunction() -if(WIN32 AND NOT CYGWIN) - set(CURL_INSTALL_CMAKE_DIR CMake) -else() - set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl) -endif() +include(GNUInstallDirs) + +set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) +set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") +set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") +set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") +set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") if(USE_MANUAL) add_subdirectory(docs) @@ -1282,7 +1288,7 @@ set(VERSIONNUM "${CURL_VERSION_NUM}") configure_file("${CURL_SOURCE_DIR}/curl-config.in" "${CURL_BINARY_DIR}/curl-config" @ONLY) install(FILES "${CURL_BINARY_DIR}/curl-config" - DESTINATION bin + DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE @@ -1292,34 +1298,36 @@ install(FILES "${CURL_BINARY_DIR}/curl-config" configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) install(FILES "${CURL_BINARY_DIR}/libcurl.pc" - DESTINATION lib/pkgconfig) - -# This needs to be run very last so other parts of the scripts can take advantage of this. -if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE) - set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before") -endif() + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) # install headers install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" - DESTINATION include + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") - include(CMakePackageConfigHelpers) write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/curl-config-version.cmake" + "${version_config}" VERSION ${CURL_VERSION} COMPATIBILITY SameMajorVersion ) -configure_file(CMake/curl-config.cmake.in - "${PROJECT_BINARY_DIR}/curl-config.cmake" - @ONLY +# Use: +# * TARGETS_EXPORT_NAME +# * PROJECT_NAME +configure_package_config_file(CMake/curl-config.cmake.in + "${project_config}" + INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR} +) + +install( + EXPORT "${TARGETS_EXPORT_NAME}" + NAMESPACE "${PROJECT_NAME}::" + DESTINATION ${CURL_INSTALL_CMAKE_DIR} ) install( - FILES ${PROJECT_BINARY_DIR}/curl-config.cmake - ${PROJECT_BINARY_DIR}/curl-config-version.cmake + FILES ${version_config} ${project_config} DESTINATION ${CURL_INSTALL_CMAKE_DIR} ) diff --git a/include/curl/curl.h b/include/curl/curl.h index 067b34d..cf6f01d 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -146,7 +146,8 @@ typedef enum { CURLSSLBACKEND_SCHANNEL = 8, CURLSSLBACKEND_DARWINSSL = 9, CURLSSLBACKEND_AXTLS = 10, - CURLSSLBACKEND_MBEDTLS = 11 + CURLSSLBACKEND_MBEDTLS = 11, + CURLSSLBACKEND_MESALINK = 12 } curl_sslbackend; /* aliases for library clones and renames */ @@ -517,8 +518,7 @@ typedef enum { CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ + CURLE_OBSOLETE51, /* 51 - NOT USED */ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as @@ -528,7 +528,8 @@ typedef enum { CURLE_OBSOLETE57, /* 57 - NOT IN USE */ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint + wasn't verified fine */ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ @@ -584,6 +585,9 @@ typedef enum { CURL_LAST /* never use! */ } CURLcode; +/* added in 7.62.0 */ +#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION + #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all the obsolete stuff removed! */ @@ -800,6 +804,9 @@ typedef enum { this value, keep them in sync. */ #define CURL_HET_DEFAULT 200L +/* The default connection upkeep interval in milliseconds. */ +#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L + #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all the obsolete stuff removed! */ @@ -1856,6 +1863,15 @@ typedef enum { /* Disallow specifying username/login in URL. */ CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278), + /* DNS-over-HTTPS URL */ + CINIT(DOH_URL, STRINGPOINT, 279), + + /* Preferred buffer size to use for uploads */ + CINIT(UPLOAD_BUFFERSIZE, LONG, 280), + + /* Time in ms between connection upkeep calls for long-lived connections. */ + CINIT(UPKEEP_INTERVAL_MS, LONG, 281), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2779,6 +2795,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); stuff before they can be included! */ #include "easy.h" /* nothing in curl is fun without the easy stuff */ #include "multi.h" +#include "urlapi.h" /* the typechecker doesn't work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ diff --git a/include/curl/curlver.h b/include/curl/curlver.h index 12b2f9f..6c111da 100644 --- a/include/curl/curlver.h +++ b/include/curl/curlver.h @@ -30,13 +30,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.61.1-DEV" +#define LIBCURL_VERSION "7.62.0-DEV" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 61 -#define LIBCURL_VERSION_PATCH 1 +#define LIBCURL_VERSION_MINOR 62 +#define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparions by programs. The LIBCURL_VERSION_NUM define will @@ -57,7 +57,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x073D01 +#define LIBCURL_VERSION_NUM 0x073E00 /* * This is the date and time when the full source package was created. The diff --git a/include/curl/easy.h b/include/curl/easy.h index 752c504..f42a8a9 100644 --- a/include/curl/easy.h +++ b/include/curl/easy.h @@ -95,6 +95,16 @@ CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, size_t *n); + +/* + * NAME curl_easy_upkeep() + * + * DESCRIPTION + * + * Performs connection upkeep for the given session handle. + */ +CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); + #ifdef __cplusplus } #endif diff --git a/include/curl/system.h b/include/curl/system.h index a54fd58..1e555ec 100644 --- a/include/curl/system.h +++ b/include/curl/system.h @@ -298,7 +298,7 @@ # define CURL_PULL_SYS_TYPES_H 1 # define CURL_PULL_SYS_SOCKET_H 1 -#elif defined(__SUNPRO_C) /* Oracle Solaris Studio */ +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */ # if !defined(__LP64) && (defined(__ILP32) || \ defined(__i386) || \ defined(__sparcv8) || \ diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h index a6f6386..2443362 100644 --- a/include/curl/typecheck-gcc.h +++ b/include/curl/typecheck-gcc.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -269,6 +269,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, (option) == CURLOPT_DNS_LOCAL_IP4 || \ (option) == CURLOPT_DNS_LOCAL_IP6 || \ (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_DOH_URL || \ (option) == CURLOPT_EGDSOCKET || \ (option) == CURLOPT_FTPPORT || \ (option) == CURLOPT_FTP_ACCOUNT || \ @@ -500,7 +501,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, /* evaluates to true if expr can be passed as POST data (void* or char*) */ #define _curl_is_postfields(expr) \ (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) + _curl_is_arr((expr), char) || \ + _curl_is_arr((expr), unsigned char)) /* FIXME: the whole callback checking is messy... * The idea is to tolerate char vs. void and const vs. not const diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h new file mode 100644 index 0000000..90dd56c --- /dev/null +++ b/include/curl/urlapi.h @@ -0,0 +1,120 @@ +#ifndef __CURL_URLAPI_H +#define __CURL_URLAPI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* the error codes for the URL API */ +typedef enum { + CURLUE_OK, + CURLUE_BAD_HANDLE, /* 1 */ + CURLUE_BAD_PARTPOINTER, /* 2 */ + CURLUE_MALFORMED_INPUT, /* 3 */ + CURLUE_BAD_PORT_NUMBER, /* 4 */ + CURLUE_UNSUPPORTED_SCHEME, /* 5 */ + CURLUE_URLDECODE, /* 6 */ + CURLUE_OUT_OF_MEMORY, /* 7 */ + CURLUE_USER_NOT_ALLOWED, /* 8 */ + CURLUE_UNKNOWN_PART, /* 9 */ + CURLUE_NO_SCHEME, /* 10 */ + CURLUE_NO_USER, /* 11 */ + CURLUE_NO_PASSWORD, /* 12 */ + CURLUE_NO_OPTIONS, /* 13 */ + CURLUE_NO_HOST, /* 14 */ + CURLUE_NO_PORT, /* 15 */ + CURLUE_NO_QUERY, /* 16 */ + CURLUE_NO_FRAGMENT /* 17 */ +} CURLUcode; + +typedef enum { + CURLUPART_URL, + CURLUPART_SCHEME, + CURLUPART_USER, + CURLUPART_PASSWORD, + CURLUPART_OPTIONS, + CURLUPART_HOST, + CURLUPART_PORT, + CURLUPART_PATH, + CURLUPART_QUERY, + CURLUPART_FRAGMENT +} CURLUPart; + +#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ +#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, + if the port number matches the + default for the scheme */ +#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if + missing */ +#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ +#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ +#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ +#define CURLU_URLDECODE (1<<6) /* URL decode on get */ +#define CURLU_URLENCODE (1<<7) /* URL encode on set */ +#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ +#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ + +typedef struct Curl_URL CURLU; + +/* + * curl_url() creates a new CURLU handle and returns a pointer to it. + * Must be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url(void); + +/* + * curl_url_cleanup() frees the CURLU handle and related resources used for + * the URL parsing. It will not free strings previously returned with the URL + * API. + */ +CURL_EXTERN void curl_url_cleanup(CURLU *handle); + +/* + * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new + * handle must also be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url_dup(CURLU *in); + +/* + * curl_url_get() extracts a specific part of the URL from a CURLU + * handle. Returns error code. The returned pointer MUST be freed with + * curl_free() afterwards. + */ +CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what, + char **part, unsigned int flags); + +/* + * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns + * error code. The passed in string will be copied. Passing a NULL instead of + * a part string, clears that part. + */ +CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, + const char *part, unsigned int flags); + + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 87cbe81..eca9a8a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -105,23 +105,17 @@ if(WIN32) endif() target_include_directories(${LIB_NAME} INTERFACE - $) + $ + $) install(TARGETS ${LIB_NAME} - EXPORT libcurl-target - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin + EXPORT ${TARGETS_EXPORT_NAME} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) export(TARGETS ${LIB_NAME} APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake NAMESPACE CURL:: ) - -install(EXPORT libcurl-target - FILE libcurl-target.cmake - NAMESPACE CURL:: - DESTINATION ${CURL_INSTALL_CMAKE_DIR} -) - diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 76ca6d0..4aa0422 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -30,12 +30,12 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \ vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \ - vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c + vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \ vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \ - vtls/mbedtls.h + vtls/mbedtls.h vtls/mesalink.h LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ @@ -54,7 +54,8 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ - mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c + mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ + doh.c urlapi.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -74,7 +75,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ - curl_path.h curl_ctype.h curl_range.h psl.h + curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h LIB_RCFILES = libcurl.rc diff --git a/lib/amigaos.h b/lib/amigaos.h index 02bee16..7c0926c 100644 --- a/lib/amigaos.h +++ b/lib/amigaos.h @@ -36,4 +36,3 @@ void Curl_amiga_cleanup(); #endif #endif /* HEADER_CURL_AMIGAOS_H */ - diff --git a/lib/arpa_telnet.h b/lib/arpa_telnet.h index ec23872..232680e 100644 --- a/lib/arpa_telnet.h +++ b/lib/arpa_telnet.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -37,6 +37,7 @@ #define CURL_NEW_ENV_VAR 0 #define CURL_NEW_ENV_VALUE 1 +#ifndef CURL_DISABLE_VERBOSE_STRINGS /* * The telnet options represented as strings */ @@ -53,6 +54,7 @@ static const char * const telnetoptions[]= "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" }; +#endif #define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON @@ -76,6 +78,7 @@ static const char * const telnetoptions[]= #define CURL_DONT 254 /* DON'T use this option! */ #define CURL_IAC 255 /* Interpret As Command */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS /* * Then those numbers represented as strings: */ @@ -86,6 +89,7 @@ static const char * const telnetcmds[]= "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC" }; +#endif #define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */ #define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */ diff --git a/lib/cookie.c b/lib/cookie.c index da49c2a..a342c61 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -1218,7 +1218,6 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, { struct Cookie *newco; struct Cookie *co; - time_t now = time(NULL); struct Cookie *mainco = NULL; size_t matches = 0; bool is_ip; @@ -1236,11 +1235,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, co = c->cookies[myhash]; while(co) { - /* only process this cookie if it is not expired or had no expire - date AND that if the cookie requires we're secure we must only - continue if we are! */ - if((!co->expires || (co->expires > now)) && - (co->secure?secure:TRUE)) { + /* if the cookie requires we're secure we must only continue if we are! */ + if(co->secure?secure:TRUE) { /* now check if the domain is correct */ if(!co->domain || @@ -1266,12 +1262,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, matches++; } - else { - fail: - /* failure, clear up the allocated chain and return NULL */ - Curl_cookie_freelist(mainco); - return NULL; - } + else + goto fail; } } } @@ -1309,6 +1301,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, } return mainco; /* return the new list */ + +fail: + /* failure, clear up the allocated chain and return NULL */ + Curl_cookie_freelist(mainco); + return NULL; } /***************************************************************************** @@ -1508,10 +1505,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) format_ptr = get_netscape_format(array[i]); if(format_ptr == NULL) { fprintf(out, "#\n# Fatal libcurl error\n"); - if(!use_stdout) { - free(array); + free(array); + if(!use_stdout) fclose(out); - } return 1; } fprintf(out, "%s\n", format_ptr); diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index ab0094b..5308eb5 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -127,6 +127,9 @@ /* Define to 1 if bool is an available type. */ #cmakedefine HAVE_BOOL_T 1 +/* Define to 1 if you have the __builtin_available function. */ +#cmakedefine HAVE_BUILTIN_AVAILABLE 1 + /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 @@ -900,9 +903,6 @@ /* The size of `time_t', as computed by sizeof. */ #cmakedefine SIZEOF_TIME_T ${SIZEOF_TIME_T} -/* The size of `void*', as computed by sizeof. */ -#cmakedefine SIZEOF_VOIDP ${SIZEOF_VOIDP} - /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 diff --git a/lib/curl_ldap.h b/lib/curl_ldap.h index 27d0381..94c0029 100644 --- a/lib/curl_ldap.h +++ b/lib/curl_ldap.h @@ -32,4 +32,3 @@ extern const struct Curl_handler Curl_handler_ldaps; #endif #endif /* HEADER_CURL_LDAP_H */ - diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c index 353a656..a4791eb 100644 --- a/lib/curl_ntlm_wb.c +++ b/lib/curl_ntlm_wb.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -249,6 +249,9 @@ done: return CURLE_REMOTE_ACCESS_DENIED; } +/* if larger than this, something is seriously wrong */ +#define MAX_NTLM_WB_RESPONSE 100000 + static CURLcode ntlm_wb_response(struct connectdata *conn, const char *input, curlntlm state) { @@ -289,6 +292,13 @@ static CURLcode ntlm_wb_response(struct connectdata *conn, buf[len_out - 1] = '\0'; break; } + + if(len_out > MAX_NTLM_WB_RESPONSE) { + failf(conn->data, "too large ntlm_wb response!"); + free(buf); + return CURLE_OUT_OF_MEMORY; + } + newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE); if(!newbuf) return CURLE_OUT_OF_MEMORY; @@ -314,6 +324,8 @@ static CURLcode ntlm_wb_response(struct connectdata *conn, conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3); free(buf); + if(!conn->response_header) + return CURLE_OUT_OF_MEMORY; return CURLE_OK; done: free(buf); @@ -389,6 +401,8 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, conn->response_header); DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); free(conn->response_header); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; conn->response_header = NULL; break; case NTLMSTATE_TYPE2: @@ -409,6 +423,8 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ authp->done = TRUE; Curl_ntlm_wb_cleanup(conn); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; break; case NTLMSTATE_TYPE3: /* connection is already authenticated, diff --git a/lib/curl_path.c b/lib/curl_path.c index e843dea..68f3e44 100644 --- a/lib/curl_path.c +++ b/lib/curl_path.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,7 +39,7 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, char *working_path; size_t working_path_len; CURLcode result = - Curl_urldecode(data, data->state.path, 0, &working_path, + Curl_urldecode(data, data->state.up.path, 0, &working_path, &working_path_len, FALSE); if(result) return result; diff --git a/lib/curl_path.h b/lib/curl_path.h index 5ee4ff3..636c37f 100644 --- a/lib/curl_path.h +++ b/lib/curl_path.h @@ -44,4 +44,4 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, char **path); CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir); -#endif +#endif /* HEADER_CURL_PATH_H */ diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 9743064..f09f2f3 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -37,9 +37,11 @@ /* The last #include file should be: */ #include "memdebug.h" -#ifdef _WIN32 +#if defined(WIN32) && !defined(USE_LWIPSOCK) #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) #define SET_RCVTIMEO(tv,s) int tv = s*1000 +#elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) +#define SET_RCVTIMEO(tv,s) int tv = s*1000 #else #define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0} #endif diff --git a/lib/curl_setup.h b/lib/curl_setup.h index 2498987..b845015 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -44,6 +44,9 @@ # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif +# ifndef NOGDI +# define NOGDI +# endif #endif /* @@ -645,7 +648,7 @@ int netware_init(void); #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \ defined(USE_CYASSL) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_GSKIT) + defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK) #define USE_SSL /* SSL support has been enabled */ #endif diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h index 6d01ea1..413ccea 100644 --- a/lib/curl_setup_once.h +++ b/lib/curl_setup_once.h @@ -515,4 +515,3 @@ typedef int sig_atomic_t; #endif /* HEADER_CURL_SETUP_ONCE_H */ - diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 11a7120..1d0de4e 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -90,8 +90,9 @@ CURLcode Curl_sspi_global_init(void) return CURLE_FAILED_INIT; /* Get address of the InitSecurityInterfaceA function from the SSPI dll */ - pInitSecurityInterface = (INITSECURITYINTERFACE_FN) - GetProcAddress(s_hSecDll, SECURITYENTRYPOINT); + pInitSecurityInterface = + CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN, + (GetProcAddress(s_hSecDll, SECURITYENTRYPOINT))); if(!pInitSecurityInterface) return CURLE_FAILED_INIT; @@ -131,7 +132,7 @@ void Curl_sspi_global_cleanup(void) * Parameters: * * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * identity [in/out] - The identity structure. * * Returns CURLE_OK on success. diff --git a/lib/curl_threads.c b/lib/curl_threads.c index b8f0cd3..8e5937a 100644 --- a/lib/curl_threads.c +++ b/lib/curl_threads.c @@ -104,13 +104,21 @@ int Curl_thread_join(curl_thread_t *hnd) curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *), void *arg) { +#ifdef _WIN32_WCE + typedef HANDLE curl_win_thread_handle_t; +#elif defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) + typedef unsigned long curl_win_thread_handle_t; +#else + typedef uintptr_t curl_win_thread_handle_t; +#endif curl_thread_t t; + curl_win_thread_handle_t thread_handle; #ifdef _WIN32_WCE - t = CreateThread(NULL, 0, func, arg, 0, NULL); + thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL); #else - uintptr_t thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL); - t = (curl_thread_t)thread_handle; + thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL); #endif + t = (curl_thread_t)thread_handle; if((t == 0) || (t == LongToHandle(-1L))) { #ifdef _WIN32_WCE DWORD gle = GetLastError(); diff --git a/lib/curl_threads.h b/lib/curl_threads.h index 9e0d14a..2a93644 100644 --- a/lib/curl_threads.h +++ b/lib/curl_threads.h @@ -38,7 +38,8 @@ # define curl_thread_t HANDLE # define curl_thread_t_null (HANDLE)0 # if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) + (_WIN32_WINNT < _WIN32_WINNT_VISTA) || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) # define Curl_mutex_init(m) InitializeCriticalSection(m) # else # define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1) diff --git a/lib/curlx.h b/lib/curlx.h index 6e41826..4c77d4f 100644 --- a/lib/curlx.h +++ b/lib/curlx.h @@ -102,4 +102,3 @@ #endif /* ENABLE_CURLX_PRINTF */ #endif /* HEADER_CURL_CURLX_H */ - diff --git a/lib/dict.c b/lib/dict.c index 408d57b..78ef046 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -136,7 +136,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - char *path = data->state.path; + char *path = data->state.up.path; curl_off_t *bytecount = &data->req.bytecount; *done = TRUE; /* unconditionally */ diff --git a/lib/doh.c b/lib/doh.c new file mode 100644 index 0000000..ef6013d --- /dev/null +++ b/lib/doh.c @@ -0,0 +1,920 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include "curl_addrinfo.h" +#include "doh.h" + +#ifdef USE_NGHTTP2 +#include "sendf.h" +#include "multiif.h" +#include "url.h" +#include "share.h" +#include "curl_base64.h" +#include "connect.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define DNS_CLASS_IN 0x01 +#define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static const char * const errors[]={ + "", + "Bad label", + "Out of range", + "Label loop", + "Too small", + "Out of memory", + "RDATA length", + "Malformat", + "Bad RCODE", + "Unexpected TYPE", + "Unexpected CLASS", + "No content", + "Bad ID" +}; + +static const char *doh_strerror(DOHcode code) +{ + if((code >= DOH_OK) && (code <= DOH_DNS_BAD_ID)) + return errors[code]; + return "bad error code"; +} +#endif + +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + +UNITTEST DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen) /* output length */ +{ + size_t hostlen = strlen(host); + unsigned char *orig = dnsp; + const char *hostp = host; + + if(len < (12 + hostlen + 4)) + return DOH_TOO_SMALL_BUFFER; + + *dnsp++ = 0; /* 16 bit id */ + *dnsp++ = 0; + *dnsp++ = 0x01; /* |QR| Opcode |AA|TC|RD| Set the RD bit */ + *dnsp++ = '\0'; /* |RA| Z | RCODE | */ + *dnsp++ = '\0'; + *dnsp++ = 1; /* QDCOUNT (number of entries in the question section) */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* ANCOUNT */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* NSCOUNT */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* ARCOUNT */ + + /* store a QNAME */ + do { + char *dot = strchr(hostp, '.'); + size_t labellen; + bool found = false; + if(dot) { + found = true; + labellen = dot - hostp; + } + else + labellen = strlen(hostp); + if(labellen > 63) { + /* too long label, error out */ + *olen = 0; + return DOH_DNS_BAD_LABEL; + } + *dnsp++ = (unsigned char)labellen; + memcpy(dnsp, hostp, labellen); + dnsp += labellen; + hostp += labellen + 1; + if(!found) { + *dnsp++ = 0; /* terminating zero */ + break; + } + } while(1); + + *dnsp++ = '\0'; /* upper 8 bit TYPE */ + *dnsp++ = (unsigned char)dnstype; + *dnsp++ = '\0'; /* upper 8 bit CLASS */ + *dnsp++ = DNS_CLASS_IN; /* IN - "the Internet" */ + + *olen = dnsp - orig; + return DOH_OK; +} + +static size_t +doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct dohresponse *mem = (struct dohresponse *)userp; + + if((mem->size + realsize) > DOH_MAX_RESPONSE_SIZE) + /* suspiciously much for us */ + return 0; + + mem->memory = realloc(mem->memory, mem->size + realsize); + if(mem->memory == NULL) + /* out of memory! */ + return 0; + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + + return realsize; +} + +/* called from multi.c when this DOH transfer is complete */ +static int Curl_doh_done(struct Curl_easy *doh, CURLcode result) +{ + struct Curl_easy *data = doh->set.dohfor; + /* so one of the DOH request done for the 'data' transfer is now complete! */ + data->req.doh.pending--; + infof(data, "a DOH request is completed, %d to go\n", data->req.doh.pending); + if(result) + infof(data, "DOH request %s\n", curl_easy_strerror(result)); + + if(!data->req.doh.pending) { + /* DOH completed */ + curl_slist_free_all(data->req.doh.headers); + data->req.doh.headers = NULL; + Curl_expire(data, 0, EXPIRE_RUN_NOW); + } + return 0; +} + +#define ERROR_CHECK_SETOPT(x,y) result = curl_easy_setopt(doh, x, y); \ + if(result) goto error + +static CURLcode dohprobe(struct Curl_easy *data, + struct dnsprobe *p, DNStype dnstype, + const char *host, + const char *url, CURLM *multi, + struct curl_slist *headers) +{ + struct Curl_easy *doh = NULL; + char *nurl = NULL; + CURLcode result = CURLE_OK; + timediff_t timeout_ms; + DOHcode d = doh_encode(host, dnstype, p->dohbuffer, sizeof(p->dohbuffer), + &p->dohlen); + if(d) { + failf(data, "Failed to encode DOH packet [%d]\n", d); + return CURLE_OUT_OF_MEMORY; + } + + p->dnstype = dnstype; + p->serverdoh.memory = NULL; + /* the memory will be grown as needed by realloc in the doh_write_cb + function */ + p->serverdoh.size = 0; + + /* Note: this is code for sending the DoH request with GET but there's still + no logic that actually enables this. We should either add that ability or + yank out the GET code. Discuss! */ + if(data->set.doh_get) { + char *b64; + size_t b64len; + result = Curl_base64url_encode(data, (char *)p->dohbuffer, p->dohlen, + &b64, &b64len); + if(result) + goto error; + nurl = aprintf("%s?dns=%s", url, b64); + free(b64); + if(!nurl) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + url = nurl; + } + + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + /* Curl_open() is the internal version of curl_easy_init() */ + result = Curl_open(&doh); + if(!result) { + /* pass in the struct pointer via a local variable to please coverity and + the gcc typecheck helpers */ + struct dohresponse *resp = &p->serverdoh; + ERROR_CHECK_SETOPT(CURLOPT_URL, url); + ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); + ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp); + if(!data->set.doh_get) { + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer); + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen); + } + ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers); + ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); +#ifndef CURLDEBUG + /* enforce HTTPS if not debug */ + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); +#endif + ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); + ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + doh->set.fmultidone = Curl_doh_done; + doh->set.dohfor = data; /* identify for which transfer this is done */ + p->easy = doh; + + /* add this transfer to the multi handle */ + if(curl_multi_add_handle(multi, doh)) + goto error; + } + else + goto error; + free(nurl); + return CURLE_OK; + + error: + free(nurl); + Curl_close(doh); + return result; +} + +/* + * Curl_doh() resolves a name using DOH. It resolves a name and returns a + * 'Curl_addrinfo *' with the address information. + */ + +Curl_addrinfo *Curl_doh(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + *waitp = TRUE; /* this never returns synchronously */ + (void)conn; + (void)hostname; + (void)port; + + /* start clean, consider allocating this struct on demand */ + memset(&data->req.doh, 0, sizeof(struct dohdata)); + + data->req.doh.host = hostname; + data->req.doh.port = port; + data->req.doh.headers = + curl_slist_append(NULL, + "Content-Type: application/dns-message"); + if(!data->req.doh.headers) + goto error; + + if(conn->ip_version != CURL_IPRESOLVE_V6) { + /* create IPv4 DOH request */ + result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A, + hostname, data->set.str[STRING_DOH], + data->multi, data->req.doh.headers); + if(result) + goto error; + data->req.doh.pending++; + } + + if(conn->ip_version != CURL_IPRESOLVE_V4) { + /* create IPv6 DOH request */ + result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA, + hostname, data->set.str[STRING_DOH], + data->multi, data->req.doh.headers); + if(result) + goto error; + data->req.doh.pending++; + } + return NULL; + + error: + curl_slist_free_all(data->req.doh.headers); + data->req.doh.headers = NULL; + curl_easy_cleanup(data->req.doh.probe[0].easy); + data->req.doh.probe[0].easy = NULL; + curl_easy_cleanup(data->req.doh.probe[1].easy); + data->req.doh.probe[1].easy = NULL; + return NULL; +} + +static DOHcode skipqname(unsigned char *doh, size_t dohlen, + unsigned int *indexp) +{ + unsigned char length; + do { + if(dohlen < (*indexp + 1)) + return DOH_DNS_OUT_OF_RANGE; + length = doh[*indexp]; + if((length & 0xc0) == 0xc0) { + /* name pointer, advance over it and be done */ + if(dohlen < (*indexp + 2)) + return DOH_DNS_OUT_OF_RANGE; + *indexp += 2; + break; + } + if(length & 0xc0) + return DOH_DNS_BAD_LABEL; + if(dohlen < (*indexp + 1 + length)) + return DOH_DNS_OUT_OF_RANGE; + *indexp += 1 + length; + } while(length); + return DOH_OK; +} + +static unsigned short get16bit(unsigned char *doh, int index) +{ + return (unsigned short)((doh[index] << 8) | doh[index + 1]); +} + +static unsigned int get32bit(unsigned char *doh, int index) +{ + return (doh[index] << 24) | (doh[index + 1] << 16) | + (doh[index + 2] << 8) | doh[index + 3]; +} + +static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d) +{ + /* silently ignore addresses over the limit */ + if(d->numaddr < DOH_MAX_ADDR) { + struct dohaddr *a = &d->addr[d->numaddr]; + a->type = DNS_TYPE_A; + memcpy(&a->ip.v4, &doh[index], 4); + d->numaddr++; + } + return DOH_OK; +} + +static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d) +{ + /* silently ignore addresses over the limit */ + if(d->numaddr < DOH_MAX_ADDR) { + struct dohaddr *a = &d->addr[d->numaddr]; + a->type = DNS_TYPE_AAAA; + memcpy(&a->ip.v6, &doh[index], 16); + d->numaddr++; + } + return DOH_OK; +} + +static DOHcode cnameappend(struct cnamestore *c, + unsigned char *src, + size_t len) +{ + if(!c->alloc) { + c->allocsize = len + 1; + c->alloc = malloc(c->allocsize); + if(!c->alloc) + return DOH_OUT_OF_MEM; + } + else if(c->allocsize < (c->allocsize + len + 1)) { + char *ptr; + c->allocsize += len + 1; + ptr = realloc(c->alloc, c->allocsize); + if(!ptr) { + free(c->alloc); + return DOH_OUT_OF_MEM; + } + c->alloc = ptr; + } + memcpy(&c->alloc[c->len], src, len); + c->len += len; + c->alloc[c->len] = 0; /* keep it zero terminated */ + return DOH_OK; +} + +static DOHcode store_cname(unsigned char *doh, + size_t dohlen, + unsigned int index, + struct dohentry *d) +{ + struct cnamestore *c; + unsigned int loop = 128; /* a valid DNS name can never loop this much */ + unsigned char length; + + if(d->numcname == DOH_MAX_CNAME) + return DOH_OK; /* skip! */ + + c = &d->cname[d->numcname++]; + do { + if(index >= dohlen) + return DOH_DNS_OUT_OF_RANGE; + length = doh[index]; + if((length & 0xc0) == 0xc0) { + int newpos; + /* name pointer, get the new offset (14 bits) */ + if((index + 1) >= dohlen) + return DOH_DNS_OUT_OF_RANGE; + + /* move to the the new index */ + newpos = (length & 0x3f) << 8 | doh[index + 1]; + index = newpos; + continue; + } + else if(length & 0xc0) + return DOH_DNS_BAD_LABEL; /* bad input */ + else + index++; + + if(length) { + DOHcode rc; + if(c->len) { + rc = cnameappend(c, (unsigned char *)".", 1); + if(rc) + return rc; + } + if((index + length) > dohlen) + return DOH_DNS_BAD_LABEL; + + rc = cnameappend(c, &doh[index], length); + if(rc) + return rc; + index += length; + } + } while(length && --loop); + + if(!loop) + return DOH_DNS_LABEL_LOOP; + return DOH_OK; +} + +static DOHcode rdata(unsigned char *doh, + size_t dohlen, + unsigned short rdlength, + unsigned short type, + int index, + struct dohentry *d) +{ + /* RDATA + - A (TYPE 1): 4 bytes + - AAAA (TYPE 28): 16 bytes + - NS (TYPE 2): N bytes */ + DOHcode rc; + + switch(type) { + case DNS_TYPE_A: + if(rdlength != 4) + return DOH_DNS_RDATA_LEN; + rc = store_a(doh, index, d); + if(rc) + return rc; + break; + case DNS_TYPE_AAAA: + if(rdlength != 16) + return DOH_DNS_RDATA_LEN; + rc = store_aaaa(doh, index, d); + if(rc) + return rc; + break; + case DNS_TYPE_CNAME: + rc = store_cname(doh, dohlen, index, d); + if(rc) + return rc; + break; + default: + /* unsupported type, just skip it */ + break; + } + return DOH_OK; +} + +static void init_dohentry(struct dohentry *de) +{ + memset(de, 0, sizeof(*de)); + de->ttl = INT_MAX; +} + + +UNITTEST DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d) +{ + unsigned char rcode; + unsigned short qdcount; + unsigned short ancount; + unsigned short type = 0; + unsigned short class; + unsigned short rdlength; + unsigned short nscount; + unsigned short arcount; + unsigned int index = 12; + DOHcode rc; + + if(dohlen < 12) + return DOH_TOO_SMALL_BUFFER; /* too small */ + if(doh[0] || doh[1]) + return DOH_DNS_BAD_ID; /* bad ID */ + rcode = doh[3] & 0x0f; + if(rcode) + return DOH_DNS_BAD_RCODE; /* bad rcode */ + + qdcount = get16bit(doh, 4); + while(qdcount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + if(dohlen < (index + 4)) + return DOH_DNS_OUT_OF_RANGE; + index += 4; /* skip question's type and class */ + qdcount--; + } + + ancount = get16bit(doh, 6); + while(ancount) { + unsigned int ttl; + + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + type = get16bit(doh, index); + if((type != DNS_TYPE_CNAME) && (type != dnstype)) + /* Not the same type as was asked for nor CNAME */ + return DOH_DNS_UNEXPECTED_TYPE; + index += 2; + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + class = get16bit(doh, index); + if(DNS_CLASS_IN != class) + return DOH_DNS_UNEXPECTED_CLASS; /* unsupported */ + index += 2; + + if(dohlen < (index + 4)) + return DOH_DNS_OUT_OF_RANGE; + + ttl = get32bit(doh, index); + if(ttl < d->ttl) + d->ttl = ttl; + index += 4; + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + + rc = rdata(doh, dohlen, rdlength, type, index, d); + if(rc) + return rc; /* bad rdata */ + index += rdlength; + ancount--; + } + + nscount = get16bit(doh, 8); + while(nscount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 8)) + return DOH_DNS_OUT_OF_RANGE; + + index += 2 + 2 + 4; /* type, class and ttl */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + index += rdlength; + nscount--; + } + + arcount = get16bit(doh, 10); + while(arcount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 8)) + return DOH_DNS_OUT_OF_RANGE; + + index += 2 + 2 + 4; /* type, class and ttl */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + index += rdlength; + arcount--; + } + + if(index != dohlen) + return DOH_DNS_MALFORMAT; /* something is wrong */ + + if((type != DNS_TYPE_NS) && !d->numcname && !d->numaddr) + /* nothing stored! */ + return DOH_NO_CONTENT; + + return DOH_OK; /* ok */ +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void showdoh(struct Curl_easy *data, + struct dohentry *d) +{ + int i; + infof(data, "TTL: %u seconds\n", d->ttl); + for(i = 0; i < d->numaddr; i++) { + struct dohaddr *a = &d->addr[i]; + if(a->type == DNS_TYPE_A) { + infof(data, "DOH A: %u.%u.%u.%u\n", + a->ip.v4[0], a->ip.v4[1], + a->ip.v4[2], a->ip.v4[3]); + } + else if(a->type == DNS_TYPE_AAAA) { + int j; + char buffer[128]; + char *ptr; + size_t len; + snprintf(buffer, 128, "DOH AAAA: "); + ptr = &buffer[10]; + len = 118; + for(j = 0; j < 16; j += 2) { + size_t l; + snprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j], + d->addr[i].ip.v6[j + 1]); + l = strlen(ptr); + len -= l; + ptr += l; + } + infof(data, "%s\n", buffer); + } + } + for(i = 0; i < d->numcname; i++) { + infof(data, "CNAME: %s\n", d->cname[i].alloc); + } +} +#else +#define showdoh(x,y) +#endif + +/* + * doh2ai() + * + * This function returns a pointer to the first element of a newly allocated + * Curl_addrinfo struct linked list filled with the data from a set of DOH + * lookups. Curl_addrinfo is meant to work like the addrinfo struct does for + * a IPv6 stack, but usable also for IPv4, all hosts and environments. + * + * The memory allocated by this function *MUST* be free'd later on calling + * Curl_freeaddrinfo(). For each successful call to this function there + * must be an associated call later to Curl_freeaddrinfo(). + */ + +static Curl_addrinfo * +doh2ai(const struct dohentry *de, const char *hostname, int port) +{ + Curl_addrinfo *ai; + Curl_addrinfo *prevai = NULL; + Curl_addrinfo *firstai = NULL; + struct sockaddr_in *addr; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *addr6; +#endif + CURLcode result = CURLE_OK; + int i; + + if(!de) + /* no input == no output! */ + return NULL; + + for(i = 0; i < de->numaddr; i++) { + size_t ss_size; + CURL_SA_FAMILY_T addrtype; + if(de->addr[i].type == DNS_TYPE_AAAA) { +#ifndef ENABLE_IPV6 + /* we can't handle IPv6 addresses */ + continue; +#else + ss_size = sizeof(struct sockaddr_in6); + addrtype = AF_INET6; +#endif + } + else { + ss_size = sizeof(struct sockaddr_in); + addrtype = AF_INET; + } + + ai = calloc(1, sizeof(Curl_addrinfo)); + if(!ai) { + result = CURLE_OUT_OF_MEMORY; + break; + } + ai->ai_canonname = strdup(hostname); + if(!ai->ai_canonname) { + result = CURLE_OUT_OF_MEMORY; + free(ai); + break; + } + ai->ai_addr = calloc(1, ss_size); + if(!ai->ai_addr) { + result = CURLE_OUT_OF_MEMORY; + free(ai->ai_canonname); + free(ai); + break; + } + + if(!firstai) + /* store the pointer we want to return from this function */ + firstai = ai; + + if(prevai) + /* make the previous entry point to this */ + prevai->ai_next = ai; + + ai->ai_family = addrtype; + + /* we return all names as STREAM, so when using this address for TFTP + the type must be ignored and conn->socktype be used instead! */ + ai->ai_socktype = SOCK_STREAM; + + ai->ai_addrlen = (curl_socklen_t)ss_size; + + /* leave the rest of the struct filled with zero */ + + switch(ai->ai_family) { + case AF_INET: + addr = (void *)ai->ai_addr; /* storage area for this info */ + DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4)); + memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr)); + addr->sin_family = (CURL_SA_FAMILY_T)addrtype; + addr->sin_port = htons((unsigned short)port); + break; + +#ifdef ENABLE_IPV6 + case AF_INET6: + addr6 = (void *)ai->ai_addr; /* storage area for this info */ + DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6)); + memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr)); + addr6->sin6_family = (CURL_SA_FAMILY_T)addrtype; + addr6->sin6_port = htons((unsigned short)port); + break; +#endif + } + + prevai = ai; + } + + if(result) { + Curl_freeaddrinfo(firstai); + firstai = NULL; + } + + return firstai; +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static const char *type2name(DNStype dnstype) +{ + return (dnstype == DNS_TYPE_A)?"A":"AAAA"; +} +#endif + +UNITTEST void de_cleanup(struct dohentry *d) +{ + int i = 0; + for(i = 0; i < d->numcname; i++) { + free(d->cname[i].alloc); + } +} + +CURLcode Curl_doh_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dnsp) +{ + struct Curl_easy *data = conn->data; + *dnsp = NULL; /* defaults to no response */ + + if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) { + failf(data, "Could not DOH-resolve: %s", conn->async.hostname); + return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: + CURLE_COULDNT_RESOLVE_HOST; + } + else if(!data->req.doh.pending) { + DOHcode rc; + DOHcode rc2; + struct dohentry de; + struct Curl_dns_entry *dns; + struct Curl_addrinfo *ai; + /* remove DOH handles from multi handle and close them */ + curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy); + Curl_close(data->req.doh.probe[0].easy); + curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy); + Curl_close(data->req.doh.probe[1].easy); + + /* parse the responses, create the struct and return it! */ + init_dohentry(&de); + rc = doh_decode(data->req.doh.probe[0].serverdoh.memory, + data->req.doh.probe[0].serverdoh.size, + data->req.doh.probe[0].dnstype, + &de); + free(data->req.doh.probe[0].serverdoh.memory); + if(rc) { + infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc), + type2name(data->req.doh.probe[0].dnstype), + data->req.doh.host); + } + rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory, + data->req.doh.probe[1].serverdoh.size, + data->req.doh.probe[1].dnstype, + &de); + free(data->req.doh.probe[1].serverdoh.memory); + if(rc2) { + infof(data, "DOG: %s type %s for %s\n", doh_strerror(rc2), + type2name(data->req.doh.probe[1].dnstype), + data->req.doh.host); + } + if(!rc || !rc2) { + infof(data, "DOH Host name: %s\n", data->req.doh.host); + showdoh(data, &de); + + ai = doh2ai(&de, data->req.doh.host, data->req.doh.port); + if(!ai) { + de_cleanup(&de); + return CURLE_OUT_OF_MEMORY; + } + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + /* we got a response, store it in the cache */ + dns = Curl_cache_addr(data, ai, data->req.doh.host, data->req.doh.port); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + de_cleanup(&de); + if(!dns) + /* returned failure, bail out nicely */ + Curl_freeaddrinfo(ai); + else { + conn->async.dns = dns; + *dnsp = dns; + return CURLE_OK; + } + } + de_cleanup(&de); + + return CURLE_COULDNT_RESOLVE_HOST; + } + + return CURLE_OK; +} + +#else /* !USE_NGHTTP2 */ +/* + */ +Curl_addrinfo *Curl_doh(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + (void)conn; + (void)hostname; + (void)port; + (void)waitp; + return NULL; +} + +CURLcode Curl_doh_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dnsp) +{ + (void)conn; + (void)dnsp; + return CURLE_NOT_BUILT_IN; +} + +#endif /* USE_NGHTTP2 */ diff --git a/lib/doh.h b/lib/doh.h new file mode 100644 index 0000000..83c79bc --- /dev/null +++ b/lib/doh.h @@ -0,0 +1,105 @@ +#ifndef HEADER_CURL_DOH_H +#define HEADER_CURL_DOH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "urldata.h" +#include "curl_addrinfo.h" + +/* + * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name + * and returns a 'Curl_addrinfo *' with the address information. + */ + +Curl_addrinfo *Curl_doh(struct connectdata *conn, + const char *hostname, + int port, + int *waitp); + +CURLcode Curl_doh_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns); + +int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); + +typedef enum { + DOH_OK, + DOH_DNS_BAD_LABEL, /* 1 */ + DOH_DNS_OUT_OF_RANGE, /* 2 */ + DOH_DNS_LABEL_LOOP, /* 3 */ + DOH_TOO_SMALL_BUFFER, /* 4 */ + DOH_OUT_OF_MEM, /* 5 */ + DOH_DNS_RDATA_LEN, /* 6 */ + DOH_DNS_MALFORMAT, /* 7 */ + DOH_DNS_BAD_RCODE, /* 8 - no such name */ + DOH_DNS_UNEXPECTED_TYPE, /* 9 */ + DOH_DNS_UNEXPECTED_CLASS, /* 10 */ + DOH_NO_CONTENT, /* 11 */ + DOH_DNS_BAD_ID /* 12 */ +} DOHcode; + +typedef enum { + DNS_TYPE_A = 1, + DNS_TYPE_NS = 2, + DNS_TYPE_CNAME = 5, + DNS_TYPE_AAAA = 28 +} DNStype; + +#define DOH_MAX_ADDR 24 +#define DOH_MAX_CNAME 4 + +struct cnamestore { + size_t len; /* length of cname */ + char *alloc; /* allocated pointer */ + size_t allocsize; /* allocated size */ +}; + +struct dohaddr { + int type; + union { + unsigned char v4[4]; /* network byte order */ + unsigned char v6[16]; + } ip; +}; + +struct dohentry { + unsigned int ttl; + int numaddr; + struct dohaddr addr[DOH_MAX_ADDR]; + int numcname; + struct cnamestore cname[DOH_MAX_CNAME]; +}; + + +#ifdef DEBUGBUILD +DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen); /* output length */ +DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d); +void de_cleanup(struct dohentry *d); +#endif +#endif /* HEADER_CURL_DOH_H */ diff --git a/lib/dotdot.c b/lib/dotdot.c index cbb308d..2c6177a 100644 --- a/lib/dotdot.c +++ b/lib/dotdot.c @@ -62,6 +62,8 @@ char *Curl_dedotdotify(const char *input) if(!out) return NULL; /* out of memory */ + *out = 0; /* zero terminates, for inputs like "./" */ + /* get a cloned copy of the input */ clone = strdup(input); if(!clone) { diff --git a/lib/dotdot.h b/lib/dotdot.h index fac8e6f..125af43 100644 --- a/lib/dotdot.h +++ b/lib/dotdot.h @@ -22,4 +22,4 @@ * ***************************************************************************/ char *Curl_dedotdotify(const char *input); -#endif +#endif /* HEADER_CURL_DOTDOT_H */ diff --git a/lib/easy.c b/lib/easy.c index 027d0be..4de4e65 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1002,10 +1002,6 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) */ void curl_easy_reset(struct Curl_easy *data) { - Curl_safefree(data->state.pathbuffer); - - data->state.path = NULL; - Curl_free_request_state(data); /* zero out UserDefined data: */ @@ -1197,3 +1193,22 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, return result; } + +/* + * Performs connection upkeep for the given session handle. + */ +CURLcode curl_easy_upkeep(struct Curl_easy *data) +{ + /* Verify that we got an easy handle we can work with. */ + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(data->multi_easy) { + /* Use the common function to keep connections alive. */ + return Curl_upkeep(&data->multi_easy->conn_cache, data); + } + else { + /* No connections, so just return success */ + return CURLE_OK; + } +} diff --git a/lib/easyif.h b/lib/easyif.h index f6132cc..6ba7e54 100644 --- a/lib/easyif.h +++ b/lib/easyif.h @@ -30,4 +30,3 @@ CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy); #endif #endif /* HEADER_CURL_EASYIF_H */ - diff --git a/lib/escape.c b/lib/escape.c index 10774f0..afd3899 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -41,7 +41,7 @@ its behavior is altered by the current locale. See https://tools.ietf.org/html/rfc3986#section-2.3 */ -static bool Curl_isunreserved(unsigned char in) +bool Curl_isunreserved(unsigned char in) { switch(in) { case '0': case '1': case '2': case '3': case '4': @@ -141,6 +141,8 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string, * Returns a pointer to a malloced string in *ostring with length given in * *olen. If length == 0, the length is assumed to be strlen(string). * + * 'data' can be set to NULL but then this function can't convert network + * data to host for non-ascii. */ CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, @@ -151,7 +153,7 @@ CURLcode Curl_urldecode(struct Curl_easy *data, char *ns = malloc(alloc); size_t strindex = 0; unsigned long hex; - CURLcode result; + CURLcode result = CURLE_OK; if(!ns) return CURLE_OUT_OF_MEMORY; @@ -171,11 +173,13 @@ CURLcode Curl_urldecode(struct Curl_easy *data, in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ - result = Curl_convert_from_network(data, (char *)&in, 1); - if(result) { - /* Curl_convert_from_network calls failf if unsuccessful */ - free(ns); - return result; + if(data) { + result = Curl_convert_from_network(data, (char *)&in, 1); + if(result) { + /* Curl_convert_from_network calls failf if unsuccessful */ + free(ns); + return result; + } } string += 2; diff --git a/lib/escape.h b/lib/escape.h index 638666f..d8bbe5c 100644 --- a/lib/escape.h +++ b/lib/escape.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,10 +24,10 @@ /* Escape and unescape URL encoding in strings. The functions return a new * allocated string or NULL if an error occurred. */ +bool Curl_isunreserved(unsigned char in); CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_crlf); #endif /* HEADER_CURL_ESCAPE_H */ - diff --git a/lib/file.c b/lib/file.c index e50e988..722b55e 100644 --- a/lib/file.c +++ b/lib/file.c @@ -143,7 +143,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) #endif size_t real_path_len; - CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path, + CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &real_path, &real_path_len, FALSE); if(result) return result; @@ -197,7 +197,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) file->fd = fd; if(!data->set.upload && (fd == -1)) { - failf(data, "Couldn't open file %s", data->state.path); + failf(data, "Couldn't open file %s", data->state.up.path); file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); return CURLE_FILE_COULDNT_READ_FILE; } @@ -307,7 +307,7 @@ static CURLcode file_upload(struct connectdata *conn) size_t nread; size_t nwrite; size_t readcount; - result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount); + result = Curl_fillreadbuffer(conn, data->set.buffer_size, &readcount); if(result) break; @@ -386,7 +386,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done) *done = TRUE; /* unconditionally */ - Curl_initinfo(data); Curl_pgrsStartNow(data); if(data->set.upload) @@ -413,21 +412,18 @@ static CURLcode file_do(struct connectdata *conn, bool *done) } } - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which for FILE can't be much more than the file size and - date. */ - if(data->set.opt_no_body && data->set.include_header && fstated) { + if(fstated) { time_t filetime; struct tm buffer; const struct tm *tm = &buffer; char header[80]; snprintf(header, sizeof(header), "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); + result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); if(result) return result; - result = Curl_client_write(conn, CLIENTWRITE_BOTH, + result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"Accept-ranges: bytes\r\n", 0); if(result) return result; @@ -439,19 +435,22 @@ static CURLcode file_do(struct connectdata *conn, bool *done) /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ snprintf(header, sizeof(header), - "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", + "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s", Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], tm->tm_mday, Curl_month[tm->tm_mon], tm->tm_year + 1900, tm->tm_hour, tm->tm_min, - tm->tm_sec); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); - if(!result) - /* set the file size to make it available post transfer */ - Curl_pgrsSetDownloadSize(data, expected_size); - return result; + tm->tm_sec, + data->set.opt_no_body ? "": "\r\n"); + result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); + if(result) + return result; + /* set the file size to make it available post transfer */ + Curl_pgrsSetDownloadSize(data, expected_size); + if(data->set.opt_no_body) + return result; } /* Check whether file range has been specified */ diff --git a/lib/file.h b/lib/file.h index c12ae0e..20828ad 100644 --- a/lib/file.h +++ b/lib/file.h @@ -38,4 +38,3 @@ extern const struct Curl_handler Curl_handler_file; #endif #endif /* HEADER_CURL_FILE_H */ - diff --git a/lib/ftp.c b/lib/ftp.c index 7dbf080..793d991 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1444,6 +1444,7 @@ static CURLcode ftp_state_list(struct connectdata *conn) { CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; /* If this output is to be machine-parsed, the NLST command might be better to use, since the LIST command output is not specified or standard in any @@ -1460,7 +1461,7 @@ static CURLcode ftp_state_list(struct connectdata *conn) then just do LIST (in that case: nothing to do here) */ char *cmd, *lstArg, *slashPos; - const char *inpath = data->state.path; + const char *inpath = ftp->path; lstArg = NULL; if((data->set.ftp_filemethod == FTPFILE_NOCWD) && @@ -3141,7 +3142,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, int ftpcode; CURLcode result = CURLE_OK; char *path = NULL; - const char *path_to_use = data->state.path; if(!ftp) return CURLE_OK; @@ -3193,7 +3193,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, if(!result) /* get the "raw" path */ - result = Curl_urldecode(data, path_to_use, 0, &path, NULL, TRUE); + result = Curl_urldecode(data, ftp->path, 0, &path, NULL, TRUE); if(result) { /* We can limp along anyway (and should try to since we may already be in * the error path) */ @@ -3213,9 +3213,11 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, ftpc->prevpath[dlen] = 0; /* terminate */ } else { + free(path); /* we never changed dir */ ftpc->prevpath = strdup(""); - free(path); + if(!ftpc->prevpath) + return CURLE_OUT_OF_MEMORY; } if(ftpc->prevpath) infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath); @@ -3346,7 +3348,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, /* Send any post-transfer QUOTE strings? */ if(!status && !result && !premature && data->set.postquote) result = ftp_sendquote(conn, data->set.postquote); - + Curl_safefree(ftp->pathalloc); return result; } @@ -3695,12 +3697,13 @@ static void wc_data_dtor(void *ptr) static CURLcode init_wc_data(struct connectdata *conn) { char *last_slash; - char *path = conn->data->state.path; + struct FTP *ftp = conn->data->req.protop; + char *path = ftp->path; struct WildcardData *wildcard = &(conn->data->wildcard); CURLcode result = CURLE_OK; struct ftp_wc *ftpwc = NULL; - last_slash = strrchr(conn->data->state.path, '/'); + last_slash = strrchr(ftp->path, '/'); if(last_slash) { last_slash++; if(last_slash[0] == '\0') { @@ -3757,7 +3760,7 @@ static CURLcode init_wc_data(struct connectdata *conn) goto fail; } - wildcard->path = strdup(conn->data->state.path); + wildcard->path = strdup(ftp->path); if(!wildcard->path) { result = CURLE_OUT_OF_MEMORY; goto fail; @@ -3828,16 +3831,15 @@ static CURLcode wc_statemach(struct connectdata *conn) /* filelist has at least one file, lets get first one */ struct ftp_conn *ftpc = &conn->proto.ftpc; struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; + struct FTP *ftp = conn->data->req.protop; char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); if(!tmp_path) return CURLE_OUT_OF_MEMORY; - /* switch default "state.pathbuffer" and tmp_path, good to see - ftp_parse_url_path function to understand this trick */ - Curl_safefree(conn->data->state.pathbuffer); - conn->data->state.pathbuffer = tmp_path; - conn->data->state.path = tmp_path; + /* switch default ftp->path and tmp_path */ + free(ftp->pathalloc); + ftp->pathalloc = ftp->path = tmp_path; infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); if(conn->data->set.chunk_bgn) { @@ -3963,10 +3965,14 @@ CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd) enum protection_level data_sec = conn->data_prot; #endif + if(!cmd) + return CURLE_BAD_FUNCTION_ARGUMENT; + write_len = strlen(cmd); - if(write_len > (sizeof(s) -3)) + if(!write_len || write_len > (sizeof(s) -3)) return CURLE_BAD_FUNCTION_ARGUMENT; + memcpy(&s, cmd, write_len); strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ write_len += 2; bytes_written = 0; @@ -4101,7 +4107,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) struct FTP *ftp = data->req.protop; struct ftp_conn *ftpc = &conn->proto.ftpc; const char *slash_pos; /* position of the first '/' char in curpos */ - const char *path_to_use = data->state.path; + const char *path_to_use = ftp->path; const char *cur_pos; const char *filename = NULL; @@ -4187,7 +4193,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) /* parse the URL path into separate path components */ while((slash_pos = strchr(cur_pos, '/')) != NULL) { /* 1 or 0 pointer offset to indicate absolute directory */ - ssize_t absolute_dir = ((cur_pos - data->state.path > 0) && + ssize_t absolute_dir = ((cur_pos - ftp->path > 0) && (ftpc->dirdepth == 0))?1:0; /* seek out the next path component */ @@ -4264,7 +4270,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) size_t dlen; char *path; CURLcode result = - Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, TRUE); + Curl_urldecode(conn->data, ftp->path, 0, &path, &dlen, TRUE); if(result) { freedirs(ftpc); return result; @@ -4384,16 +4390,16 @@ static CURLcode ftp_setup_connection(struct connectdata *conn) char *type; struct FTP *ftp; - conn->data->req.protop = ftp = malloc(sizeof(struct FTP)); + conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1); if(NULL == ftp) return CURLE_OUT_OF_MEMORY; - data->state.path++; /* don't include the initial slash */ + ftp->path = &data->state.up.path[1]; /* don't include the initial slash */ data->state.slash_removed = TRUE; /* we've skipped the slash */ /* FTP URLs support an extension like ";type=" that * we'll try to get now! */ - type = strstr(data->state.path, ";type="); + type = strstr(ftp->path, ";type="); if(!type) type = strstr(conn->host.rawalloc, ";type="); diff --git a/lib/ftp.h b/lib/ftp.h index 7ec3391..38d0322 100644 --- a/lib/ftp.h +++ b/lib/ftp.h @@ -105,6 +105,8 @@ struct FTP { curl_off_t *bytecountp; char *user; /* user name string */ char *passwd; /* password string */ + char *path; /* points to the urlpieces struct field */ + char *pathalloc; /* if non-NULL a pointer to an allocated path */ /* transfer a file/body or not, done as a typedefed enum just to make debuggers display the full symbol and not just the numerical value */ diff --git a/lib/getinfo.c b/lib/getinfo.c index 14b4562..54c2c2f 100644 --- a/lib/getinfo.c +++ b/lib/getinfo.c @@ -85,7 +85,6 @@ CURLcode Curl_initinfo(struct Curl_easy *data) #ifdef USE_SSL Curl_ssl_free_certinfo(data); #endif - return CURLE_OK; } diff --git a/lib/gopher.c b/lib/gopher.c index 3ecee9b..b441a64 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -78,7 +78,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; curl_off_t *bytecount = &data->req.bytecount; - char *path = data->state.path; + char *path = data->state.up.path; char *sel = NULL; char *sel_org = NULL; ssize_t amount, k; diff --git a/lib/hostasyn.c b/lib/hostasyn.c index e7b399e..6ff60ba 100644 --- a/lib/hostasyn.c +++ b/lib/hostasyn.c @@ -111,31 +111,6 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn, return result; } -/* Call this function after Curl_connect() has returned async=TRUE and - then a successful name resolve has been received. - - Note: this function disconnects and frees the conn data in case of - resolve failure */ -CURLcode Curl_async_resolved(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result; - - if(conn->async.dns) { - conn->dns_entry = conn->async.dns; - conn->async.dns = NULL; - } - - result = Curl_setup_conn(conn, protocol_done); - - if(result) - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - Curl_disconnect(conn->data, conn, TRUE); /* close the connection */ - - return result; -} - /* * Curl_getaddrinfo() is the generic low-level name resolve API within this * source file. There are several versions of this function - for different diff --git a/lib/hostcheck.h b/lib/hostcheck.h index 86e3b96..f562df9 100644 --- a/lib/hostcheck.h +++ b/lib/hostcheck.h @@ -29,4 +29,3 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname); #endif /* HEADER_CURL_HOSTCHECK_H */ - diff --git a/lib/hostip.c b/lib/hostip.c index bc20f71..f589a0b 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -60,6 +60,7 @@ #include "url.h" #include "inet_ntop.h" #include "multiif.h" +#include "doh.h" #include "warnless.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -454,7 +455,7 @@ Curl_cache_addr(struct Curl_easy *data, /* shuffle addresses if requested */ if(data->set.dns_shuffle_addresses) { CURLcode result = Curl_shuffle_addr(data, &addr); - if(!result) + if(result) return NULL; } @@ -565,23 +566,27 @@ int Curl_resolv(struct connectdata *conn, return CURLRESOLV_ERROR; } - /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a - non-zero value indicating that we need to wait for the response to the - resolve call */ - addr = Curl_getaddrinfo(conn, + if(data->set.doh) { + addr = Curl_doh(conn, hostname, port, &respwait); + } + else { + /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a + non-zero value indicating that we need to wait for the response to the + resolve call */ + addr = Curl_getaddrinfo(conn, #ifdef DEBUGBUILD - (data->set.str[STRING_DEVICE] - && !strcmp(data->set.str[STRING_DEVICE], - "LocalHost"))?"localhost": + (data->set.str[STRING_DEVICE] + && !strcmp(data->set.str[STRING_DEVICE], + "LocalHost"))?"localhost": #endif - hostname, port, &respwait); - + hostname, port, &respwait); + } if(!addr) { if(respwait) { /* the response to our resolve call will come asynchronously at a later time, good or bad */ /* First, check that we haven't received the info by now */ - result = Curl_resolver_is_resolved(conn, &dns); + result = Curl_resolv_check(conn, &dns); if(result) /* error detected */ return CURLRESOLV_ERROR; if(dns) @@ -1053,3 +1058,54 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) return CURLE_OK; } + +CURLcode Curl_resolv_check(struct connectdata *conn, + struct Curl_dns_entry **dns) +{ + if(conn->data->set.doh) + return Curl_doh_is_resolved(conn, dns); + return Curl_resolver_is_resolved(conn, dns); +} + +int Curl_resolv_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ +#ifdef CURLRES_ASYNCH + if(conn->data->set.doh) + /* nothing to wait for during DOH resolve, those handles have their own + sockets */ + return GETSOCK_BLANK; + return Curl_resolver_getsock(conn, socks, numsocks); +#else + (void)conn; + (void)socks; + (void)numsocks; + return GETSOCK_BLANK; +#endif +} + +/* Call this function after Curl_connect() has returned async=TRUE and + then a successful name resolve has been received. + + Note: this function disconnects and frees the conn data in case of + resolve failure */ +CURLcode Curl_once_resolved(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result; + + if(conn->async.dns) { + conn->dns_entry = conn->async.dns; + conn->async.dns = NULL; + } + + result = Curl_setup_conn(conn, protocol_done); + + if(result) + /* We're not allowed to return failure with memory left allocated + in the connectdata struct, free those here */ + Curl_disconnect(conn->data, conn, TRUE); /* close the connection */ + + return result; +} diff --git a/lib/hostip.h b/lib/hostip.h index 1de4bee..29fd1ef 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -145,12 +145,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, /* IPv4 threadsafe resolve function used for synch and asynch builds */ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port); -CURLcode Curl_async_resolved(struct connectdata *conn, - bool *protocol_connect); - -#ifndef CURLRES_ASYNCH -#define Curl_async_resolved(x,y) CURLE_OK -#endif +CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect); /* * Curl_addrinfo_callback() is used when we build with any asynch specialty. @@ -258,4 +253,10 @@ void Curl_hostcache_destroy(struct Curl_easy *data); */ CURLcode Curl_loadhostpairs(struct Curl_easy *data); +CURLcode Curl_resolv_check(struct connectdata *conn, + struct Curl_dns_entry **dns); +int Curl_resolv_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + #endif /* HEADER_CURL_HOSTIP_H */ diff --git a/lib/http.c b/lib/http.c index e727ed8..46ac15a 100644 --- a/lib/http.c +++ b/lib/http.c @@ -169,7 +169,7 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn) data->req.protop = http; if(!CONN_INUSE(conn)) - /* if not alredy multi-using, setup connection details */ + /* if not already multi-using, setup connection details */ Curl_http2_setup_conn(conn); Curl_http2_setup_req(data); return CURLE_OK; @@ -537,14 +537,6 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) } if(pickhost || pickproxy) { - /* In case this is GSS auth, the newurl field is already allocated so - we must make sure to free it before allocating a new one. As figured - out in bug #2284386 */ - Curl_safefree(data->req.newurl); - data->req.newurl = strdup(data->change.url); /* clone URL */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - if((data->set.httpreq != HTTPREQ_GET) && (data->set.httpreq != HTTPREQ_HEAD) && !conn->bits.rewindaftersend) { @@ -552,6 +544,13 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) if(result) return result; } + /* In case this is GSS auth, the newurl field is already allocated so + we must make sure to free it before allocating a new one. As figured + out in bug #2284386 */ + Curl_safefree(data->req.newurl); + data->req.newurl = strdup(data->change.url); /* clone URL */ + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; } else if((data->req.httpcode < 300) && (!data->state.authhost.done) && @@ -1094,11 +1093,13 @@ Curl_send_buffer *Curl_add_buffer_init(void) /* * Curl_add_buffer_free() frees all associated resources. */ -void Curl_add_buffer_free(Curl_send_buffer *buff) +void Curl_add_buffer_free(Curl_send_buffer **inp) { - if(buff) /* deal with NULL input */ - free(buff->buffer); - free(buff); + Curl_send_buffer *in = *inp; + if(in) /* deal with NULL input */ + free(in->buffer); + free(in); + *inp = NULL; } /* @@ -1107,7 +1108,7 @@ void Curl_add_buffer_free(Curl_send_buffer *buff) * * Returns CURLcode */ -CURLcode Curl_add_buffer_send(Curl_send_buffer *in, +CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, struct connectdata *conn, /* add the number of sent bytes to this @@ -1128,6 +1129,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, size_t sendsize; curl_socket_t sockfd; size_t headersize; + Curl_send_buffer *in = *inp; DEBUGASSERT(socketindex <= SECONDARYSOCKET); @@ -1148,7 +1150,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, /* Curl_convert_to_network calls failf if unsuccessful */ if(result) { /* conversion failed, free memory and return to the caller */ - Curl_add_buffer_free(in); + Curl_add_buffer_free(inp); return result; } @@ -1172,7 +1174,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, result = Curl_get_upload_buffer(data); if(result) { /* malloc failed, free memory and return to the caller */ - Curl_add_buffer_free(in); + Curl_add_buffer_free(&in); return result; } memcpy(data->state.ulbuf, ptr, sendsize); @@ -1256,7 +1258,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, Curl_pipeline_leave_write(conn); } } - Curl_add_buffer_free(in); + Curl_add_buffer_free(&in); return result; } @@ -1265,31 +1267,35 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, /* * add_bufferf() add the formatted input to the buffer. */ -CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...) +CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...) { char *s; va_list ap; + Curl_send_buffer *in = *inp; va_start(ap, fmt); s = vaprintf(fmt, ap); /* this allocs a new string to append */ va_end(ap); if(s) { - CURLcode result = Curl_add_buffer(in, s, strlen(s)); + CURLcode result = Curl_add_buffer(inp, s, strlen(s)); free(s); return result; } /* If we failed, we cleanup the whole buffer and return error */ free(in->buffer); free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } /* - * add_buffer() appends a memory chunk to the existing buffer + * Curl_add_buffer() appends a memory chunk to the existing buffer */ -CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) +CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, + size_t size) { char *new_rb; + Curl_send_buffer *in = *inp; if(~size < in->size_used) { /* If resulting used size of send buffer would wrap size_t, cleanup @@ -1297,6 +1303,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) size will fit into a single allocatable memory chunk */ Curl_safefree(in->buffer); free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } @@ -1323,6 +1330,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) if(!new_rb) { /* If we failed, we cleanup the whole buffer and return error */ free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } @@ -1484,11 +1492,11 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn) if(!req_buffer) return CURLE_OUT_OF_MEMORY; - result = Curl_add_bufferf(req_buffer, proxy_header); + result = Curl_add_bufferf(&req_buffer, proxy_header); if(result) return result; - result = Curl_add_buffer_send(req_buffer, + result = Curl_add_buffer_send(&req_buffer, conn, &conn->data->info.request_size, 0, @@ -1561,8 +1569,7 @@ CURLcode Curl_http_done(struct connectdata *conn, return CURLE_OK; if(http->send_buffer) { - Curl_add_buffer_free(http->send_buffer); - http->send_buffer = NULL; /* clear the pointer */ + Curl_add_buffer_free(&http->send_buffer); } Curl_http2_done(conn, premature); @@ -1653,8 +1660,8 @@ static CURLcode expect100(struct Curl_easy *data, Curl_compareheader(ptr, "Expect:", "100-continue"); } else { - result = Curl_add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); + result = Curl_add_bufferf(&req_buffer, + "Expect: 100-continue\r\n"); if(!result) data->state.expect100header = TRUE; } @@ -1785,7 +1792,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, !strcasecompare(data->state.first_host, conn->host.name))) ; else { - result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); + result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data); } if(semicolonp) *semicolonp = ';'; /* put back the semicolon */ @@ -1854,7 +1861,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data, tm->tm_min, tm->tm_sec); - result = Curl_add_buffer(req_buffer, datestr, strlen(datestr)); + result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr)); return result; } @@ -1869,7 +1876,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) struct Curl_easy *data = conn->data; CURLcode result = CURLE_OK; struct HTTP *http; - const char *ppath = data->state.path; + const char *path = data->state.up.path; + const char *query = data->state.up.query; bool paste_ftp_userpwd = FALSE; char ftp_typecode[sizeof("/;type=?")] = ""; const char *host = conn->host.name; @@ -1987,7 +1995,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } /* setup the authentication headers */ - result = Curl_http_output_auth(conn, request, ppath, FALSE); + result = Curl_http_output_auth(conn, request, path, FALSE); if(result) return result; @@ -2215,47 +2223,59 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* The path sent to the proxy is in fact the entire URL. But if the remote host is a IDN-name, we must make sure that the request we produce only uses the encoded host name! */ + + /* and no fragment part */ + CURLUcode uc; + char *url; + CURLU *h = curl_url_dup(data->state.uh); + if(!h) + return CURLE_OUT_OF_MEMORY; + if(conn->host.dispname != conn->host.name) { - char *url = data->change.url; - ptr = strstr(url, conn->host.dispname); - if(ptr) { - /* This is where the display name starts in the URL, now replace this - part with the encoded name. TODO: This method of replacing the host - name is rather crude as I believe there's a slight risk that the - user has entered a user name or password that contain the host name - string. */ - size_t currlen = strlen(conn->host.dispname); - size_t newlen = strlen(conn->host.name); - size_t urllen = strlen(url); - - char *newurl; - - newurl = malloc(urllen + newlen - currlen + 1); - if(newurl) { - /* copy the part before the host name */ - memcpy(newurl, url, ptr - url); - /* append the new host name instead of the old */ - memcpy(newurl + (ptr - url), conn->host.name, newlen); - /* append the piece after the host name */ - memcpy(newurl + newlen + (ptr - url), - ptr + currlen, /* copy the trailing zero byte too */ - urllen - (ptr-url) - currlen + 1); - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - data->change.url = newurl; - data->change.url_alloc = TRUE; - } - else - return CURLE_OUT_OF_MEMORY; + uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + } + uc = curl_url_set(h, CURLUPART_FRAGMENT, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + + if(strcasecompare("http", data->state.up.scheme)) { + /* when getting HTTP, we don't want the userinfo the URL */ + uc = curl_url_set(h, CURLUPART_USER, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + uc = curl_url_set(h, CURLUPART_PASSWORD, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; } } - ppath = data->change.url; - if(checkprefix("ftp://", ppath)) { + /* now extract the new version of the URL */ + uc = curl_url_get(h, CURLUPART_URL, &url, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + + if(data->change.url_alloc) + free(data->change.url); + + data->change.url = url; + data->change.url_alloc = TRUE; + + curl_url_cleanup(h); + + if(strcasecompare("ftp", data->state.up.scheme)) { if(data->set.proxy_transfer_mode) { /* when doing ftp, append ;type= if not present */ - char *type = strstr(ppath, ";type="); + char *type = strstr(path, ";type="); if(type && type[6] && type[7] == 0) { switch(Curl_raw_toupper(type[6])) { case 'A': @@ -2270,7 +2290,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) char *p = ftp_typecode; /* avoid sending invalid URLs like ftp://example.com;type=i if the * user specified ftp://example.com without the slash */ - if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') { + if(!*data->state.up.path && path[strlen(path) - 1] != '/') { *p++ = '/'; } snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c", @@ -2419,25 +2439,36 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* add the main request stuff */ /* GET/HEAD/POST/PUT */ - result = Curl_add_bufferf(req_buffer, "%s ", request); + result = Curl_add_bufferf(&req_buffer, "%s ", request); if(result) return result; - if(data->set.str[STRING_TARGET]) - ppath = data->set.str[STRING_TARGET]; + if(data->set.str[STRING_TARGET]) { + path = data->set.str[STRING_TARGET]; + query = NULL; + } /* url */ - if(paste_ftp_userpwd) - result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s", + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + char *url = data->change.url; + result = Curl_add_buffer(&req_buffer, url, strlen(url)); + } + else if(paste_ftp_userpwd) + result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s", conn->user, conn->passwd, - ppath + sizeof("ftp://") - 1); - else - result = Curl_add_buffer(req_buffer, ppath, strlen(ppath)); + path + sizeof("ftp://") - 1); + else { + result = Curl_add_buffer(&req_buffer, path, strlen(path)); + if(result) + return result; + if(query) + result = Curl_add_bufferf(&req_buffer, "?%s", query); + } if(result) return result; result = - Curl_add_bufferf(req_buffer, + Curl_add_bufferf(&req_buffer, "%s" /* ftp typecode (;type=x) */ " HTTP/%s\r\n" /* HTTP version */ "%s" /* host */ @@ -2507,7 +2538,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) co = Curl_cookie_getlist(data->cookies, conn->allocptr.cookiehost? conn->allocptr.cookiehost:host, - data->state.path, + data->state.up.path, (conn->handler->protocol&CURLPROTO_HTTPS)? TRUE:FALSE); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); @@ -2518,11 +2549,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) while(co) { if(co->value) { if(0 == count) { - result = Curl_add_bufferf(req_buffer, "Cookie: "); + result = Curl_add_bufferf(&req_buffer, "Cookie: "); if(result) break; } - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "%s%s=%s", count?"; ":"", co->name, co->value); if(result) @@ -2535,15 +2566,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } if(addcookies && !result) { if(!count) - result = Curl_add_bufferf(req_buffer, "Cookie: "); + result = Curl_add_bufferf(&req_buffer, "Cookie: "); if(!result) { - result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"", + result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"", addcookies); count++; } } if(count && !result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; @@ -2577,7 +2608,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if((postsize != -1) && !data->req.upload_chunky && (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* only add Content-Length if not uploading chunked */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2590,7 +2621,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */ if(result) return result; @@ -2598,7 +2629,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) Curl_pgrsSetUploadSize(data, postsize); /* this sends the buffer and frees all the buffer resources */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending PUT request"); @@ -2616,11 +2647,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* This is form posting using mime data. */ if(conn->bits.authneg) { /* nothing to post! */ - result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n"); + result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n"); if(result) return result; - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending POST request"); @@ -2640,7 +2671,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2652,7 +2683,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) struct curl_slist *hdr; for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) { - result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data); + result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data); if(result) return result; } @@ -2676,7 +2707,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) data->state.expect100header = FALSE; /* make the request end in a true CRLF */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; @@ -2689,7 +2720,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http->sending = HTTPSEND_BODY; /* this sends the buffer and frees all the buffer resources */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending POST request"); @@ -2719,7 +2750,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2727,7 +2758,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } if(!Curl_checkheaders(conn, "Content-Type")) { - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Type: application/" "x-www-form-urlencoded\r\n"); if(result) @@ -2765,31 +2796,31 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) is no magic limit but only set to prevent really huge POSTs to get the data duplicated with malloc() and family. */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; if(!data->req.upload_chunky) { /* We're not sending it 'chunked', append it to the request already now to reduce the number if send() calls */ - result = Curl_add_buffer(req_buffer, data->set.postfields, + result = Curl_add_buffer(&req_buffer, data->set.postfields, (size_t)postsize); included_body = postsize; } else { if(postsize) { /* Append the POST data chunky-style */ - result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize); + result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize); if(!result) { - result = Curl_add_buffer(req_buffer, data->set.postfields, + result = Curl_add_buffer(&req_buffer, data->set.postfields, (size_t)postsize); if(!result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); included_body = postsize + 2; } } if(!result) - result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); + result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); /* 0 CR LF CR LF */ included_body += 5; } @@ -2811,20 +2842,20 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* set the upload size to the progress meter */ Curl_pgrsSetUploadSize(data, http->postsize); - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; } } else { - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; if(data->req.upload_chunky && conn->bits.authneg) { /* Chunky upload is selected and we're negotiating auth still, send end-of-data only */ - result = Curl_add_buffer(req_buffer, + result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); /* 0 CR LF CR LF */ if(result) @@ -2845,7 +2876,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } } /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, (size_t)included_body, FIRSTSOCKET); if(result) @@ -2857,12 +2888,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) break; default: - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) @@ -3828,7 +3859,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, here, or else use real peer host name. */ conn->allocptr.cookiehost? conn->allocptr.cookiehost:conn->host.name, - data->state.path); + data->state.up.path); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } #endif diff --git a/lib/http.h b/lib/http.h index 1d373e8..21fa701 100644 --- a/lib/http.h +++ b/lib/http.h @@ -58,10 +58,12 @@ struct Curl_send_buffer { typedef struct Curl_send_buffer Curl_send_buffer; Curl_send_buffer *Curl_add_buffer_init(void); -void Curl_add_buffer_free(Curl_send_buffer *buff); -CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...); -CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size); -CURLcode Curl_add_buffer_send(Curl_send_buffer *in, +void Curl_add_buffer_free(Curl_send_buffer **inp); +CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...) + WARN_UNUSED_RESULT; +CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, + size_t size) WARN_UNUSED_RESULT; +CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, struct connectdata *conn, long *bytes_written, size_t included_body_bytes, @@ -154,9 +156,11 @@ struct HTTP { HTTPSEND_LAST /* never use this */ } sending; - void *send_buffer; /* used if the request couldn't be sent in one chunk, - points to an allocated send_buffer struct */ - +#ifndef CURL_DISABLE_HTTP + Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in + one chunk, points to an allocated + send_buffer struct */ +#endif #ifdef USE_NGHTTP2 /*********** for HTTP/2 we store stream-local data here *************/ int32_t stream_id; /* stream we are interested in */ @@ -253,4 +257,3 @@ Curl_http_output_auth(struct connectdata *conn, up the proxy tunnel */ #endif /* HEADER_CURL_HTTP_H */ - diff --git a/lib/http2.c b/lib/http2.c index d769193..0c5f6db 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -141,10 +141,8 @@ static int http2_getsock(struct connectdata *conn, static void http2_stream_free(struct HTTP *http) { if(http) { - Curl_add_buffer_free(http->header_recvbuf); - http->header_recvbuf = NULL; /* clear the pointer */ - Curl_add_buffer_free(http->trailer_recvbuf); - http->trailer_recvbuf = NULL; /* clear the pointer */ + Curl_add_buffer_free(&http->header_recvbuf); + Curl_add_buffer_free(&http->trailer_recvbuf); for(; http->push_headers_used > 0; --http->push_headers_used) { free(http->push_headers[http->push_headers_used - 1]); } @@ -203,7 +201,7 @@ static bool http2_connisdead(struct connectdata *conn) dead = !Curl_connalive(conn); if(!dead) { /* This happens before we've sent off a request and the connection is - not in use by any other thransfer, there shouldn't be any data here, + not in use by any other transfer, there shouldn't be any data here, only "protocol frames" */ CURLcode result; struct http_conn *httpc = &conn->proto.httpc; @@ -233,12 +231,43 @@ static unsigned int http2_conncheck(struct connectdata *check, unsigned int checks_to_perform) { unsigned int ret_val = CONNRESULT_NONE; + struct http_conn *c = &check->proto.httpc; + int rc; + bool send_frames = false; if(checks_to_perform & CONNCHECK_ISDEAD) { if(http2_connisdead(check)) ret_val |= CONNRESULT_DEAD; } + if(checks_to_perform & CONNCHECK_KEEPALIVE) { + struct curltime now = Curl_now(); + time_t elapsed = Curl_timediff(now, check->keepalive); + + if(elapsed > check->upkeep_interval_ms) { + /* Perform an HTTP/2 PING */ + rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL); + if(!rc) { + /* Successfully added a PING frame to the session. Need to flag this + so the frame is sent. */ + send_frames = true; + } + else { + failf(check->data, "nghttp2_submit_ping() failed: %s(%d)", + nghttp2_strerror(rc), rc); + } + + check->keepalive = now; + } + } + + if(send_frames) { + rc = nghttp2_session_send(c->h2); + if(rc) + failf(check->data, "nghttp2_session_send() failed: %s(%d)", + nghttp2_strerror(rc), rc); + } + return ret_val; } @@ -599,6 +628,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, int rv; size_t left, ncopy; int32_t stream_id = frame->hd.stream_id; + CURLcode result; if(!stream_id) { /* stream ID zero is for connection-oriented stuff */ @@ -674,7 +704,9 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, stream->status_code = -1; } - Curl_add_buffer(stream->header_recvbuf, "\r\n", 2); + result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf; ncopy = CURLMIN(stream->len, left); @@ -898,6 +930,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, struct Curl_easy *data_s; int32_t stream_id = frame->hd.stream_id; struct connectdata *conn = (struct connectdata *)userp; + CURLcode result; (void)flags; DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ @@ -924,6 +957,8 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * sizeof(char *)); + if(!stream->push_headers) + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; stream->push_headers_used = 0; } else if(stream->push_headers_used == @@ -952,11 +987,21 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, value)); - Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n)); - Curl_add_buffer(stream->trailer_recvbuf, name, namelen); - Curl_add_buffer(stream->trailer_recvbuf, ": ", 2); - Curl_add_buffer(stream->trailer_recvbuf, value, valuelen); - Curl_add_buffer(stream->trailer_recvbuf, "\r\n\0", 3); + result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n)); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; return 0; } @@ -969,10 +1014,16 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, stream->status_code = decode_status_code(value, valuelen); DEBUGASSERT(stream->status_code != -1); - Curl_add_buffer(stream->header_recvbuf, "HTTP/2 ", 7); - Curl_add_buffer(stream->header_recvbuf, value, valuelen); + result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; /* the space character after the status code is mandatory */ - Curl_add_buffer(stream->header_recvbuf, " \r\n", 3); + result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; /* if we receive data for another handle, wake that up */ if(conn->data != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); @@ -985,10 +1036,18 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, /* nghttp2 guarantees that namelen > 0, and :status was already received, and this is not pseudo-header field . */ /* convert to a HTTP1-style header */ - Curl_add_buffer(stream->header_recvbuf, name, namelen); - Curl_add_buffer(stream->header_recvbuf, ": ", 2); - Curl_add_buffer(stream->header_recvbuf, value, valuelen); - Curl_add_buffer(stream->header_recvbuf, "\r\n", 2); + result = Curl_add_buffer(&stream->header_recvbuf, name, namelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; /* if we receive data for another handle, wake that up */ if(conn->data != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); @@ -1049,7 +1108,8 @@ static ssize_t data_source_read_callback(nghttp2_session *session, return nread; } -#ifdef NGHTTP2_HAS_ERROR_CALLBACK +#if defined(NGHTTP2_HAS_ERROR_CALLBACK) && \ + !defined(CURL_DISABLE_VERBOSE_STRINGS) static int error_callback(nghttp2_session *session, const char *msg, size_t len, @@ -1085,17 +1145,11 @@ void Curl_http2_done(struct connectdata *conn, bool premature) struct HTTP *http = data->req.protop; struct http_conn *httpc = &conn->proto.httpc; - if(!httpc->h2) /* not HTTP/2 ? */ - return; - - if(data->state.drain) - drained_transfer(data, httpc); - + /* there might be allocated resources done before this got the 'h2' pointer + setup */ if(http->header_recvbuf) { - Curl_add_buffer_free(http->header_recvbuf); - http->header_recvbuf = NULL; /* clear the pointer */ - Curl_add_buffer_free(http->trailer_recvbuf); - http->trailer_recvbuf = NULL; /* clear the pointer */ + Curl_add_buffer_free(&http->header_recvbuf); + Curl_add_buffer_free(&http->trailer_recvbuf); if(http->push_headers) { /* if they weren't used and then freed before */ for(; http->push_headers_used > 0; --http->push_headers_used) { @@ -1106,6 +1160,12 @@ void Curl_http2_done(struct connectdata *conn, bool premature) } } + if(!httpc->h2) /* not HTTP/2 ? */ + return; + + if(data->state.drain) + drained_transfer(data, httpc); + if(premature) { /* RST_STREAM */ if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, @@ -1167,7 +1227,9 @@ CURLcode Curl_http2_init(struct connectdata *conn) /* nghttp2_on_header_callback */ nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header); +#ifndef CURL_DISABLE_VERBOSE_STRINGS nghttp2_session_callbacks_set_error_callback(callbacks, error_callback); +#endif /* The nghttp2 session is not yet setup, do it */ rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); @@ -1204,7 +1266,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, httpc->local_settings_num); if(!binlen) { failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload"); - Curl_add_buffer_free(req); + Curl_add_buffer_free(&req); return CURLE_FAILED_INIT; } conn->proto.httpc.binlen = binlen; @@ -1212,11 +1274,11 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen, &base64, &blen); if(result) { - Curl_add_buffer_free(req); + Curl_add_buffer_free(&req); return result; } - result = Curl_add_bufferf(req, + result = Curl_add_bufferf(&req, "Connection: Upgrade, HTTP2-Settings\r\n" "Upgrade: %s\r\n" "HTTP2-Settings: %s\r\n", @@ -2060,8 +2122,11 @@ CURLcode Curl_http2_setup(struct connectdata *conn) stream->stream_id = -1; - if(!stream->header_recvbuf) + if(!stream->header_recvbuf) { stream->header_recvbuf = Curl_add_buffer_init(); + if(!stream->header_recvbuf) + return CURLE_OUT_OF_MEMORY; + } if((conn->handler == &Curl_handler_http2_ssl) || (conn->handler == &Curl_handler_http2)) @@ -2073,8 +2138,10 @@ CURLcode Curl_http2_setup(struct connectdata *conn) conn->handler = &Curl_handler_http2; result = Curl_http2_init(conn); - if(result) + if(result) { + Curl_add_buffer_free(&stream->header_recvbuf); return result; + } infof(conn->data, "Using HTTP2, server supports multi-use\n"); stream->upload_left = 0; diff --git a/lib/http2.h b/lib/http2.h index 21cd9b8..4492ec2 100644 --- a/lib/http2.h +++ b/lib/http2.h @@ -77,4 +77,3 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data); #endif #endif /* HEADER_CURL_HTTP2_H */ - diff --git a/lib/http_chunks.h b/lib/http_chunks.h index 3a8b4dd..b969c55 100644 --- a/lib/http_chunks.h +++ b/lib/http_chunks.h @@ -88,4 +88,3 @@ struct Curl_chunker { }; #endif /* HEADER_CURL_HTTP_CHUNKS_H */ - diff --git a/lib/http_proxy.c b/lib/http_proxy.c index c8c445b..2e0d92e 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -222,7 +222,7 @@ static CURLcode CONNECT(struct connectdata *conn, host_port = aprintf("%s:%d", hostname, remote_port); if(!host_port) { - Curl_add_buffer_free(req_buffer); + Curl_add_buffer_free(&req_buffer); return CURLE_OUT_OF_MEMORY; } @@ -247,7 +247,7 @@ static CURLcode CONNECT(struct connectdata *conn, aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", remote_port); if(!hostheader) { - Curl_add_buffer_free(req_buffer); + Curl_add_buffer_free(&req_buffer); return CURLE_OUT_OF_MEMORY; } @@ -255,7 +255,7 @@ static CURLcode CONNECT(struct connectdata *conn, host = aprintf("Host: %s\r\n", hostheader); if(!host) { free(hostheader); - Curl_add_buffer_free(req_buffer); + Curl_add_buffer_free(&req_buffer); return CURLE_OUT_OF_MEMORY; } } @@ -267,7 +267,7 @@ static CURLcode CONNECT(struct connectdata *conn, useragent = conn->allocptr.uagent; result = - Curl_add_bufferf(req_buffer, + Curl_add_bufferf(&req_buffer, "CONNECT %s HTTP/%s\r\n" "%s" /* Host: */ "%s" /* Proxy-Authorization */ @@ -290,13 +290,13 @@ static CURLcode CONNECT(struct connectdata *conn, if(!result) /* CRLF terminate the request */ - result = Curl_add_bufferf(req_buffer, "\r\n"); + result = Curl_add_bufferf(&req_buffer, "\r\n"); if(!result) { /* Send the connect request to the proxy */ /* BLOCKING */ result = - Curl_add_buffer_send(req_buffer, conn, + Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, sockindex); } req_buffer = NULL; @@ -304,7 +304,7 @@ static CURLcode CONNECT(struct connectdata *conn, failf(data, "Failed sending CONNECT to proxy"); } - Curl_add_buffer_free(req_buffer); + Curl_add_buffer_free(&req_buffer); if(result) return result; diff --git a/lib/imap.c b/lib/imap.c index 942fe7d..3ef8909 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -159,7 +159,8 @@ const struct Curl_handler Curl_handler_imaps = { ZERO_NULL, /* connection_check */ PORT_IMAPS, /* defport */ CURLPROTO_IMAPS, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */ + PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ + PROTOPT_URLOPTIONS }; #endif @@ -421,7 +422,6 @@ static CURLcode imap_perform_capability(struct connectdata *conn) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; - imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ imapc->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ imapc->tls_supported = FALSE; /* Clear the TLS capability */ @@ -683,24 +683,37 @@ static CURLcode imap_perform_fetch(struct connectdata *conn) { CURLcode result = CURLE_OK; struct IMAP *imap = conn->data->req.protop; - /* Check we have a UID */ - if(!imap->uid) { - failf(conn->data, "Cannot FETCH without a UID."); - return CURLE_URL_MALFORMAT; + if(imap->uid) { + + /* Send the FETCH command */ + if(imap->partial) + result = imap_sendf(conn, "UID FETCH %s BODY[%s]<%s>", + imap->uid, + imap->section ? imap->section : "", + imap->partial); + else + result = imap_sendf(conn, "UID FETCH %s BODY[%s]", + imap->uid, + imap->section ? imap->section : ""); + } + else if(imap->mindex) { + + /* Send the FETCH command */ + if(imap->partial) + result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>", + imap->mindex, + imap->section ? imap->section : "", + imap->partial); + else + result = imap_sendf(conn, "FETCH %s BODY[%s]", + imap->mindex, + imap->section ? imap->section : ""); + } + else { + failf(conn->data, "Cannot FETCH without a UID."); + return CURLE_URL_MALFORMAT; } - - /* Send the FETCH command */ - if(imap->partial) - result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>", - imap->uid, - imap->section ? imap->section : "", - imap->partial); - else - result = imap_sendf(conn, "FETCH %s BODY[%s]", - imap->uid, - imap->section ? imap->section : ""); - if(!result) state(conn, IMAP_FETCH); @@ -1464,9 +1477,10 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, result = status; /* use the already set error code */ } else if(!data->set.connect_only && !imap->custom && - (imap->uid || data->set.upload || + (imap->uid || imap->mindex || data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)) { /* Handle responses after FETCH or APPEND transfer has finished */ + if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE) state(conn, IMAP_FETCH_FINAL); else { @@ -1490,6 +1504,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, Curl_safefree(imap->mailbox); Curl_safefree(imap->uidvalidity); Curl_safefree(imap->uid); + Curl_safefree(imap->mindex); Curl_safefree(imap->section); Curl_safefree(imap->partial); Curl_safefree(imap->query); @@ -1543,14 +1558,14 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected, else if(imap->custom && (selected || !imap->mailbox)) /* Custom command using the same mailbox or no mailbox */ result = imap_perform_list(conn); - else if(!imap->custom && selected && imap->uid) + else if(!imap->custom && selected && (imap->uid || imap->mindex)) /* FETCH from the same mailbox */ result = imap_perform_fetch(conn); else if(!imap->custom && selected && imap->query) /* SEARCH the current mailbox */ result = imap_perform_search(conn); else if(imap->mailbox && !selected && - (imap->custom || imap->uid || imap->query)) + (imap->custom || imap->uid || imap->mindex || imap->query)) /* SELECT the mailbox */ result = imap_perform_select(conn); else @@ -1702,8 +1717,6 @@ static CURLcode imap_regular_transfer(struct connectdata *conn, static CURLcode imap_setup_connection(struct connectdata *conn) { - struct Curl_easy *data = conn->data; - /* Initialise the IMAP layer */ CURLcode result = imap_init(conn); if(result) @@ -1711,7 +1724,6 @@ static CURLcode imap_setup_connection(struct connectdata *conn) /* Clear the TLS upgraded flag */ conn->tls_upgraded = FALSE; - data->state.path++; /* don't include the initial slash */ return CURLE_OK; } @@ -1944,7 +1956,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; struct IMAP *imap = data->req.protop; - const char *begin = data->state.path; + const char *begin = &data->state.up.path[1]; /* skip leading slash */ const char *ptr = begin; /* See how much of the URL is a valid path and decode it */ @@ -2016,6 +2028,13 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) imap->uid = value; value = NULL; } + else if(strcasecompare(name, "MAILINDEX") && !imap->mindex) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->mindex = value; + value = NULL; + } else if(strcasecompare(name, "SECTION") && !imap->section) { if(valuelen > 0 && value[valuelen - 1] == '/') value[valuelen - 1] = '\0'; @@ -2043,17 +2062,10 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) /* Does the URL contain a query parameter? Only valid when we have a mailbox and no UID as per RFC-5092 */ - if(imap->mailbox && !imap->uid && *ptr == '?') { - /* Find the length of the query parameter */ - begin = ++ptr; - while(imap_is_bchar(*ptr)) - ptr++; - - /* Decode the query parameter */ - result = Curl_urldecode(data, begin, ptr - begin, &imap->query, NULL, - TRUE); - if(result) - return result; + if(imap->mailbox && !imap->uid && !imap->mindex) { + /* Get the query parameter, URL decoded */ + (void)curl_url_get(data->state.uh, CURLUPART_QUERY, &imap->query, + CURLU_URLDECODE); } /* Any extra stuff at the end of the URL is an error */ diff --git a/lib/imap.h b/lib/imap.h index 9fc4ff5..0efcfd2 100644 --- a/lib/imap.h +++ b/lib/imap.h @@ -58,6 +58,7 @@ struct IMAP { char *mailbox; /* Mailbox to select */ char *uidvalidity; /* UIDVALIDITY to check in select */ char *uid; /* Message UID to fetch */ + char *mindex; /* Index in mail box of mail to fetch */ char *section; /* Message SECTION to fetch */ char *partial; /* Message PARTIAL to fetch */ char *query; /* Query to search for */ diff --git a/lib/inet_ntop.h b/lib/inet_ntop.h index 9f44612..d150bb6 100644 --- a/lib/inet_ntop.h +++ b/lib/inet_ntop.h @@ -35,4 +35,3 @@ char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); #endif #endif /* HEADER_CURL_INET_NTOP_H */ - diff --git a/lib/inet_pton.h b/lib/inet_pton.h index e216f4e..0209b9b 100644 --- a/lib/inet_pton.h +++ b/lib/inet_pton.h @@ -37,4 +37,3 @@ int Curl_inet_pton(int, const char *, void *); #endif #endif /* HEADER_CURL_INET_PTON_H */ - diff --git a/lib/krb5.c b/lib/krb5.c index 59c0d71..147ab02 100644 --- a/lib/krb5.c +++ b/lib/krb5.c @@ -206,7 +206,7 @@ krb5_auth(void *app_data, struct connectdata *conn) if(maj != GSS_S_COMPLETE) { gss_release_name(&min, &gssname); if(service == srv_host) { - Curl_failf(data, "Error importing service name %s@%s", service, host); + failf(data, "Error importing service name %s@%s", service, host); return AUTH_ERROR; } service = srv_host; @@ -265,6 +265,7 @@ krb5_auth(void *app_data, struct connectdata *conn) result = CURLE_OUT_OF_MEMORY; free(p); + free(cmd); if(result) { ret = -2; @@ -290,8 +291,7 @@ krb5_auth(void *app_data, struct connectdata *conn) (unsigned char **)&_gssresp.value, &_gssresp.length); if(result) { - Curl_failf(data, "base64-decoding: %s", - curl_easy_strerror(result)); + failf(data, "base64-decoding: %s", curl_easy_strerror(result)); ret = AUTH_CONTINUE; break; } diff --git a/lib/ldap.c b/lib/ldap.c index 4d8f4fa..ceaa71d 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -474,7 +474,13 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) #endif } if(rc != 0) { - failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc)); +#ifdef USE_WIN32_LDAP + failf(data, "LDAP local: bind via ldap_win_bind %s", + ldap_err2string(rc)); +#else + failf(data, "LDAP local: bind via ldap_simple_bind_s %s", + ldap_err2string(rc)); +#endif result = CURLE_LDAP_CANNOT_BIND; goto quit; } @@ -838,9 +844,9 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp) size_t i; if(!conn->data || - !conn->data->state.path || - conn->data->state.path[0] != '/' || - !checkprefix("LDAP", conn->data->change.url)) + !conn->data->state.up.path || + conn->data->state.up.path[0] != '/' || + !strcasecompare("LDAP", conn->data->state.up.scheme)) return LDAP_INVALID_SYNTAX; ludp->lud_scope = LDAP_SCOPE_BASE; @@ -848,7 +854,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp) ludp->lud_host = conn->host.name; /* Duplicate the path */ - p = path = strdup(conn->data->state.path + 1); + p = path = strdup(conn->data->state.up.path + 1); if(!path) return LDAP_NO_MEMORY; diff --git a/lib/llist.h b/lib/llist.h index 6b644b9..b9d4c89 100644 --- a/lib/llist.h +++ b/lib/llist.h @@ -51,4 +51,3 @@ void Curl_llist_move(struct curl_llist *, struct curl_llist_element *, struct curl_llist *, struct curl_llist_element *); #endif /* HEADER_CURL_LLIST_H */ - diff --git a/lib/md4.c b/lib/md4.c index 2bb7dcc..d350602 100644 --- a/lib/md4.c +++ b/lib/md4.c @@ -3,7 +3,7 @@ * MD4 Message-Digest Algorithm (RFC 1320). * * Homepage: - http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 + https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 * * Author: * Alexander Peslyak, better known as Solar Designer diff --git a/lib/md5.c b/lib/md5.c index b819d39..45f45bb 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -177,7 +177,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) * MD5 Message-Digest Algorithm (RFC 1321). * * Homepage: - http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 * * Author: * Alexander Peslyak, better known as Solar Designer diff --git a/lib/multi.c b/lib/multi.c index 0caf943..0db2a97 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -347,6 +347,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ Curl_llist_init(&multi->pending, multi_freeamsg); multi->max_pipeline_length = 5; + multi->pipelining = CURLPIPE_MULTIPLEX; /* -1 means it not set by user, use the default value */ multi->maxconnects = -1; @@ -491,6 +492,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->state.conn_cache->closure_handle->set.timeout = data->set.timeout; data->state.conn_cache->closure_handle->set.server_response_timeout = data->set.server_response_timeout; + data->state.conn_cache->closure_handle->set.no_signal = + data->set.no_signal; update_timer(multi); return CURLM_OK; @@ -541,10 +544,8 @@ static CURLcode multi_done(struct connectdata **connp, Curl_getoff_all_pipelines(data, conn); /* Cleanup possible redirect junk */ - free(data->req.newurl); - data->req.newurl = NULL; - free(data->req.location); - data->req.location = NULL; + Curl_safefree(data->req.newurl); + Curl_safefree(data->req.location); switch(status) { case CURLE_ABORTED_BY_CALLBACK: @@ -656,7 +657,6 @@ static CURLcode multi_done(struct connectdata **connp, cache here, and therefore cannot be used from this point on */ Curl_free_request_state(data); - return result; } @@ -905,7 +905,7 @@ static int multi_getsock(struct Curl_easy *data, return 0; case CURLM_STATE_WAITRESOLVE: - return Curl_resolver_getsock(data->easy_conn, socks, numsocks); + return Curl_resolv_getsock(data->easy_conn, socks, numsocks); case CURLM_STATE_PROTOCONNECT: case CURLM_STATE_SENDPROTOCONNECT: @@ -1009,13 +1009,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - /* If the internally desired timeout is actually shorter than requested from - the outside, then use the shorter time! But only if the internal timer - is actually larger than -1! */ - (void)multi_timeout(multi, &timeout_internal); - if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) - timeout_ms = (int)timeout_internal; - /* Count up how many fds we have from the multi handle */ data = multi->easyp; while(data) { @@ -1040,6 +1033,13 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, data = data->next; /* check next handle */ } + /* If the internally desired timeout is actually shorter than requested from + the outside, then use the shorter time! But only if the internal timer + is actually larger than -1! */ + (void)multi_timeout(multi, &timeout_internal); + if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) + timeout_ms = (int)timeout_internal; + curlfds = nfds; /* number of internal file descriptors */ nfds += extra_nfds; /* add the externally provided ones */ @@ -1235,7 +1235,7 @@ static CURLcode multi_reconnect_request(struct connectdata **connp) return result; /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn, &protocol_done); + result = Curl_once_resolved(conn, &protocol_done); if(result) return result; } @@ -1511,7 +1511,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(!dns) - result = Curl_resolver_is_resolved(data->easy_conn, &dns); + result = Curl_resolv_check(data->easy_conn, &dns); /* Update sockets here, because the socket(s) may have been closed and the application thus needs to be told, even if it @@ -1524,10 +1524,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(dns) { /* Perform the next step in the connection phase, and then move on to the WAITCONNECT state */ - result = Curl_async_resolved(data->easy_conn, &protocol_connect); + result = Curl_once_resolved(data->easy_conn, &protocol_connect); if(result) - /* if Curl_async_resolved() returns failure, the connection struct + /* if Curl_once_resolved() returns failure, the connection struct is already freed and gone */ data->easy_conn = NULL; /* no more connection */ else { @@ -1608,7 +1608,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_SENDPROTOCONNECT: result = Curl_protocol_connect(data->easy_conn, &protocol_connect); - if(!protocol_connect) + if(!result && !protocol_connect) /* switch to waiting state */ multistate(data, CURLM_STATE_PROTOCONNECT); else if(!result) { @@ -1707,7 +1707,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, char *newurl = NULL; followtype follow = FOLLOW_NONE; CURLcode drc; - bool retry = FALSE; drc = Curl_retry_request(data->easy_conn, &newurl); if(drc) { @@ -1715,15 +1714,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, result = drc; stream_error = TRUE; } - else - retry = (newurl)?TRUE:FALSE; Curl_posttransfer(data); drc = multi_done(&data->easy_conn, result, FALSE); /* When set to retry the connection, we must to go back to * the CONNECT state */ - if(retry) { + if(newurl) { if(!drc || (drc == CURLE_SEND_ERROR)) { follow = FOLLOW_RETRY; drc = Curl_follow(data, newurl, follow); @@ -1993,6 +1990,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_CALL_MULTI_PERFORM; } } + free(newurl); } else { /* after the transfer is done, go DONE */ @@ -2004,18 +2002,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, newurl = data->req.location; data->req.location = NULL; result = Curl_follow(data, newurl, FOLLOW_FAKE); - if(result) + free(newurl); + if(result) { stream_error = TRUE; + result = multi_done(&data->easy_conn, result, TRUE); + } } - multistate(data, CURLM_STATE_DONE); - rc = CURLM_CALL_MULTI_PERFORM; + if(!result) { + multistate(data, CURLM_STATE_DONE); + rc = CURLM_CALL_MULTI_PERFORM; + } } } else if(comeback) rc = CURLM_CALL_MULTI_PERFORM; - - free(newurl); break; } @@ -2131,15 +2132,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(CURLM_STATE_COMPLETED == data->mstate) { - /* now fill in the Curl_message with this info */ - msg = &data->msg; + if(data->set.fmultidone) { + /* signal via callback instead */ + data->set.fmultidone(data, result); + } + else { + /* now fill in the Curl_message with this info */ + msg = &data->msg; - msg->extmsg.msg = CURLMSG_DONE; - msg->extmsg.easy_handle = data; - msg->extmsg.data.result = result; + msg->extmsg.msg = CURLMSG_DONE; + msg->extmsg.easy_handle = data; + msg->extmsg.data.result = result; - rc = multi_addmsg(multi, msg); - DEBUGASSERT(!data->easy_conn); + rc = multi_addmsg(multi, msg); + DEBUGASSERT(!data->easy_conn); + } multistate(data, CURLM_STATE_MSGSENT); } } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); @@ -2705,7 +2712,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, multi->push_userp = va_arg(param, void *); break; case CURLMOPT_PIPELINING: - multi->pipelining = va_arg(param, long); + multi->pipelining = va_arg(param, long) & CURLPIPE_MULTIPLEX; break; case CURLMOPT_TIMERFUNCTION: multi->timer_cb = va_arg(param, curl_multi_timer_callback); diff --git a/lib/netrc.c b/lib/netrc.c index a407bda..1724b35 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -57,7 +57,11 @@ int Curl_parsenetrc(const char *host, { FILE *file; int retcode = 1; - int specific_login = (*loginp && **loginp != 0); + char *login = *loginp; + char *password = *passwordp; + bool specific_login = (login && *login != 0); + bool login_alloc = FALSE; + bool password_alloc = FALSE; bool netrc_alloc = FALSE; enum host_lookup_state state = NOTHING; @@ -125,7 +129,7 @@ int Curl_parsenetrc(const char *host, continue; while(!done && tok) { - if((*loginp && **loginp) && (*passwordp && **passwordp)) { + if((login && *login) && (password && *password)) { done = TRUE; break; } @@ -158,26 +162,34 @@ int Curl_parsenetrc(const char *host, /* we are now parsing sub-keywords concerning "our" host */ if(state_login) { if(specific_login) { - state_our_login = strcasecompare(*loginp, tok); + state_our_login = strcasecompare(login, tok); } else { - free(*loginp); - *loginp = strdup(tok); - if(!*loginp) { + if(login_alloc) { + free(login); + login_alloc = FALSE; + } + login = strdup(tok); + if(!login) { retcode = -1; /* allocation failed */ goto out; } + login_alloc = TRUE; } state_login = 0; } else if(state_password) { if(state_our_login || !specific_login) { - free(*passwordp); - *passwordp = strdup(tok); - if(!*passwordp) { + if(password_alloc) { + free(password); + password_alloc = FALSE; + } + password = strdup(tok); + if(!password) { retcode = -1; /* allocation failed */ goto out; } + password_alloc = TRUE; } state_password = 0; } @@ -198,6 +210,24 @@ int Curl_parsenetrc(const char *host, } /* while fgets() */ out: + if(!retcode) { + if(login_alloc) { + if(*loginp) + free(*loginp); + *loginp = login; + } + if(password_alloc) { + if(*passwordp) + free(*passwordp); + *passwordp = password; + } + } + else { + if(login_alloc) + free(login); + if(password_alloc) + free(password); + } fclose(file); } diff --git a/lib/nonblock.c b/lib/nonblock.c index 5959281..4d105c1 100644 --- a/lib/nonblock.c +++ b/lib/nonblock.c @@ -48,7 +48,8 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */) { #if defined(USE_BLOCKING_SOCKETS) - + (void)sockfd; + (void)nonblock; return 0; /* returns success */ #elif defined(HAVE_FCNTL_O_NONBLOCK) diff --git a/lib/nonblock.h b/lib/nonblock.h index 98cdc25..eb18ea1 100644 --- a/lib/nonblock.h +++ b/lib/nonblock.h @@ -28,4 +28,3 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */); #endif /* HEADER_CURL_NONBLOCK_H */ - diff --git a/lib/nwlib.c b/lib/nwlib.c index 215d933..7bf5f51 100644 --- a/lib/nwlib.c +++ b/lib/nwlib.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -195,7 +195,7 @@ int GetOrSetUpData(int id, libdata_t **appData, if(!app_data->tenbytes || !app_data->lock) { if(app_data->lock) NXMutexFree(app_data->lock); - + free(app_data->tenbytes); free(app_data); app_data = (libdata_t *) NULL; err = ENOMEM; @@ -213,6 +213,9 @@ int GetOrSetUpData(int id, libdata_t **appData, err = set_app_data(gLibId, app_data); if(err) { + if(app_data->lock) + NXMutexFree(app_data->lock); + free(app_data->tenbytes); free(app_data); app_data = (libdata_t *) NULL; err = ENOMEM; diff --git a/lib/parsedate.h b/lib/parsedate.h index 2e59eb1..8dc3b90 100644 --- a/lib/parsedate.h +++ b/lib/parsedate.h @@ -28,4 +28,3 @@ extern const char * const Curl_month[12]; CURLcode Curl_gmtime(time_t intime, struct tm *store); #endif /* HEADER_CURL_PARSEDATE_H */ - diff --git a/lib/pop3.c b/lib/pop3.c index cd994f6..5e0fd22 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -1303,8 +1303,6 @@ static CURLcode pop3_regular_transfer(struct connectdata *conn, static CURLcode pop3_setup_connection(struct connectdata *conn) { - struct Curl_easy *data = conn->data; - /* Initialise the POP3 layer */ CURLcode result = pop3_init(conn); if(result) @@ -1312,7 +1310,6 @@ static CURLcode pop3_setup_connection(struct connectdata *conn) /* Clear the TLS upgraded flag */ conn->tls_upgraded = FALSE; - data->state.path++; /* don't include the initial slash */ return CURLE_OK; } @@ -1387,7 +1384,7 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn) /* The POP3 struct is already initialised in pop3_connect() */ struct Curl_easy *data = conn->data; struct POP3 *pop3 = data->req.protop; - const char *path = data->state.path; + const char *path = &data->state.up.path[1]; /* skip leading path */ /* URL decode the path for the message ID */ return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE); diff --git a/lib/progress.h b/lib/progress.h index 92dbcbd..3515ac6 100644 --- a/lib/progress.h +++ b/lib/progress.h @@ -62,4 +62,3 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, #define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */ #endif /* HEADER_CURL_PROGRESS_H */ - diff --git a/lib/rand.c b/lib/rand.c index 1dc2504..6ee45fe 100644 --- a/lib/rand.c +++ b/lib/rand.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -174,6 +174,8 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, return result; while(num) { + /* clang-tidy warns on this line without this comment: */ + /* NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult) */ *rnd++ = hex[(*bufp & 0xF0)>>4]; *rnd++ = hex[*bufp & 0x0F]; bufp++; diff --git a/lib/rtsp.c b/lib/rtsp.c index 182ee29..01dfce6 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -462,7 +462,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) return CURLE_OUT_OF_MEMORY; result = - Curl_add_bufferf(req_buffer, + Curl_add_bufferf(&req_buffer, "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */ "CSeq: %ld\r\n", /* CSeq */ p_request, p_stream_uri, rtsp->CSeq_sent); @@ -474,7 +474,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) * to make comparison easier */ if(p_session_id) { - result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id); + result = Curl_add_bufferf(&req_buffer, "Session: %s\r\n", p_session_id); if(result) return result; } @@ -482,7 +482,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* * Shared HTTP-like options */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "%s" /* transport */ "%s" /* accept */ "%s" /* accept-encoding */ @@ -541,9 +541,10 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* As stated in the http comments, it is probably not wise to * actually set a custom Content-Length in the headers */ if(!Curl_checkheaders(conn, "Content-Length")) { - result = Curl_add_bufferf(req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", - (data->set.upload ? putsize : postsize)); + result = + Curl_add_bufferf(&req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", + (data->set.upload ? putsize : postsize)); if(result) return result; } @@ -551,8 +552,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) if(rtspreq == RTSPREQ_SET_PARAMETER || rtspreq == RTSPREQ_GET_PARAMETER) { if(!Curl_checkheaders(conn, "Content-Type")) { - result = Curl_add_bufferf(req_buffer, - "Content-Type: text/parameters\r\n"); + result = Curl_add_bufferf(&req_buffer, + "Content-Type: text/parameters\r\n"); if(result) return result; } @@ -560,8 +561,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) if(rtspreq == RTSPREQ_ANNOUNCE) { if(!Curl_checkheaders(conn, "Content-Type")) { - result = Curl_add_bufferf(req_buffer, - "Content-Type: application/sdp\r\n"); + result = Curl_add_bufferf(&req_buffer, + "Content-Type: application/sdp\r\n"); if(result) return result; } @@ -579,19 +580,19 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* RTSP never allows chunked transfer */ data->req.forbidchunk = TRUE; /* Finish the request buffer */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; if(postsize > 0) { - result = Curl_add_buffer(req_buffer, data->set.postfields, + result = Curl_add_buffer(&req_buffer, data->set.postfields, (size_t)postsize); if(result) return result; } /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) { failf(data, "Failed sending RTSP request"); diff --git a/lib/rtsp.h b/lib/rtsp.h index 8375a53..2f9cc32 100644 --- a/lib/rtsp.h +++ b/lib/rtsp.h @@ -64,4 +64,3 @@ struct RTSP { #endif /* HEADER_CURL_RTSP_H */ - diff --git a/lib/security.c b/lib/security.c index 4034115..c278406 100644 --- a/lib/security.c +++ b/lib/security.c @@ -61,7 +61,9 @@ #include "strcase.h" #include "warnless.h" #include "strdup.h" -/* The last #include file should be: */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" #include "memdebug.h" static const struct { @@ -422,7 +424,7 @@ static int sec_set_protection_level(struct connectdata *conn) if(!conn->sec_complete) { infof(conn->data, "Trying to change the protection level after the" - "completion of the data exchange.\n"); + " completion of the data exchange.\n"); return -1; } diff --git a/lib/select.h b/lib/select.h index 4351786..9a1ba45 100644 --- a/lib/select.h +++ b/lib/select.h @@ -113,4 +113,3 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, #endif #endif /* HEADER_CURL_SELECT_H */ - diff --git a/lib/sendf.h b/lib/sendf.h index 7627fe6..c68b017 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -36,7 +36,7 @@ void Curl_failf(struct Curl_easy *, const char *fmt, ...); #elif defined(HAVE_VARIADIC_MACROS_GCC) #define infof(x...) Curl_nop_stmt #else -#define infof (void) +#error "missing VARIADIC macro define, fix and rebuild!" #endif #else /* CURL_DISABLE_VERBOSE_STRINGS */ diff --git a/lib/setopt.c b/lib/setopt.c index 5c5f4b3..22956a2 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -127,9 +127,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, data->set.dns_cache_timeout = arg; break; case CURLOPT_DNS_USE_GLOBAL_CACHE: +#if 0 /* deprecated */ /* remember we want this enabled */ arg = va_arg(param, long); data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE; +#endif break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ @@ -841,6 +843,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, #else if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) return CURLE_UNSUPPORTED_PROTOCOL; + if(arg == CURL_HTTP_VERSION_NONE) + arg = CURL_HTTP_VERSION_2TLS; #endif data->set.httpversion = arg; break; @@ -1936,6 +1940,22 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, break; + case CURLOPT_UPLOAD_BUFFERSIZE: + /* + * The application kindly asks for a differently sized upload buffer. + * Cap it to sensible. + */ + arg = va_arg(param, long); + + if(arg > UPLOADBUFFER_MAX) + arg = UPLOADBUFFER_MAX; + else if(arg < UPLOADBUFFER_MIN) + arg = UPLOADBUFFER_MIN; + + data->set.upload_buffer_size = arg; + Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */ + break; + case CURLOPT_NOSIGNAL: /* * The application asks not to set any signal() or alarm() handlers, @@ -2599,6 +2619,17 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, data->set.disallow_username_in_url = (0 != va_arg(param, long)) ? TRUE : FALSE; break; + case CURLOPT_DOH_URL: + result = Curl_setstropt(&data->set.str[STRING_DOH], + va_arg(param, char *)); + data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE; + break; + case CURLOPT_UPKEEP_INTERVAL_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.upkeep_interval_ms = arg; + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; diff --git a/lib/slist.c b/lib/slist.c index e5adc0e..392b84d 100644 --- a/lib/slist.c +++ b/lib/slist.c @@ -142,4 +142,3 @@ void curl_slist_free_all(struct curl_slist *list) item = next; } while(next); } - diff --git a/lib/slist.h b/lib/slist.h index b3f498c..d73dbf6 100644 --- a/lib/slist.h +++ b/lib/slist.h @@ -37,4 +37,3 @@ struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data); #endif /* HEADER_CURL_SLIST_H */ - diff --git a/lib/smb.c b/lib/smb.c index e4b18fc..e4f266e 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -610,7 +610,8 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg) /* Check if there is data in the transfer buffer */ if(!smbc->send_size && smbc->upload_size) { - size_t nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE : + size_t nread = smbc->upload_size > conn->data->set.upload_buffer_size ? + conn->data->set.upload_buffer_size : smbc->upload_size; conn->data->req.upload_fromhere = conn->data->state.ulbuf; result = Curl_fillreadbuffer(conn, nread, &nread); @@ -968,7 +969,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn) char *slash; /* URL decode the path */ - result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE); + result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL, TRUE); if(result) return result; diff --git a/lib/smtp.c b/lib/smtp.c index ecf10a4..5875623 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1441,7 +1441,6 @@ static CURLcode smtp_regular_transfer(struct connectdata *conn, static CURLcode smtp_setup_connection(struct connectdata *conn) { - struct Curl_easy *data = conn->data; CURLcode result; /* Clear the TLS upgraded flag */ @@ -1452,8 +1451,6 @@ static CURLcode smtp_setup_connection(struct connectdata *conn) if(result) return result; - data->state.path++; /* don't include the initial slash */ - return CURLE_OK; } @@ -1507,7 +1504,7 @@ static CURLcode smtp_parse_url_path(struct connectdata *conn) /* The SMTP struct is already initialised in smtp_connect() */ struct Curl_easy *data = conn->data; struct smtp_conn *smtpc = &conn->proto.smtpc; - const char *path = data->state.path; + const char *path = &data->state.up.path[1]; /* skip leading path */ char localhost[HOSTNAME_MAX + 1]; /* Calculate the path if necessary */ @@ -1563,14 +1560,14 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) if(!scratch || data->set.crlf) { oldscratch = scratch; - scratch = newscratch = malloc(2 * UPLOAD_BUFSIZE); + scratch = newscratch = malloc(2 * data->set.upload_buffer_size); if(!newscratch) { failf(data, "Failed to alloc scratch buffer!"); return CURLE_OUT_OF_MEMORY; } } - DEBUGASSERT(UPLOAD_BUFSIZE >= nread); + DEBUGASSERT(data->set.upload_buffer_size >= (size_t)nread); /* Have we already sent part of the EOB? */ eob_sent = smtp->eob; diff --git a/lib/sockaddr.h b/lib/sockaddr.h index 95ba4c3..db14680 100644 --- a/lib/sockaddr.h +++ b/lib/sockaddr.h @@ -40,4 +40,3 @@ struct Curl_sockaddr_storage { }; #endif /* HEADER_CURL_SOCKADDR_H */ - diff --git a/lib/socks.c b/lib/socks.c index 81f3eda..d2209ad 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -98,7 +98,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ * destination server. * * Reference : -* http://socks.permeo.com/protocol/socks4.protocol +* https://www.openssh.com/txt/socks4.protocol * * Note : * Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" @@ -789,4 +789,3 @@ CURLcode Curl_SOCKS5(const char *proxy_user, } #endif /* CURL_DISABLE_PROXY */ - diff --git a/lib/socks.h b/lib/socks.h index 348707e..daa07c1 100644 --- a/lib/socks.h +++ b/lib/socks.h @@ -73,4 +73,3 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, #endif /* CURL_DISABLE_PROXY */ #endif /* HEADER_CURL_SOCKS_H */ - diff --git a/lib/splay.c b/lib/splay.c index c54a63b..baf07e0 100644 --- a/lib/splay.c +++ b/lib/splay.c @@ -274,4 +274,3 @@ int Curl_splayremovebyaddr(struct Curl_tree *t, return 0; } - diff --git a/lib/ssh.c b/lib/ssh.c index a4b2ca4..da89619 100644 --- a/lib/ssh.c +++ b/lib/ssh.c @@ -2926,7 +2926,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) int rc; ssh->kh = libssh2_knownhost_init(ssh->ssh_session); if(!ssh->kh) { - /* eeek. TODO: free the ssh_session! */ + libssh2_session_free(ssh->ssh_session); return CURLE_FAILED_INIT; } diff --git a/lib/strdup.c b/lib/strdup.c index 19cb044..51e7978 100644 --- a/lib/strdup.c +++ b/lib/strdup.c @@ -81,7 +81,7 @@ void *Curl_memdup(const void *src, size_t length) * Curl_saferealloc(ptr, size) * * Does a normal realloc(), but will free the data pointer if the realloc - * fails. If 'size' is zero, it will free the data and return a failure. + * fails. If 'size' is non-zero, it will free the data and return a failure. * * This convenience function is provided and used to help us avoid a common * mistake pattern when we could pass in a zero, catch the NULL return and end diff --git a/lib/strerror.c b/lib/strerror.c index 0295d6c..47ef44a 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -191,9 +191,6 @@ curl_easy_strerror(CURLcode error) case CURLE_TELNET_OPTION_SYNTAX : return "Malformed telnet option"; - case CURLE_PEER_FAILED_VERIFICATION: - return "SSL peer certificate or SSH remote key was not OK"; - case CURLE_GOT_NOTHING: return "Server returned nothing (no headers, no data)"; @@ -218,9 +215,8 @@ curl_easy_strerror(CURLcode error) case CURLE_SSL_CIPHER: return "Couldn't use specified SSL cipher"; - case CURLE_SSL_CACERT: - return "Peer certificate cannot be authenticated with given CA " - "certificates"; + case CURLE_PEER_FAILED_VERIFICATION: + return "SSL peer certificate or SSH remote key was not OK"; case CURLE_SSL_CACERT_BADFILE: return "Problem with the SSL CA cert (path? access rights?)"; @@ -324,6 +320,7 @@ curl_easy_strerror(CURLcode error) case CURLE_OBSOLETE44: case CURLE_OBSOLETE46: case CURLE_OBSOLETE50: + case CURLE_OBSOLETE51: case CURLE_OBSOLETE57: case CURL_LAST: break; diff --git a/lib/telnet.h b/lib/telnet.h index 419a399..668a78a 100644 --- a/lib/telnet.h +++ b/lib/telnet.h @@ -26,4 +26,3 @@ extern const struct Curl_handler Curl_handler_telnet; #endif #endif /* HEADER_CURL_TELNET_H */ - diff --git a/lib/tftp.c b/lib/tftp.c index e5bc80b..5b74e8e 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -485,7 +485,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) /* As RFC3617 describes the separator slash is not actually part of the file name so we skip the always-present first letter of the path string. */ - result = Curl_urldecode(data, &state->conn->data->state.path[1], 0, + result = Curl_urldecode(data, &state->conn->data->state.up.path[1], 0, &filename, NULL, FALSE); if(result) return result; @@ -1374,7 +1374,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn) /* TFTP URLs support an extension like ";mode=" that * we'll try to get now! */ - type = strstr(data->state.path, ";mode="); + type = strstr(data->state.up.path, ";mode="); if(!type) type = strstr(conn->host.rawalloc, ";mode="); diff --git a/lib/tftp.h b/lib/tftp.h index c2325b2..1335f64 100644 --- a/lib/tftp.h +++ b/lib/tftp.h @@ -26,4 +26,3 @@ extern const struct Curl_handler Curl_handler_tftp; #endif #endif /* HEADER_CURL_TFTP_H */ - diff --git a/lib/timeval.c b/lib/timeval.c index f4bf835..dce1a76 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,7 +33,8 @@ struct curltime Curl_now(void) */ struct curltime now; #if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) + (_WIN32_WINNT < _WIN32_WINNT_VISTA) || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) DWORD milliseconds = GetTickCount(); now.tv_sec = milliseconds / 1000; now.tv_usec = (milliseconds % 1000) * 1000; @@ -60,7 +61,23 @@ struct curltime Curl_now(void) struct timeval now; struct curltime cnow; struct timespec tsnow; - if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { + + /* + ** clock_gettime() may be defined by Apple's SDK as weak symbol thus + ** code compiles but fails during run-time if clock_gettime() is + ** called on unsupported OS version. + */ +#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) + bool have_clock_gettime = FALSE; + if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) + have_clock_gettime = TRUE; +#endif + + if( +#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) + have_clock_gettime && +#endif + (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) { cnow.tv_sec = tsnow.tv_sec; cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000); } diff --git a/lib/transfer.c b/lib/transfer.c index 7159d5c..b73f94d 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -75,6 +75,7 @@ #include "http2.h" #include "mime.h" #include "strcase.h" +#include "urlapi-int.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -362,7 +363,7 @@ static int data_pending(const struct connectdata *conn) return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || #if defined(USE_NGHTTP2) Curl_ssl_data_pending(conn, FIRSTSOCKET) || - /* For HTTP/2, we may read up everything including responde body + /* For HTTP/2, we may read up everything including response body with header fields in Curl_http_readwrite_headers. If no content-length is provided, curl waits for the connection close, which we emulate it using conn->proto.httpc.closed = @@ -566,7 +567,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, infof(data, "Rewinding stream by : %zd" " bytes on url %s (zero-length body)\n", - nread, data->state.path); + nread, data->state.up.path); read_rewind(conn, (size_t)nread); } else { @@ -574,7 +575,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, "Excess found in a non pipelined read:" " excess = %zd" " url = %s (zero-length body)\n", - nread, data->state.path); + nread, data->state.up.path); } } @@ -743,7 +744,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T ", maxdownload = %" CURL_FORMAT_CURL_OFF_T ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n", - excess, data->state.path, + excess, data->state.up.path, k->size, k->maxdownload, k->bytecount, nread); read_rewind(conn, excess); } @@ -878,7 +879,7 @@ static CURLcode done_sending(struct connectdata *conn, return CURLE_OK; } -#ifdef WIN32 +#if defined(WIN32) && !defined(USE_LWIPSOCK) #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B #endif @@ -959,7 +960,8 @@ static CURLcode readwrite_upload(struct Curl_easy *data, sending_http_headers = FALSE; } - result = Curl_fillreadbuffer(conn, UPLOAD_BUFSIZE, &fillcount); + result = Curl_fillreadbuffer(conn, data->set.upload_buffer_size, + &fillcount); if(result) return result; @@ -991,7 +993,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, (data->set.crlf))) { /* Do we need to allocate a scratch buffer? */ if(!data->state.scratch) { - data->state.scratch = malloc(2 * UPLOAD_BUFSIZE); + data->state.scratch = malloc(2 * data->set.upload_buffer_size); if(!data->state.scratch) { failf(data, "Failed to alloc scratch buffer!"); @@ -1453,314 +1455,11 @@ CURLcode Curl_posttransfer(struct Curl_easy *data) return CURLE_OK; } -#ifndef CURL_DISABLE_HTTP -/* - * Find the separator at the end of the host name, or the '?' in cases like - * http://www.url.com?id=2380 - */ -static const char *find_host_sep(const char *url) -{ - const char *sep; - const char *query; - - /* Find the start of the hostname */ - sep = strstr(url, "//"); - if(!sep) - sep = url; - else - sep += 2; - - query = strchr(sep, '?'); - sep = strchr(sep, '/'); - - if(!sep) - sep = url + strlen(url); - - if(!query) - query = url + strlen(url); - - return sep < query ? sep : query; -} - -/* - * Decide in an encoding-independent manner whether a character in an - * URL must be escaped. The same criterion must be used in strlen_url() - * and strcpy_url(). - */ -static bool urlchar_needs_escaping(int c) -{ - return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); -} - -/* - * strlen_url() returns the length of the given URL if the spaces within the - * URL were properly URL encoded. - * URL encoding should be skipped for host names, otherwise IDN resolution - * will fail. - */ -static size_t strlen_url(const char *url, bool relative) -{ - const unsigned char *ptr; - size_t newlen = 0; - bool left = TRUE; /* left side of the ? */ - const unsigned char *host_sep = (const unsigned char *) url; - - if(!relative) - host_sep = (const unsigned char *) find_host_sep(url); - - for(ptr = (unsigned char *)url; *ptr; ptr++) { - - if(ptr < host_sep) { - ++newlen; - continue; - } - - switch(*ptr) { - case '?': - left = FALSE; - /* FALLTHROUGH */ - default: - if(urlchar_needs_escaping(*ptr)) - newlen += 2; - newlen++; - break; - case ' ': - if(left) - newlen += 3; - else - newlen++; - break; - } - } - return newlen; -} - -/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in - * the source URL accordingly. - * URL encoding should be skipped for host names, otherwise IDN resolution - * will fail. - */ -static void strcpy_url(char *output, const char *url, bool relative) -{ - /* we must add this with whitespace-replacing */ - bool left = TRUE; - const unsigned char *iptr; - char *optr = output; - const unsigned char *host_sep = (const unsigned char *) url; - - if(!relative) - host_sep = (const unsigned char *) find_host_sep(url); - - for(iptr = (unsigned char *)url; /* read from here */ - *iptr; /* until zero byte */ - iptr++) { - - if(iptr < host_sep) { - *optr++ = *iptr; - continue; - } - - switch(*iptr) { - case '?': - left = FALSE; - /* FALLTHROUGH */ - default: - if(urlchar_needs_escaping(*iptr)) { - snprintf(optr, 4, "%%%02x", *iptr); - optr += 3; - } - else - *optr++=*iptr; - break; - case ' ': - if(left) { - *optr++='%'; /* add a '%' */ - *optr++='2'; /* add a '2' */ - *optr++='0'; /* add a '0' */ - } - else - *optr++='+'; /* add a '+' here */ - break; - } - } - *optr = 0; /* zero terminate output buffer */ - -} - -/* - * Returns true if the given URL is absolute (as opposed to relative) - */ -static bool is_absolute_url(const char *url) -{ - char prot[16]; /* URL protocol string storage */ - char letter; /* used for a silly sscanf */ - - return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE; -} - -/* - * Concatenate a relative URL to a base URL making it absolute. - * URL-encodes any spaces. - * The returned pointer must be freed by the caller unless NULL - * (returns NULL on out of memory). - */ -static char *concat_url(const char *base, const char *relurl) -{ - /*** - TRY to append this new path to the old URL - to the right of the host part. Oh crap, this is doomed to cause - problems in the future... - */ - char *newest; - char *protsep; - char *pathsep; - size_t newlen; - bool host_changed = FALSE; - - const char *useurl = relurl; - size_t urllen; - - /* we must make our own copy of the URL to play with, as it may - point to read-only data */ - char *url_clone = strdup(base); - - if(!url_clone) - return NULL; /* skip out of this NOW */ - - /* protsep points to the start of the host name */ - protsep = strstr(url_clone, "//"); - if(!protsep) - protsep = url_clone; - else - protsep += 2; /* pass the slashes */ - - if('/' != relurl[0]) { - int level = 0; - - /* First we need to find out if there's a ?-letter in the URL, - and cut it and the right-side of that off */ - pathsep = strchr(protsep, '?'); - if(pathsep) - *pathsep = 0; - - /* we have a relative path to append to the last slash if there's one - available, or if the new URL is just a query string (starts with a - '?') we append the new one at the end of the entire currently worked - out URL */ - if(useurl[0] != '?') { - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep = 0; - } - - /* Check if there's any slash after the host name, and if so, remember - that position instead */ - pathsep = strchr(protsep, '/'); - if(pathsep) - protsep = pathsep + 1; - else - protsep = NULL; - - /* now deal with one "./" or any amount of "../" in the newurl - and act accordingly */ - - if((useurl[0] == '.') && (useurl[1] == '/')) - useurl += 2; /* just skip the "./" */ - - while((useurl[0] == '.') && - (useurl[1] == '.') && - (useurl[2] == '/')) { - level++; - useurl += 3; /* pass the "../" */ - } - - if(protsep) { - while(level--) { - /* cut off one more level from the right of the original URL */ - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep = 0; - else { - *protsep = 0; - break; - } - } - } - } - else { - /* We got a new absolute path for this server */ - - if((relurl[0] == '/') && (relurl[1] == '/')) { - /* the new URL starts with //, just keep the protocol part from the - original one */ - *protsep = 0; - useurl = &relurl[2]; /* we keep the slashes from the original, so we - skip the new ones */ - host_changed = TRUE; - } - else { - /* cut off the original URL from the first slash, or deal with URLs - without slash */ - pathsep = strchr(protsep, '/'); - if(pathsep) { - /* When people use badly formatted URLs, such as - "http://www.url.com?dir=/home/daniel" we must not use the first - slash, if there's a ?-letter before it! */ - char *sep = strchr(protsep, '?'); - if(sep && (sep < pathsep)) - pathsep = sep; - *pathsep = 0; - } - else { - /* There was no slash. Now, since we might be operating on a badly - formatted URL, such as "http://www.url.com?id=2380" which doesn't - use a slash separator as it is supposed to, we need to check for a - ?-letter as well! */ - pathsep = strchr(protsep, '?'); - if(pathsep) - *pathsep = 0; - } - } - } - - /* If the new part contains a space, this is a mighty stupid redirect - but we still make an effort to do "right". To the left of a '?' - letter we replace each space with %20 while it is replaced with '+' - on the right side of the '?' letter. - */ - newlen = strlen_url(useurl, !host_changed); - - urllen = strlen(url_clone); - - newest = malloc(urllen + 1 + /* possible slash */ - newlen + 1 /* zero byte */); - - if(!newest) { - free(url_clone); /* don't leak this */ - return NULL; - } - - /* copy over the root url part */ - memcpy(newest, url_clone, urllen); - - /* check if we need to append a slash */ - if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) - ; - else - newest[urllen++]='/'; - - /* then append the new piece on the right side */ - strcpy_url(&newest[urllen], useurl, !host_changed); - - free(url_clone); - - return newest; -} -#endif /* CURL_DISABLE_HTTP */ - /* * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string * as given by the remote server and set up the new URL to request. + * + * This function DOES NOT FREE the given url. */ CURLcode Curl_follow(struct Curl_easy *data, char *newurl, /* the Location: string */ @@ -1777,6 +1476,7 @@ CURLcode Curl_follow(struct Curl_easy *data, /* Location: redirect */ bool disallowport = FALSE; bool reachedmax = FALSE; + CURLUcode uc; if(type == FOLLOW_REDIR) { if((data->set.maxredirs != -1) && @@ -1809,33 +1509,18 @@ CURLcode Curl_follow(struct Curl_easy *data, } } - if(!is_absolute_url(newurl)) { - /*** - *DANG* this is an RFC 2068 violation. The URL is supposed - to be absolute and this doesn't seem to be that! - */ - char *absolute = concat_url(data->change.url, newurl); - if(!absolute) - return CURLE_OUT_OF_MEMORY; - newurl = absolute; - } - else { - /* The new URL MAY contain space or high byte values, that means a mighty - stupid redirect URL but we still make an effort to do "right". */ - char *newest; - size_t newlen = strlen_url(newurl, FALSE); - + if(Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN)) /* This is an absolute URL, don't allow the custom port number */ disallowport = TRUE; - newest = malloc(newlen + 1); /* get memory for this */ - if(!newest) - return CURLE_OUT_OF_MEMORY; - - strcpy_url(newest, newurl, FALSE); /* create a space-free URL */ - newurl = newest; /* use this instead now */ + DEBUGASSERT(data->state.uh); + uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, 0); + if(uc) + return Curl_uc_to_curlcode(uc); - } + uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0); + if(uc) + return Curl_uc_to_curlcode(uc); if(type == FOLLOW_FAKE) { /* we're only figuring out the new url if we would've followed locations @@ -1852,10 +1537,8 @@ CURLcode Curl_follow(struct Curl_easy *data, if(disallowport) data->state.allow_port = FALSE; - if(data->change.url_alloc) { + if(data->change.url_alloc) Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } data->change.url = newurl; data->change.url_alloc = TRUE; @@ -2021,8 +1704,13 @@ CURLcode Curl_retry_request(struct connectdata *conn, if(conn->handler->protocol&PROTO_FAMILY_HTTP) { struct HTTP *http = data->req.protop; - if(http->writebytecount) - return Curl_readrewind(conn); + if(http->writebytecount) { + CURLcode result = Curl_readrewind(conn); + if(result) { + Curl_safefree(*url); + return result; + } + } } } return CURLE_OK; diff --git a/lib/transfer.h b/lib/transfer.h index 9263e5b..9742455 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -71,4 +71,3 @@ Curl_setup_transfer (struct connectdata *data, ); #endif /* HEADER_CURL_TRANSFER_H */ - diff --git a/lib/url.c b/lib/url.c index f159008..0d5a13f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -92,6 +92,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "non-ascii.h" #include "inet_pton.h" #include "getinfo.h" +#include "urlapi-int.h" /* And now for the protocols */ #include "ftp.h" @@ -127,10 +128,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); static void conn_free(struct connectdata *conn); static void free_fixed_hostname(struct hostname *host); -static CURLcode parse_url_login(struct Curl_easy *data, - struct connectdata *conn, - char **userptr, char **passwdptr, - char **optionsptr); static unsigned int get_protocol_family(unsigned int protocol); /* Some parts of the code (e.g. chunked encoding) assume this buffer has at @@ -294,6 +291,22 @@ void Curl_freeset(struct Curl_easy *data) Curl_mime_cleanpart(&data->set.mimepost); } +/* free the URL pieces */ +void Curl_up_free(struct Curl_easy *data) +{ + struct urlpieces *up = &data->state.up; + Curl_safefree(up->scheme); + Curl_safefree(up->hostname); + Curl_safefree(up->port); + Curl_safefree(up->user); + Curl_safefree(up->password); + Curl_safefree(up->options); + Curl_safefree(up->path); + Curl_safefree(up->query); + curl_url_cleanup(data->state.uh); + data->state.uh = NULL; +} + /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -313,16 +326,17 @@ CURLcode Curl_close(struct Curl_easy *data) Curl_expire_clear(data); /* shut off timers */ m = data->multi; - if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ curl_multi_remove_handle(data->multi, data); - if(data->multi_easy) + if(data->multi_easy) { /* when curl_easy_perform() is used, it creates its own multi handle to use and this is the one */ curl_multi_cleanup(data->multi_easy); + data->multi_easy = NULL; + } /* Destroy the timeout list that is held in the easy handle. It is /normally/ done by curl_multi_remove_handle() but this is "just in @@ -336,10 +350,6 @@ CURLcode Curl_close(struct Curl_easy *data) if(data->state.rangestringalloc) free(data->state.range); - /* Free the pathbuffer */ - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - /* freed here just in case DONE wasn't called */ Curl_free_request_state(data); @@ -359,12 +369,7 @@ CURLcode Curl_close(struct Curl_easy *data) } data->change.referer = NULL; - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - data->change.url = NULL; - + Curl_up_free(data); Curl_safefree(data->state.buffer); Curl_safefree(data->state.headerbuff); Curl_safefree(data->state.ulbuf); @@ -516,25 +521,28 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->wildcard_enabled = FALSE; set->chunk_bgn = ZERO_NULL; set->chunk_end = ZERO_NULL; - - /* tcp keepalives are disabled by default, but provide reasonable values for - * the interval and idle times. - */ set->tcp_keepalive = FALSE; set->tcp_keepintvl = 60; set->tcp_keepidle = 60; set->tcp_fastopen = FALSE; set->tcp_nodelay = TRUE; - set->ssl_enable_npn = TRUE; set->ssl_enable_alpn = TRUE; - set->expect_100_timeout = 1000L; /* Wait for a second by default. */ set->sep_headers = TRUE; /* separated header lists by default */ set->buffer_size = READBUFFER_SIZE; - set->upload_buffer_size = UPLOAD_BUFSIZE; + set->upload_buffer_size = UPLOADBUFFER_DEFAULT; set->happy_eyeballs_timeout = CURL_HET_DEFAULT; - + set->fnmatch = ZERO_NULL; + set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; + set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ + set->httpversion = +#ifdef USE_NGHTTP2 + CURL_HTTP_VERSION_2TLS +#else + CURL_HTTP_VERSION_1_1 +#endif + ; Curl_http2_init_userset(set); return result; } @@ -594,8 +602,6 @@ CURLcode Curl_open(struct Curl_easy **curl) data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ - data->set.fnmatch = ZERO_NULL; - data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ Curl_http2_init_state(&data->state); } @@ -1831,6 +1837,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) /* Store creation time to help future close decision making */ conn->created = Curl_now(); + /* Store current time to give a baseline to keepalive connection times. */ + conn->keepalive = Curl_now(); + + /* Store off the configured connection upkeep time. */ + conn->upkeep_interval_ms = data->set.upkeep_interval_ms; + conn->data = data; /* Setup the association between this connection and the Curl_easy */ @@ -1937,30 +1949,37 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) return NULL; } -static CURLcode findprotocol(struct Curl_easy *data, - struct connectdata *conn, - const char *protostr) +/* returns the handler if the given scheme is built-in */ +const struct Curl_handler *Curl_builtin_scheme(const char *scheme) { const struct Curl_handler * const *pp; const struct Curl_handler *p; - - /* Scan protocol handler table and match against 'protostr' to set a few - variables based on the URL. Now that the handler may be changed later - when the protocol specific setup function is called. */ - for(pp = protocols; (p = *pp) != NULL; pp++) { - if(strcasecompare(p->scheme, protostr)) { + /* Scan protocol handler table and match against 'scheme'. The handler may + be changed later when the protocol specific setup function is called. */ + for(pp = protocols; (p = *pp) != NULL; pp++) + if(strcasecompare(p->scheme, scheme)) /* Protocol found in table. Check if allowed */ - if(!(data->set.allowed_protocols & p->protocol)) - /* nope, get out */ - break; + return p; + return NULL; /* not found */ +} + + +static CURLcode findprotocol(struct Curl_easy *data, + struct connectdata *conn, + const char *protostr) +{ + const struct Curl_handler *p = Curl_builtin_scheme(protostr); - /* it is allowed for "normal" request, now do an extra check if this is - the result of a redirect */ - if(data->state.this_is_a_follow && - !(data->set.redir_protocols & p->protocol)) - /* nope, get out */ - break; + if(p && /* Protocol found in table. Check if allowed */ + (data->set.allowed_protocols & p->protocol)) { + /* it is allowed for "normal" request, now do an extra check if this is + the result of a redirect */ + if(data->state.this_is_a_follow && + !(data->set.redir_protocols & p->protocol)) + /* nope, get out */ + ; + else { /* Perform setup complement if some. */ conn->handler = conn->given = p; @@ -1969,7 +1988,6 @@ static CURLcode findprotocol(struct Curl_easy *data, } } - /* The protocol was not found in the table, but we don't have to assign it to anything since it is already assigned to a dummy-struct in the create_conn() function when the connectdata struct is allocated. */ @@ -1979,379 +1997,134 @@ static CURLcode findprotocol(struct Curl_easy *data, return CURLE_UNSUPPORTED_PROTOCOL; } + +CURLcode Curl_uc_to_curlcode(CURLUcode uc) +{ + switch(uc) { + default: + return CURLE_URL_MALFORMAT; + case CURLUE_UNSUPPORTED_SCHEME: + return CURLE_UNSUPPORTED_PROTOCOL; + case CURLUE_OUT_OF_MEMORY: + return CURLE_OUT_OF_MEMORY; + case CURLUE_USER_NOT_ALLOWED: + return CURLE_LOGIN_DENIED; + } +} + /* * Parse URL and fill in the relevant members of the connection struct. */ static CURLcode parseurlandfillconn(struct Curl_easy *data, - struct connectdata *conn, - bool *prot_missing, - char **userp, char **passwdp, - char **optionsp) + struct connectdata *conn) { - char *at; - char *fragment; - char *path = data->state.path; - char *query; - int rc; - const char *protop = ""; CURLcode result; - bool rebuild_url = FALSE; - bool url_has_scheme = FALSE; - char protobuf[16]; - - *prot_missing = FALSE; + CURLU *uh; + CURLUcode uc; + char *hostname; - /* We might pass the entire URL into the request so we need to make sure - * there are no bad characters in there.*/ - if(strpbrk(data->change.url, "\r\n")) { - failf(data, "Illegal characters found in URL"); - return CURLE_URL_MALFORMAT; - } + Curl_up_free(data); /* cleanup previous leftovers first */ - /************************************************************* - * Parse the URL. - * - * We need to parse the url even when using the proxy, because we will need - * the hostname and port in case we are trying to SSL connect through the - * proxy -- and we don't know if we will need to use SSL until we parse the - * url ... - ************************************************************/ - if(data->change.url[0] == ':') { - failf(data, "Bad URL, colon is first character"); - return CURLE_URL_MALFORMAT; - } + /* parse the URL */ + uh = data->state.uh = curl_url(); + if(!uh) + return CURLE_OUT_OF_MEMORY; - /* MSDOS/Windows style drive prefix, eg c: in c:foo */ -#define STARTS_WITH_DRIVE_PREFIX(str) \ - ((('a' <= str[0] && str[0] <= 'z') || \ - ('A' <= str[0] && str[0] <= 'Z')) && \ - (str[1] == ':')) - - /* MSDOS/Windows style drive prefix, optionally with - * a '|' instead of ':', followed by a slash or NUL */ -#define STARTS_WITH_URL_DRIVE_PREFIX(str) \ - ((('a' <= (str)[0] && (str)[0] <= 'z') || \ - ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ - ((str)[1] == ':' || (str)[1] == '|') && \ - ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) - - /* Don't mistake a drive letter for a scheme if the default protocol is file. - curld --proto-default file c:/foo/bar.txt */ - if(STARTS_WITH_DRIVE_PREFIX(data->change.url) && - data->set.str[STRING_DEFAULT_PROTOCOL] && - strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) { - ; /* do nothing */ - } - else { /* check for a scheme */ - int i; - for(i = 0; i < 16 && data->change.url[i]; ++i) { - if(data->change.url[i] == '/') - break; - if(data->change.url[i] == ':') { - url_has_scheme = TRUE; - break; - } - } + if(data->set.str[STRING_DEFAULT_PROTOCOL] && + !Curl_is_absolute_url(data->change.url, NULL, MAX_SCHEME_LEN)) { + char *url; + if(data->change.url_alloc) + free(data->change.url); + url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], + data->change.url); + if(!url) + return CURLE_OUT_OF_MEMORY; + data->change.url = url; + data->change.url_alloc = TRUE; } - /* handle the file: scheme */ - if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) || - (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] && - strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) { - if(url_has_scheme) - rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path); - else - rc = sscanf(data->change.url, "%[^\n]", path); - - if(rc != 1) { - failf(data, "Bad URL"); - return CURLE_URL_MALFORMAT; - } + uc = curl_url_set(uh, CURLUPART_URL, data->change.url, + CURLU_GUESS_SCHEME | + CURLU_NON_SUPPORT_SCHEME | + (data->set.disallow_username_in_url ? + CURLU_DISALLOW_USER : 0) | + (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); + if(uc) + return Curl_uc_to_curlcode(uc); - /* Extra handling URLs with an authority component (i.e. that start with - * "file://") - * - * We allow omitted hostname (e.g. file:/) -- valid according to - * RFC 8089, but not the (current) WHAT-WG URL spec. - */ - if(url_has_scheme && path[0] == '/' && path[1] == '/') { - /* swallow the two slashes */ - char *ptr = &path[2]; + uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); + if(uc) + return Curl_uc_to_curlcode(uc); - /* - * According to RFC 8089, a file: URL can be reliably dereferenced if: - * - * o it has no/blank hostname, or - * - * o the hostname matches "localhost" (case-insensitively), or - * - * o the hostname is a FQDN that resolves to this machine. - * - * For brevity, we only consider URLs with empty, "localhost", or - * "127.0.0.1" hostnames as local. - * - * Additionally, there is an exception for URLs with a Windows drive - * letter in the authority (which was accidentally omitted from RFC 8089 - * Appendix E, but believe me, it was meant to be there. --MK) - */ - if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) { - /* the URL includes a host name, it must match "localhost" or - "127.0.0.1" to be valid */ - if(!checkprefix("localhost/", ptr) && - !checkprefix("127.0.0.1/", ptr)) { - failf(data, "Invalid file://hostname/, " - "expected localhost or 127.0.0.1 or none"); - return CURLE_URL_MALFORMAT; - } - ptr += 9; /* now points to the slash after the host */ - } - - /* This cannot be done with strcpy, as the memory chunks overlap! */ - memmove(path, ptr, strlen(ptr) + 1); - } - -#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) - /* Don't allow Windows drive letters when not in Windows. - * This catches both "file:/c:" and "file:c:" */ - if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || - STARTS_WITH_URL_DRIVE_PREFIX(path)) { - failf(data, "File drive letters are only accepted in MSDOS/Windows."); - return CURLE_URL_MALFORMAT; - } -#else - /* If the path starts with a slash and a drive letter, ditch the slash */ - if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { - /* This cannot be done with strcpy, as the memory chunks overlap! */ - memmove(path, &path[1], strlen(&path[1]) + 1); - } -#endif + result = findprotocol(data, conn, data->state.up.scheme); + if(result) + return result; - protop = "file"; /* protocol string */ - *prot_missing = !url_has_scheme; + uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, + CURLU_URLDECODE); + if(!uc) { + conn->user = strdup(data->state.up.user); + if(!conn->user) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; } - else { - /* clear path */ - char slashbuf[4]; - path[0] = 0; - - rc = sscanf(data->change.url, - "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]", - protobuf, slashbuf, conn->host.name, path); - if(2 == rc) { - failf(data, "Bad URL"); - return CURLE_URL_MALFORMAT; - } - if(3 > rc) { - - /* - * The URL was badly formatted, let's try the browser-style _without_ - * protocol specified like 'http://'. - */ - rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path); - if(1 > rc) { - /* - * We couldn't even get this format. - * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is - * assigned, but the return value is EOF! - */ -#if defined(__DJGPP__) && (DJGPP_MINOR == 4) - if(!(rc == -1 && *conn->host.name)) -#endif - { - failf(data, " malformed"); - return CURLE_URL_MALFORMAT; - } - } - - /* - * Since there was no protocol part specified in the URL use the - * user-specified default protocol. If we weren't given a default make a - * guess by matching some protocols against the host's outermost - * sub-domain name. Finally if there was no match use HTTP. - */ + else if(uc != CURLUE_NO_USER) + return Curl_uc_to_curlcode(uc); - protop = data->set.str[STRING_DEFAULT_PROTOCOL]; - if(!protop) { - /* Note: if you add a new protocol, please update the list in - * lib/version.c too! */ - if(checkprefix("FTP.", conn->host.name)) - protop = "ftp"; - else if(checkprefix("DICT.", conn->host.name)) - protop = "DICT"; - else if(checkprefix("LDAP.", conn->host.name)) - protop = "LDAP"; - else if(checkprefix("IMAP.", conn->host.name)) - protop = "IMAP"; - else if(checkprefix("SMTP.", conn->host.name)) - protop = "smtp"; - else if(checkprefix("POP3.", conn->host.name)) - protop = "pop3"; - else - protop = "http"; - } - - *prot_missing = TRUE; /* not given in URL */ - } - else { - size_t s = strlen(slashbuf); - protop = protobuf; - if(s != 2) { - infof(data, "Unwillingly accepted illegal URL using %zu slash%s!\n", - s, s>1?"es":""); - - if(data->change.url_alloc) - free(data->change.url); - /* repair the URL to use two slashes */ - data->change.url = aprintf("%s://%s%s", - protobuf, conn->host.name, path); - if(!data->change.url) - return CURLE_OUT_OF_MEMORY; - data->change.url_alloc = TRUE; - } - } + uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, + CURLU_URLDECODE); + if(!uc) { + conn->passwd = strdup(data->state.up.password); + if(!conn->passwd) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; } + else if(uc != CURLUE_NO_PASSWORD) + return Curl_uc_to_curlcode(uc); - /* We search for '?' in the host name (but only on the right side of a - * @-letter to allow ?-letters in username and password) to handle things - * like http://example.com?param= (notice the missing '/'). - */ - at = strchr(conn->host.name, '@'); - if(at) - query = strchr(at + 1, '?'); - else - query = strchr(conn->host.name, '?'); - - if(query) { - /* We must insert a slash before the '?'-letter in the URL. If the URL had - a slash after the '?', that is where the path currently begins and the - '?string' is still part of the host name. - - We must move the trailing part from the host name and put it first in - the path. And have it all prefixed with a slash. - */ - - size_t hostlen = strlen(query); - size_t pathlen = strlen(path); - - /* move the existing path plus the zero byte forward, to make room for - the host-name part */ - memmove(path + hostlen + 1, path, pathlen + 1); - - /* now copy the trailing host part in front of the existing path */ - memcpy(path + 1, query, hostlen); - - path[0]='/'; /* prepend the missing slash */ - rebuild_url = TRUE; - - *query = 0; /* now cut off the hostname at the ? */ - } - else if(!path[0]) { - /* if there's no path set, use a single slash */ - strcpy(path, "/"); - rebuild_url = TRUE; + uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options, + CURLU_URLDECODE); + if(!uc) { + conn->options = strdup(data->state.up.options); + if(!conn->options) + return CURLE_OUT_OF_MEMORY; } + else if(uc != CURLUE_NO_OPTIONS) + return Curl_uc_to_curlcode(uc); - /* If the URL is malformatted (missing a '/' after hostname before path) we - * insert a slash here. The only letters except '/' that can start a path is - * '?' and '#' - as controlled by the two sscanf() patterns above. - */ - if(path[0] != '/') { - /* We need this function to deal with overlapping memory areas. We know - that the memory area 'path' points to is 'urllen' bytes big and that - is bigger than the path. Use +1 to move the zero byte too. */ - memmove(&path[1], path, strlen(path) + 1); - path[0] = '/'; - rebuild_url = TRUE; - } - else if(!data->set.path_as_is) { - /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ - char *newp = Curl_dedotdotify(path); - if(!newp) + uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0); + if(uc) { + if(!strcasecompare("file", data->state.up.scheme)) return CURLE_OUT_OF_MEMORY; - - if(strcmp(newp, path)) { - rebuild_url = TRUE; - free(data->state.pathbuffer); - data->state.pathbuffer = newp; - data->state.path = newp; - path = newp; - } - else - free(newp); } - /* - * "rebuild_url" means that one or more URL components have been modified so - * we need to generate an updated full version. We need the corrected URL - * when communicating over HTTP proxy and we don't know at this point if - * we're using a proxy or not. - */ - if(rebuild_url) { - char *reurl; - - size_t plen = strlen(path); /* new path, should be 1 byte longer than - the original */ - size_t prefixlen = strlen(conn->host.name); - - if(!*prot_missing) { - size_t protolen = strlen(protop); - - if(curl_strnequal(protop, data->change.url, protolen)) - prefixlen += protolen; - else { - failf(data, " malformed"); - return CURLE_URL_MALFORMAT; - } - - if(curl_strnequal("://", &data->change.url[protolen], 3)) - prefixlen += 3; - /* only file: is allowed to omit one or both slashes */ - else if(curl_strnequal("file:", data->change.url, 5)) - prefixlen += 1 + (data->change.url[5] == '/'); - else { - failf(data, " malformed"); - return CURLE_URL_MALFORMAT; - } - } + uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0); + if(uc) + return Curl_uc_to_curlcode(uc); - reurl = malloc(prefixlen + plen + 1); - if(!reurl) + uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port, + CURLU_DEFAULT_PORT); + if(uc) { + if(!strcasecompare("file", data->state.up.scheme)) return CURLE_OUT_OF_MEMORY; - - /* copy the prefix */ - memcpy(reurl, data->change.url, prefixlen); - - /* append the trailing piece + zerobyte */ - memcpy(&reurl[prefixlen], path, plen + 1); - - /* possible free the old one */ - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - infof(data, "Rebuilt URL to: %s\n", reurl); - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ + } + else { + unsigned long port = strtoul(data->state.up.port, NULL, 10); + conn->remote_port = curlx_ultous(port); } - result = findprotocol(data, conn, protop); - if(result) - return result; + (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); - /* - * Parse the login details from the URL and strip them out of - * the host name - */ - result = parse_url_login(data, conn, userp, passwdp, optionsp); - if(result) - return result; + hostname = data->state.up.hostname; + if(!hostname) + /* this is for file:// transfers, get a dummy made */ + hostname = (char *)""; - if(conn->host.name[0] == '[') { + if(hostname[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address - scope if there is no location header */ - char *percent = strchr(conn->host.name, '%'); + scope. */ + char *percent = strchr(++hostname, '%'); + conn->bits.ipv6_ip = TRUE; if(percent) { unsigned int identifier_offset = 3; char *endp; @@ -2399,33 +2172,22 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, infof(data, "Invalid IPv6 address format\n"); } } + percent = strchr(hostname, ']'); + if(percent) + /* terminate IPv6 numerical at end bracket */ + *percent = 0; } + /* make sure the connect struct gets its own copy of the host name */ + conn->host.rawalloc = strdup(hostname); + if(!conn->host.rawalloc) + return CURLE_OUT_OF_MEMORY; + conn->host.name = conn->host.rawalloc; + if(data->set.scope_id) /* Override any scope that was set above. */ conn->scope_id = data->set.scope_id; - /* Remove the fragment part of the path. Per RFC 2396, this is always the - last part of the URI. We are looking for the first '#' so that we deal - gracefully with non conformant URI such as http://example.com#foo#bar. */ - fragment = strchr(path, '#'); - if(fragment) { - *fragment = 0; - - /* we know the path part ended with a fragment, so we know the full URL - string does too and we need to cut it off from there so it isn't used - over proxy */ - fragment = strchr(data->change.url, '#'); - if(fragment) - *fragment = 0; - } - - /* - * So if the URL was A://B/C#D, - * protop is A - * conn->host.name is B - * data->state.path is /C - */ return CURLE_OK; } @@ -2540,11 +2302,8 @@ static bool check_noproxy(const char *name, const char *no_proxy) if(!endptr) return FALSE; name++; - } - else - endptr = strchr(name, ':'); - if(endptr) namelen = endptr - name; + } else namelen = strlen(name); @@ -3077,131 +2836,6 @@ out: #endif /* CURL_DISABLE_PROXY */ /* - * parse_url_login() - * - * Parse the login details (user name, password and options) from the URL and - * strip them out of the host name - * - * Inputs: data->set.use_netrc (CURLOPT_NETRC) - * conn->host.name - * - * Outputs: (almost :- all currently undefined) - * conn->bits.user_passwd - non-zero if non-default passwords exist - * user - non-zero length if defined - * passwd - non-zero length if defined - * options - non-zero length if defined - * conn->host.name - remove user name and password - */ -static CURLcode parse_url_login(struct Curl_easy *data, - struct connectdata *conn, - char **user, char **passwd, char **options) -{ - CURLcode result = CURLE_OK; - char *userp = NULL; - char *passwdp = NULL; - char *optionsp = NULL; - - /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->host.name is at most - * [user[:password][;options]]@]hostname - * - * We need somewhere to put the embedded details, so do that first. - */ - - char *ptr = strchr(conn->host.name, '@'); - char *login = conn->host.name; - - DEBUGASSERT(!**user); - DEBUGASSERT(!**passwd); - DEBUGASSERT(!**options); - DEBUGASSERT(conn->handler); - - if(!ptr) - goto out; - - /* We will now try to extract the - * possible login information in a string like: - * ftp://user:password at ftp.my.site:8021/README */ - conn->host.name = ++ptr; - - /* So the hostname is sane. Only bother interpreting the - * results if we could care. It could still be wasted - * work because it might be overtaken by the programmatically - * set user/passwd, but doing that first adds more cases here :-( - */ - - if(data->set.use_netrc == CURL_NETRC_REQUIRED) - goto out; - - /* We could use the login information in the URL so extract it. Only parse - options if the handler says we should. */ - result = - Curl_parse_login_details(login, ptr - login - 1, - &userp, &passwdp, - (conn->handler->flags & PROTOPT_URLOPTIONS)? - &optionsp:NULL); - if(result) - goto out; - - if(userp) { - char *newname; - - if(data->set.disallow_username_in_url) { - failf(data, "Option DISALLOW_USERNAME_IN_URL is set " - "and url contains username."); - result = CURLE_LOGIN_DENIED; - goto out; - } - - /* We have a user in the URL */ - conn->bits.userpwd_in_url = TRUE; - conn->bits.user_passwd = TRUE; /* enable user+password */ - - /* Decode the user */ - result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE); - if(result) { - goto out; - } - - free(*user); - *user = newname; - } - - if(passwdp) { - /* We have a password in the URL so decode it */ - char *newpasswd; - result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE); - if(result) { - goto out; - } - - free(*passwd); - *passwd = newpasswd; - } - - if(optionsp) { - /* We have an options list in the URL so decode it */ - char *newoptions; - result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE); - if(result) { - goto out; - } - - free(*options); - *options = newoptions; - } - - - out: - - free(userp); - free(passwdp); - free(optionsp); - - return result; -} - -/* * Curl_parse_login_details() * * This is used to parse a login string for user name, password and options in @@ -3223,7 +2857,7 @@ static CURLcode parse_url_login(struct Curl_easy *data, * len [in] - The length of the login string. * userp [in/out] - The address where a pointer to newly allocated memory * holding the user will be stored upon completion. - * passdwp [in/out] - The address where a pointer to newly allocated memory + * passwdp [in/out] - The address where a pointer to newly allocated memory * holding the password will be stored upon completion. * optionsp [in/out] - The address where a pointer to newly allocated memory * holding the options will be stored upon completion. @@ -3334,131 +2968,23 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, * No matter if we use a proxy or not, we have to figure out the remote * port number of various reasons. * - * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. (RFC2732) - * - * The conn->host.name is currently [user:passwd@]host[:port] where host - * could be a hostname, IPv4 address or IPv6 address. - * * The port number embedded in the URL is replaced, if necessary. *************************************************************/ static CURLcode parse_remote_port(struct Curl_easy *data, struct connectdata *conn) { - char *portptr; - char endbracket; - - /* Note that at this point, the IPv6 address cannot contain any scope - suffix as that has already been removed in the parseurlandfillconn() - function */ - if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c", - &endbracket)) && - (']' == endbracket)) { - /* this is a RFC2732-style specified IP-address */ - conn->bits.ipv6_ip = TRUE; - - conn->host.name++; /* skip over the starting bracket */ - portptr = strchr(conn->host.name, ']'); - if(portptr) { - *portptr++ = '\0'; /* zero terminate, killing the bracket */ - if(*portptr) { - if (*portptr != ':') { - failf(data, "IPv6 closing bracket followed by '%c'", *portptr); - return CURLE_URL_MALFORMAT; - } - } - else - portptr = NULL; /* no port number available */ - } - } - else { -#ifdef ENABLE_IPV6 - struct in6_addr in6; - if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) { - /* This is a numerical IPv6 address, meaning this is a wrongly formatted - URL */ - failf(data, "IPv6 numerical address used in URL without brackets"); - return CURLE_URL_MALFORMAT; - } -#endif - - portptr = strchr(conn->host.name, ':'); - } if(data->set.use_port && data->state.allow_port) { - /* if set, we use this and ignore the port possibly given in the URL */ + /* if set, we use this instead of the port possibly given in the URL */ + char portbuf[16]; + CURLUcode uc; conn->remote_port = (unsigned short)data->set.use_port; - if(portptr) - *portptr = '\0'; /* cut off the name there anyway - if there was a port - number - since the port number is to be ignored! */ - if(conn->bits.httpproxy) { - /* we need to create new URL with the new port number */ - char *url; - char type[12]=""; - - if(conn->bits.type_set) - snprintf(type, sizeof(type), ";type=%c", - data->set.prefer_ascii?'A': - (data->set.ftp_list_only?'D':'I')); - - /* - * This synthesized URL isn't always right--suffixes like ;type=A are - * stripped off. It would be better to work directly from the original - * URL and simply replace the port part of it. - */ - url = aprintf("%s://%s%s%s:%d%s%s%s", conn->given->scheme, - conn->bits.ipv6_ip?"[":"", conn->host.name, - conn->bits.ipv6_ip?"]":"", conn->remote_port, - data->state.slash_removed?"/":"", data->state.path, - type); - if(!url) - return CURLE_OUT_OF_MEMORY; - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - data->change.url = url; - data->change.url_alloc = TRUE; - } - } - else if(portptr) { - /* no CURLOPT_PORT given, extract the one from the URL */ - - char *rest; - long port; - - port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ - - if((port < 0) || (port > 0xffff)) { - /* Single unix standard says port numbers are 16 bits long */ - failf(data, "Port number out of range"); - return CURLE_URL_MALFORMAT; - } - - if(rest[0]) { - failf(data, "Port number ended with '%c'", rest[0]); - return CURLE_URL_MALFORMAT; - } - - if(rest != &portptr[1]) { - *portptr = '\0'; /* cut off the name there */ - conn->remote_port = curlx_ultous(port); - } - else { - /* Browser behavior adaptation. If there's a colon with no digits after, - just cut off the name there which makes us ignore the colon and just - use the default port. Firefox and Chrome both do that. */ - *portptr = '\0'; - } + snprintf(portbuf, sizeof(portbuf), "%u", conn->remote_port); + uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0); + if(uc) + return CURLE_OUT_OF_MEMORY; } - /* only if remote_port was not already parsed off the URL we use the - default port number */ - if(conn->remote_port < 0) - conn->remote_port = (unsigned short)conn->given->defport; - return CURLE_OK; } @@ -3470,11 +2996,16 @@ static CURLcode override_login(struct Curl_easy *data, struct connectdata *conn, char **userp, char **passwdp, char **optionsp) { + bool user_changed = FALSE; + bool passwd_changed = FALSE; + CURLUcode uc; if(data->set.str[STRING_USERNAME]) { free(*userp); *userp = strdup(data->set.str[STRING_USERNAME]); if(!*userp) return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; /* enable user+password */ + user_changed = TRUE; } if(data->set.str[STRING_PASSWORD]) { @@ -3482,6 +3013,8 @@ static CURLcode override_login(struct Curl_easy *data, *passwdp = strdup(data->set.str[STRING_PASSWORD]); if(!*passwdp) return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; /* enable user+password */ + passwd_changed = TRUE; } if(data->set.str[STRING_OPTIONS]) { @@ -3493,9 +3026,16 @@ static CURLcode override_login(struct Curl_easy *data, conn->bits.netrc = FALSE; if(data->set.use_netrc != CURL_NETRC_IGNORED) { - int ret = Curl_parsenetrc(conn->host.name, - userp, passwdp, - data->set.str[STRING_NETRC_FILE]); + char *nuser = NULL; + char *npasswd = NULL; + int ret; + + if(data->set.use_netrc == CURL_NETRC_OPTIONAL) + nuser = *userp; /* to separate otherwise identical machines */ + + ret = Curl_parsenetrc(conn->host.name, + &nuser, &npasswd, + data->set.str[STRING_NETRC_FILE]); if(ret > 0) { infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file; using defaults\n", @@ -3509,55 +3049,85 @@ static CURLcode override_login(struct Curl_easy *data, file, so that it is safe to use even if we followed a Location: to a different host or similar. */ conn->bits.netrc = TRUE; - conn->bits.user_passwd = TRUE; /* enable user+password */ + + if(data->set.use_netrc == CURL_NETRC_OPTIONAL) { + /* prefer credentials outside netrc */ + if(nuser && !*userp) { + free(*userp); + *userp = nuser; + user_changed = TRUE; + } + if(npasswd && !*passwdp) { + free(*passwdp); + *passwdp = npasswd; + passwd_changed = TRUE; + } + } + else { + /* prefer netrc credentials */ + if(nuser) { + free(*userp); + *userp = nuser; + user_changed = TRUE; + } + if(npasswd) { + free(*passwdp); + *passwdp = npasswd; + passwd_changed = TRUE; + } + } } } + /* for updated strings, we update them in the URL */ + if(user_changed) { + uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + } + if(passwd_changed) { + uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + } return CURLE_OK; } /* * Set the login details so they're available in the connection */ -static CURLcode set_login(struct connectdata *conn, - const char *user, const char *passwd, - const char *options) +static CURLcode set_login(struct connectdata *conn) { CURLcode result = CURLE_OK; + const char *setuser = CURL_DEFAULT_USER; + const char *setpasswd = CURL_DEFAULT_PASSWORD; /* If our protocol needs a password and we have none, use the defaults */ - if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { - /* Store the default user */ - conn->user = strdup(CURL_DEFAULT_USER); - - /* Store the default password */ - if(conn->user) - conn->passwd = strdup(CURL_DEFAULT_PASSWORD); - else - conn->passwd = NULL; - - /* This is the default password, so DON'T set conn->bits.user_passwd */ - } + if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) + ; else { - /* Store the user, zero-length if not set */ - conn->user = strdup(user); - - /* Store the password (only if user is present), zero-length if not set */ - if(conn->user) - conn->passwd = strdup(passwd); - else - conn->passwd = NULL; + setuser = ""; + setpasswd = ""; + } + /* Store the default user */ + if(!conn->user) { + conn->user = strdup(setuser); + if(!conn->user) + return CURLE_OUT_OF_MEMORY; } - if(!conn->user || !conn->passwd) - result = CURLE_OUT_OF_MEMORY; - - /* Store the options, null if not set */ - if(!result && options[0]) { - conn->options = strdup(options); + /* Store the default password */ + if(!conn->passwd) { + conn->passwd = strdup(setpasswd); + if(!conn->passwd) + result = CURLE_OUT_OF_MEMORY; + } - if(!conn->options) + /* if there's a user without password, consider password blank */ + if(conn->user && !conn->passwd) { + conn->passwd = strdup(""); + if(!conn->passwd) result = CURLE_OUT_OF_MEMORY; } @@ -4009,12 +3579,7 @@ static CURLcode create_conn(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn; struct connectdata *conn_temp = NULL; - size_t urllen; - char *user = NULL; - char *passwd = NULL; - char *options = NULL; bool reuse; - bool prot_missing = FALSE; bool connections_available = TRUE; bool force_reuse = FALSE; bool waitpipe = FALSE; @@ -4026,7 +3591,6 @@ static CURLcode create_conn(struct Curl_easy *data, /************************************************************* * Check input data *************************************************************/ - if(!data->change.url) { result = CURLE_URL_MALFORMAT; goto out; @@ -4048,107 +3612,10 @@ static CURLcode create_conn(struct Curl_easy *data, any failure */ *in_connect = conn; - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ - - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen = strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen = LEAST_PATH_ALLOC; - - /* - * We malloc() the buffers below urllen+2 to make room for 2 possibilities: - * 1 - an extra terminating zero - * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) - */ - - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - - data->state.pathbuffer = malloc(urllen + 2); - if(NULL == data->state.pathbuffer) { - result = CURLE_OUT_OF_MEMORY; /* really bad error */ - goto out; - } - data->state.path = data->state.pathbuffer; - - conn->host.rawalloc = malloc(urllen + 2); - if(NULL == conn->host.rawalloc) { - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - conn->host.name = conn->host.rawalloc; - conn->host.name[0] = 0; - - user = strdup(""); - passwd = strdup(""); - options = strdup(""); - if(!user || !passwd || !options) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd, - &options); + result = parseurlandfillconn(data, conn); if(result) goto out; - /************************************************************* - * No protocol part in URL was used, add it! - *************************************************************/ - if(prot_missing) { - /* We're guessing prefixes here and if we're told to use a proxy or if - we're going to follow a Location: later or... then we need the protocol - part added so that we have a valid URL. */ - char *reurl; - char *ch_lower; - - reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url); - - if(!reurl) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Change protocol prefix to lower-case */ - for(ch_lower = reurl; *ch_lower != ':'; ch_lower++) - *ch_lower = (char)TOLOWER(*ch_lower); - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - } - - /************************************************************* - * If the protocol can't handle url query strings, then cut - * off the unhandable part - *************************************************************/ - if((conn->given->flags&PROTOPT_NOURLQUERY)) { - char *path_q_sep = strchr(conn->data->state.path, '?'); - if(path_q_sep) { - /* according to rfc3986, allow the query (?foo=bar) - also on protocols that can't handle it. - - cut the string-part after '?' - */ - - /* terminate the string */ - path_q_sep[0] = 0; - } - } - if(data->set.str[STRING_BEARER]) { conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); if(!conn->oauth_bearer) { @@ -4192,10 +3659,12 @@ static CURLcode create_conn(struct Curl_easy *data, /* Check for overridden login details and set them accordingly so they they are known when protocol->setup_connection is called! */ - result = override_login(data, conn, &user, &passwd, &options); + result = override_login(data, conn, &conn->user, &conn->passwd, + &conn->options); if(result) goto out; - result = set_login(conn, user, passwd, options); + + result = set_login(conn); /* default credentials */ if(result) goto out; @@ -4278,6 +3747,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* this is supposed to be the connect function so we better at least check that the file is present here! */ DEBUGASSERT(conn->handler->connect_it); + Curl_persistconninfo(conn); result = conn->handler->connect_it(conn, &done); /* Setup a "faked" transfer that'll do nothing */ @@ -4381,6 +3851,9 @@ static CURLcode create_conn(struct Curl_easy *data, * new one. *************************************************************/ + DEBUGASSERT(conn->user); + DEBUGASSERT(conn->passwd); + /* reuse_fresh is TRUE if we are told to use a new connection by force, but we only acknowledge this option if this is not a re-used connection already (which happens due to follow-location or during a HTTP @@ -4556,10 +4029,6 @@ static CURLcode create_conn(struct Curl_easy *data, result = resolve_server(data, conn, async); out: - - free(options); - free(passwd); - free(user); return result; } @@ -4843,3 +4312,34 @@ static unsigned int get_protocol_family(unsigned int protocol) return family; } + + +/* + * Wrapper to call functions in Curl_conncache_foreach() + * + * Returns always 0. + */ +static int conn_upkeep(struct connectdata *conn, + void *param) +{ + /* Param is unused. */ + (void)param; + + if(conn->handler->connection_check) { + /* Do a protocol-specific keepalive check on the connection. */ + conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); + } + + return 0; /* continue iteration */ +} + +CURLcode Curl_upkeep(struct conncache *conn_cache, + void *data) +{ + /* Loop over every connection and make connection alive. */ + Curl_conncache_foreach(data, + conn_cache, + data, + conn_upkeep); + return CURLE_OK; +} diff --git a/lib/url.h b/lib/url.h index ef3ebf0..095d638 100644 --- a/lib/url.h +++ b/lib/url.h @@ -27,6 +27,18 @@ #define READBUFFER_MAX CURL_MAX_READ_SIZE #define READBUFFER_MIN 1024 +/* The default upload buffer size, should not be smaller than + CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in + a write callback. + + The size was 16KB for many years but was bumped to 64KB because it makes + libcurl able to do significantly faster uploads in some circumstances. Even + larger buffers can help further, but this is deemed a fair memory/speed + compromise. */ +#define UPLOADBUFFER_DEFAULT 65536 +#define UPLOADBUFFER_MAX (2*1024*1024) +#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE + /* * Prototypes for library-wide functions provided by url.c */ @@ -34,8 +46,11 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn); CURLcode Curl_open(struct Curl_easy **curl); CURLcode Curl_init_userdefined(struct Curl_easy *data); -CURLcode Curl_dupset(struct Curl_easy * dst, struct Curl_easy * src); + void Curl_freeset(struct Curl_easy * data); +/* free the URL pieces */ +void Curl_up_free(struct Curl_easy *data); +CURLcode Curl_uc_to_curlcode(CURLUcode uc); CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */ CURLcode Curl_connect(struct Curl_easy *, struct connectdata **, bool *async, bool *protocol_connect); @@ -57,9 +72,7 @@ int Curl_doing_getsock(struct connectdata *conn, CURLcode Curl_parse_login_details(const char *login, const size_t len, char **userptr, char **passwdptr, char **optionsptr); -bool Curl_isPipeliningEnabled(const struct Curl_easy *handle); -CURLcode Curl_addHandleToPipeline(struct Curl_easy *handle, - struct curl_llist *pipeline); + int Curl_removeHandleFromPipeline(struct Curl_easy *handle, struct curl_llist *pipeline); /* remove the specified connection from all (possible) pipelines and related @@ -67,7 +80,9 @@ int Curl_removeHandleFromPipeline(struct Curl_easy *handle, void Curl_getoff_all_pipelines(struct Curl_easy *data, struct connectdata *conn); -void Curl_close_connections(struct Curl_easy *data); +CURLcode Curl_upkeep(struct conncache *conn_cache, void *data); + +const struct Curl_handler *Curl_builtin_scheme(const char *scheme); #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless diff --git a/lib/inet_ntop.h b/lib/urlapi-int.h similarity index 64% copy from lib/inet_ntop.h copy to lib/urlapi-int.h index 9f44612..a57d2e2 100644 --- a/lib/inet_ntop.h +++ b/lib/urlapi-int.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_INET_NTOP_H -#define HEADER_CURL_INET_NTOP_H +#ifndef HEADER_CURL_URLAPI_INT_H +#define HEADER_CURL_URLAPI_INT_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -21,18 +21,13 @@ * KIND, either express or implied. * ***************************************************************************/ - #include "curl_setup.h" +/* scheme is not URL encoded, the longest libcurl supported ones are 6 + letters */ +#define MAX_SCHEME_LEN 8 -char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); - -#ifdef HAVE_INET_NTOP -#ifdef HAVE_ARPA_INET_H -#include -#endif -#define Curl_inet_ntop(af,addr,buf,size) \ - inet_ntop(af, addr, buf, (curl_socklen_t)size) -#endif - -#endif /* HEADER_CURL_INET_NTOP_H */ - +bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); +char *Curl_concat_url(const char *base, const char *relurl); +size_t Curl_strlen_url(const char *url, bool relative); +void Curl_strcpy_url(char *output, const char *url, bool relative); +#endif /* HEADER_CURL_URLAPI_INT_H */ diff --git a/lib/urlapi.c b/lib/urlapi.c new file mode 100644 index 0000000..c53e523 --- /dev/null +++ b/lib/urlapi.c @@ -0,0 +1,1340 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include "urlapi-int.h" +#include "strcase.h" +#include "dotdot.h" +#include "url.h" +#include "escape.h" +#include "curl_ctype.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + + /* MSDOS/Windows style drive prefix, eg c: in c:foo */ +#define STARTS_WITH_DRIVE_PREFIX(str) \ + ((('a' <= str[0] && str[0] <= 'z') || \ + ('A' <= str[0] && str[0] <= 'Z')) && \ + (str[1] == ':')) + + /* MSDOS/Windows style drive prefix, optionally with + * a '|' instead of ':', followed by a slash or NUL */ +#define STARTS_WITH_URL_DRIVE_PREFIX(str) \ + ((('a' <= (str)[0] && (str)[0] <= 'z') || \ + ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ + ((str)[1] == ':' || (str)[1] == '|') && \ + ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) + +/* Internal representation of CURLU. Point to URL-encoded strings. */ +struct Curl_URL { + char *scheme; + char *user; + char *password; + char *options; /* IMAP only? */ + char *host; + char *port; + char *path; + char *query; + char *fragment; + + char *scratch; /* temporary scratch area */ + long portnum; /* the numerical version */ +}; + +#define DEFAULT_SCHEME "https" + +static void free_urlhandle(struct Curl_URL *u) +{ + free(u->scheme); + free(u->user); + free(u->password); + free(u->options); + free(u->host); + free(u->port); + free(u->path); + free(u->query); + free(u->fragment); + free(u->scratch); +} + +/* move the full contents of one handle onto another and + free the original */ +static void mv_urlhandle(struct Curl_URL *from, + struct Curl_URL *to) +{ + free_urlhandle(to); + *to = *from; + free(from); +} + +/* + * Find the separator at the end of the host name, or the '?' in cases like + * http://www.url.com?id=2380 + */ +static const char *find_host_sep(const char *url) +{ + const char *sep; + const char *query; + + /* Find the start of the hostname */ + sep = strstr(url, "//"); + if(!sep) + sep = url; + else + sep += 2; + + query = strchr(sep, '?'); + sep = strchr(sep, '/'); + + if(!sep) + sep = url + strlen(url); + + if(!query) + query = url + strlen(url); + + return sep < query ? sep : query; +} + +/* + * Decide in an encoding-independent manner whether a character in an + * URL must be escaped. The same criterion must be used in strlen_url() + * and strcpy_url(). + */ +static bool urlchar_needs_escaping(int c) +{ + return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); +} + +/* + * strlen_url() returns the length of the given URL if the spaces within the + * URL were properly URL encoded. + * URL encoding should be skipped for host names, otherwise IDN resolution + * will fail. + */ +size_t Curl_strlen_url(const char *url, bool relative) +{ + const unsigned char *ptr; + size_t newlen = 0; + bool left = TRUE; /* left side of the ? */ + const unsigned char *host_sep = (const unsigned char *) url; + + if(!relative) + host_sep = (const unsigned char *) find_host_sep(url); + + for(ptr = (unsigned char *)url; *ptr; ptr++) { + + if(ptr < host_sep) { + ++newlen; + continue; + } + + switch(*ptr) { + case '?': + left = FALSE; + /* FALLTHROUGH */ + default: + if(urlchar_needs_escaping(*ptr)) + newlen += 2; + newlen++; + break; + case ' ': + if(left) + newlen += 3; + else + newlen++; + break; + } + } + return newlen; +} + +/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in + * the source URL accordingly. + * URL encoding should be skipped for host names, otherwise IDN resolution + * will fail. + */ +void Curl_strcpy_url(char *output, const char *url, bool relative) +{ + /* we must add this with whitespace-replacing */ + bool left = TRUE; + const unsigned char *iptr; + char *optr = output; + const unsigned char *host_sep = (const unsigned char *) url; + + if(!relative) + host_sep = (const unsigned char *) find_host_sep(url); + + for(iptr = (unsigned char *)url; /* read from here */ + *iptr; /* until zero byte */ + iptr++) { + + if(iptr < host_sep) { + *optr++ = *iptr; + continue; + } + + switch(*iptr) { + case '?': + left = FALSE; + /* FALLTHROUGH */ + default: + if(urlchar_needs_escaping(*iptr)) { + snprintf(optr, 4, "%%%02x", *iptr); + optr += 3; + } + else + *optr++=*iptr; + break; + case ' ': + if(left) { + *optr++='%'; /* add a '%' */ + *optr++='2'; /* add a '2' */ + *optr++='0'; /* add a '0' */ + } + else + *optr++='+'; /* add a '+' here */ + break; + } + } + *optr = 0; /* zero terminate output buffer */ + +} + +/* + * Returns true if the given URL is absolute (as opposed to relative) within + * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is + * non-NULL. + */ +bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) +{ + size_t i; +#ifdef WIN32 + if(STARTS_WITH_DRIVE_PREFIX(url)) + return FALSE; +#endif + for(i = 0; i < buflen && url[i]; ++i) { + char s = url[i]; + if(s == ':') { + if(buf) + buf[i] = 0; + return TRUE; + } + /* RFC 3986 3.1 explains: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) { + if(buf) + buf[i] = (char)TOLOWER(s); + } + else + break; + } + return FALSE; +} + +/* + * Concatenate a relative URL to a base URL making it absolute. + * URL-encodes any spaces. + * The returned pointer must be freed by the caller unless NULL + * (returns NULL on out of memory). + */ +char *Curl_concat_url(const char *base, const char *relurl) +{ + /*** + TRY to append this new path to the old URL + to the right of the host part. Oh crap, this is doomed to cause + problems in the future... + */ + char *newest; + char *protsep; + char *pathsep; + size_t newlen; + bool host_changed = FALSE; + + const char *useurl = relurl; + size_t urllen; + + /* we must make our own copy of the URL to play with, as it may + point to read-only data */ + char *url_clone = strdup(base); + + if(!url_clone) + return NULL; /* skip out of this NOW */ + + /* protsep points to the start of the host name */ + protsep = strstr(url_clone, "//"); + if(!protsep) + protsep = url_clone; + else + protsep += 2; /* pass the slashes */ + + if('/' != relurl[0]) { + int level = 0; + + /* First we need to find out if there's a ?-letter in the URL, + and cut it and the right-side of that off */ + pathsep = strchr(protsep, '?'); + if(pathsep) + *pathsep = 0; + + /* we have a relative path to append to the last slash if there's one + available, or if the new URL is just a query string (starts with a + '?') we append the new one at the end of the entire currently worked + out URL */ + if(useurl[0] != '?') { + pathsep = strrchr(protsep, '/'); + if(pathsep) + *pathsep = 0; + } + + /* Check if there's any slash after the host name, and if so, remember + that position instead */ + pathsep = strchr(protsep, '/'); + if(pathsep) + protsep = pathsep + 1; + else + protsep = NULL; + + /* now deal with one "./" or any amount of "../" in the newurl + and act accordingly */ + + if((useurl[0] == '.') && (useurl[1] == '/')) + useurl += 2; /* just skip the "./" */ + + while((useurl[0] == '.') && + (useurl[1] == '.') && + (useurl[2] == '/')) { + level++; + useurl += 3; /* pass the "../" */ + } + + if(protsep) { + while(level--) { + /* cut off one more level from the right of the original URL */ + pathsep = strrchr(protsep, '/'); + if(pathsep) + *pathsep = 0; + else { + *protsep = 0; + break; + } + } + } + } + else { + /* We got a new absolute path for this server */ + + if((relurl[0] == '/') && (relurl[1] == '/')) { + /* the new URL starts with //, just keep the protocol part from the + original one */ + *protsep = 0; + useurl = &relurl[2]; /* we keep the slashes from the original, so we + skip the new ones */ + host_changed = TRUE; + } + else { + /* cut off the original URL from the first slash, or deal with URLs + without slash */ + pathsep = strchr(protsep, '/'); + if(pathsep) { + /* When people use badly formatted URLs, such as + "http://www.url.com?dir=/home/daniel" we must not use the first + slash, if there's a ?-letter before it! */ + char *sep = strchr(protsep, '?'); + if(sep && (sep < pathsep)) + pathsep = sep; + *pathsep = 0; + } + else { + /* There was no slash. Now, since we might be operating on a badly + formatted URL, such as "http://www.url.com?id=2380" which doesn't + use a slash separator as it is supposed to, we need to check for a + ?-letter as well! */ + pathsep = strchr(protsep, '?'); + if(pathsep) + *pathsep = 0; + } + } + } + + /* If the new part contains a space, this is a mighty stupid redirect + but we still make an effort to do "right". To the left of a '?' + letter we replace each space with %20 while it is replaced with '+' + on the right side of the '?' letter. + */ + newlen = Curl_strlen_url(useurl, !host_changed); + + urllen = strlen(url_clone); + + newest = malloc(urllen + 1 + /* possible slash */ + newlen + 1 /* zero byte */); + + if(!newest) { + free(url_clone); /* don't leak this */ + return NULL; + } + + /* copy over the root url part */ + memcpy(newest, url_clone, urllen); + + /* check if we need to append a slash */ + if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) + ; + else + newest[urllen++]='/'; + + /* then append the new piece on the right side */ + Curl_strcpy_url(&newest[urllen], useurl, !host_changed); + + free(url_clone); + + return newest; +} + +/* + * parse_hostname_login() + * + * Parse the login details (user name, password and options) from the URL and + * strip them out of the host name + * + */ +static CURLUcode parse_hostname_login(struct Curl_URL *u, + const struct Curl_handler *h, + char **hostname, + unsigned int flags) +{ + CURLUcode result = CURLUE_OK; + CURLcode ccode; + char *userp = NULL; + char *passwdp = NULL; + char *optionsp = NULL; + + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most + * [user[:password][;options]]@]hostname + * + * We need somewhere to put the embedded details, so do that first. + */ + + char *ptr = strchr(*hostname, '@'); + char *login = *hostname; + + if(!ptr) + goto out; + + /* We will now try to extract the + * possible login information in a string like: + * ftp://user:password at ftp.my.site:8021/README */ + *hostname = ++ptr; + + /* We could use the login information in the URL so extract it. Only parse + options if the handler says we should. Note that 'h' might be NULL! */ + ccode = Curl_parse_login_details(login, ptr - login - 1, + &userp, &passwdp, + (h && (h->flags & PROTOPT_URLOPTIONS)) ? + &optionsp:NULL); + if(ccode) { + result = CURLUE_MALFORMED_INPUT; + goto out; + } + + if(userp) { + if(flags & CURLU_DISALLOW_USER) { + /* Option DISALLOW_USER is set and url contains username. */ + result = CURLUE_USER_NOT_ALLOWED; + goto out; + } + + u->user = userp; + } + + if(passwdp) + u->password = passwdp; + + if(optionsp) + u->options = optionsp; + + return CURLUE_OK; + out: + + free(userp); + free(passwdp); + free(optionsp); + + return result; +} + +static CURLUcode parse_port(struct Curl_URL *u, char *hostname) +{ + char *portptr; + char endbracket; + int len; + + if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.%%]%c%n", + &endbracket, &len)) && + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ + portptr = &hostname[len]; + if (*portptr != ':') + return CURLUE_MALFORMED_INPUT; + } + else + portptr = strchr(hostname, ':'); + + if(portptr) { + char *rest; + long port; + char portbuf[7]; + + if(!ISDIGIT(portptr[1])) + return CURLUE_BAD_PORT_NUMBER; + + port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ + + if((port <= 0) || (port > 0xffff)) + /* Single unix standard says port numbers are 16 bits long, but we don't + treat port zero as OK. */ + return CURLUE_BAD_PORT_NUMBER; + + if(rest[0]) + return CURLUE_BAD_PORT_NUMBER; + + if(rest != &portptr[1]) { + *portptr++ = '\0'; /* cut off the name there */ + *rest = 0; + /* generate a new to get rid of leading zeroes etc */ + snprintf(portbuf, sizeof(portbuf), "%ld", port); + u->portnum = port; + u->port = strdup(portbuf); + if(!u->port) + return CURLUE_OUT_OF_MEMORY; + } + else { + /* Browser behavior adaptation. If there's a colon with no digits after, + just cut off the name there which makes us ignore the colon and just + use the default port. Firefox and Chrome both do that. */ + *portptr = '\0'; + } + } + + return CURLUE_OK; +} + +/* scan for byte values < 31 or 127 */ +static CURLUcode junkscan(char *part) +{ + char badbytes[]={ + /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x7f, + 0x00 /* zero terminate */ + }; + if(part) { + size_t n = strlen(part); + size_t nfine = strcspn(part, badbytes); + if(nfine != n) + /* since we don't know which part is scanned, return a generic error + code */ + return CURLUE_MALFORMED_INPUT; + } + return CURLUE_OK; +} + +static CURLUcode hostname_check(char *hostname, unsigned int flags) +{ + const char *l = NULL; /* accepted characters */ + size_t len; + size_t hlen = strlen(hostname); + (void)flags; + + if(hostname[0] == '[') { + hostname++; + l = "0123456789abcdefABCDEF::.%"; + hlen -= 2; + } + + if(l) { + /* only valid letters are ok */ + len = strspn(hostname, l); + if(hlen != len) + /* hostname with bad content */ + return CURLUE_MALFORMED_INPUT; + } + else { + /* letters from the second string is not ok */ + len = strcspn(hostname, " "); + if(hlen != len) + /* hostname with bad content */ + return CURLUE_MALFORMED_INPUT; + } + return CURLUE_OK; +} + +#define HOSTNAME_END(x) (((x) == '/') || ((x) == '?') || ((x) == '#')) + +static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) +{ + char *path; + bool path_alloced = FALSE; + char *hostname; + char *query = NULL; + char *fragment = NULL; + CURLUcode result; + bool url_has_scheme = FALSE; + char schemebuf[MAX_SCHEME_LEN]; + char *schemep = NULL; + size_t schemelen = 0; + size_t urllen; + const struct Curl_handler *h = NULL; + + if(!url) + return CURLUE_MALFORMED_INPUT; + + /************************************************************* + * Parse the URL. + ************************************************************/ + /* allocate scratch area */ + urllen = strlen(url); + path = u->scratch = malloc(urllen * 2 + 2); + if(!path) + return CURLUE_OUT_OF_MEMORY; + + hostname = &path[urllen + 1]; + hostname[0] = 0; + + if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) { + url_has_scheme = TRUE; + schemelen = strlen(schemebuf); + } + + /* handle the file: scheme */ + if(url_has_scheme && strcasecompare(schemebuf, "file")) { + /* path has been allocated large enough to hold this */ + strcpy(path, &url[5]); + + hostname = NULL; /* no host for file: URLs */ + u->scheme = strdup("file"); + if(!u->scheme) + return CURLUE_OUT_OF_MEMORY; + + /* Extra handling URLs with an authority component (i.e. that start with + * "file://") + * + * We allow omitted hostname (e.g. file:/) -- valid according to + * RFC 8089, but not the (current) WHAT-WG URL spec. + */ + if(path[0] == '/' && path[1] == '/') { + /* swallow the two slashes */ + char *ptr = &path[2]; + + /* + * According to RFC 8089, a file: URL can be reliably dereferenced if: + * + * o it has no/blank hostname, or + * + * o the hostname matches "localhost" (case-insensitively), or + * + * o the hostname is a FQDN that resolves to this machine. + * + * For brevity, we only consider URLs with empty, "localhost", or + * "127.0.0.1" hostnames as local. + * + * Additionally, there is an exception for URLs with a Windows drive + * letter in the authority (which was accidentally omitted from RFC 8089 + * Appendix E, but believe me, it was meant to be there. --MK) + */ + if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) { + /* the URL includes a host name, it must match "localhost" or + "127.0.0.1" to be valid */ + if(!checkprefix("localhost/", ptr) && + !checkprefix("127.0.0.1/", ptr)) { + /* Invalid file://hostname/, expected localhost or 127.0.0.1 or + none */ + return CURLUE_MALFORMED_INPUT; + } + ptr += 9; /* now points to the slash after the host */ + } + + path = ptr; + } + +#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) + /* Don't allow Windows drive letters when not in Windows. + * This catches both "file:/c:" and "file:c:" */ + if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || + STARTS_WITH_URL_DRIVE_PREFIX(path)) { + /* File drive letters are only accepted in MSDOS/Windows */ + return CURLUE_MALFORMED_INPUT; + } +#else + /* If the path starts with a slash and a drive letter, ditch the slash */ + if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { + /* This cannot be done with strcpy, as the memory chunks overlap! */ + memmove(path, &path[1], strlen(&path[1]) + 1); + } +#endif + + } + else { + /* clear path */ + const char *p; + const char *hostp; + size_t len; + path[0] = 0; + + if(url_has_scheme) { + int i = 0; + p = &url[schemelen + 1]; + while(p && (*p == '/') && (i < 4)) { + p++; + i++; + } + if((i < 1) || (i>3)) + /* less than one or more than three slashes */ + return CURLUE_MALFORMED_INPUT; + + schemep = schemebuf; + if(!Curl_builtin_scheme(schemep) && + !(flags & CURLU_NON_SUPPORT_SCHEME)) + return CURLUE_UNSUPPORTED_SCHEME; + + if(junkscan(schemep)) + return CURLUE_MALFORMED_INPUT; + } + else { + /* no scheme! */ + + if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) + return CURLUE_MALFORMED_INPUT; + if(flags & CURLU_DEFAULT_SCHEME) + schemep = (char *) DEFAULT_SCHEME; + + /* + * The URL was badly formatted, let's try without scheme specified. + */ + p = url; + } + hostp = p; /* host name starts here */ + + while(*p && !HOSTNAME_END(*p)) /* find end of host name */ + p++; + + len = p - hostp; + if(!len) + return CURLUE_MALFORMED_INPUT; + + memcpy(hostname, hostp, len); + hostname[len] = 0; + + if((flags & CURLU_GUESS_SCHEME) && !schemep) { + /* legacy curl-style guess based on host name */ + if(checkprefix("ftp.", hostname)) + schemep = (char *)"ftp"; + else if(checkprefix("dict.", hostname)) + schemep = (char *)"dict"; + else if(checkprefix("ldap.", hostname)) + schemep = (char *)"ldap"; + else if(checkprefix("imap.", hostname)) + schemep = (char *)"imap"; + else if(checkprefix("smtp.", hostname)) + schemep = (char *)"smtp"; + else if(checkprefix("pop3.", hostname)) + schemep = (char *)"pop3"; + else + schemep = (char *)"http"; + } + + len = strlen(p); + memcpy(path, p, len); + path[len] = 0; + + u->scheme = strdup(schemep); + if(!u->scheme) + return CURLUE_OUT_OF_MEMORY; + } + + /* if this is a known scheme, get some details */ + h = Curl_builtin_scheme(u->scheme); + + if(junkscan(path)) + return CURLUE_MALFORMED_INPUT; + + query = strchr(path, '?'); + if(query) + *query++ = 0; + + fragment = strchr(query?query:path, '#'); + if(fragment) + *fragment++ = 0; + + if(!path[0]) + /* if there's no path set, unset */ + path = NULL; + else if(!(flags & CURLU_PATH_AS_IS)) { + /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ + char *newp = Curl_dedotdotify(path); + if(!newp) + return CURLUE_OUT_OF_MEMORY; + + if(strcmp(newp, path)) { + /* if we got a new version */ + path = newp; + path_alloced = TRUE; + } + else + free(newp); + } + if(path) { + u->path = path_alloced?path:strdup(path); + if(!u->path) + return CURLUE_OUT_OF_MEMORY; + } + + if(hostname) { + /* + * Parse the login details and strip them out of the host name. + */ + if(junkscan(hostname)) + return CURLUE_MALFORMED_INPUT; + + result = parse_hostname_login(u, h, &hostname, flags); + if(result) + return result; + + result = parse_port(u, hostname); + if(result) + return result; + + result = hostname_check(hostname, flags); + if(result) + return result; + + u->host = strdup(hostname); + if(!u->host) + return CURLUE_OUT_OF_MEMORY; + } + + if(query && query[0]) { + u->query = strdup(query); + if(!u->query) + return CURLUE_OUT_OF_MEMORY; + } + if(fragment && fragment[0]) { + u->fragment = strdup(fragment); + if(!u->fragment) + return CURLUE_OUT_OF_MEMORY; + } + + free(u->scratch); + u->scratch = NULL; + + return CURLUE_OK; +} + +/* + * Parse the URL and set the relevant members of the Curl_URL struct. + */ +static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) +{ + CURLUcode result = seturl(url, u, flags); + if(result) { + free_urlhandle(u); + memset(u, 0, sizeof(struct Curl_URL)); + } + return result; +} + +/* + */ +CURLU *curl_url(void) +{ + return calloc(sizeof(struct Curl_URL), 1); +} + +void curl_url_cleanup(CURLU *u) +{ + if(u) { + free_urlhandle(u); + free(u); + } +} + +#define DUP(dest, src, name) \ + if(src->name) { \ + dest->name = strdup(src->name); \ + if(!dest->name) \ + goto fail; \ + } + +CURLU *curl_url_dup(CURLU *in) +{ + struct Curl_URL *u = calloc(sizeof(struct Curl_URL), 1); + if(u) { + DUP(u, in, scheme); + DUP(u, in, user); + DUP(u, in, password); + DUP(u, in, options); + DUP(u, in, host); + DUP(u, in, port); + DUP(u, in, path); + DUP(u, in, query); + DUP(u, in, fragment); + u->portnum = in->portnum; + } + return u; + fail: + curl_url_cleanup(u); + return NULL; +} + +CURLUcode curl_url_get(CURLU *u, CURLUPart what, + char **part, unsigned int flags) +{ + char *ptr; + CURLUcode ifmissing = CURLUE_UNKNOWN_PART; + char portbuf[7]; + bool urldecode = (flags & CURLU_URLDECODE)?1:0; + bool plusdecode = FALSE; + (void)flags; + if(!u) + return CURLUE_BAD_HANDLE; + if(!part) + return CURLUE_BAD_PARTPOINTER; + *part = NULL; + + switch(what) { + case CURLUPART_SCHEME: + ptr = u->scheme; + ifmissing = CURLUE_NO_SCHEME; + urldecode = FALSE; /* never for schemes */ + break; + case CURLUPART_USER: + ptr = u->user; + ifmissing = CURLUE_NO_USER; + break; + case CURLUPART_PASSWORD: + ptr = u->password; + ifmissing = CURLUE_NO_PASSWORD; + break; + case CURLUPART_OPTIONS: + ptr = u->options; + ifmissing = CURLUE_NO_OPTIONS; + break; + case CURLUPART_HOST: + ptr = u->host; + ifmissing = CURLUE_NO_HOST; + break; + case CURLUPART_PORT: + ptr = u->port; + ifmissing = CURLUE_NO_PORT; + urldecode = FALSE; /* never for port */ + if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { + /* there's no stored port number, but asked to deliver + a default one for the scheme */ + const struct Curl_handler *h = + Curl_builtin_scheme(u->scheme); + if(h) { + snprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + ptr = portbuf; + } + } + else if(ptr && u->scheme) { + /* there is a stored port number, but ask to inhibit if + it matches the default one for the scheme */ + const struct Curl_handler *h = + Curl_builtin_scheme(u->scheme); + if(h && (h->defport == u->portnum) && + (flags & CURLU_NO_DEFAULT_PORT)) + ptr = NULL; + } + break; + case CURLUPART_PATH: + ptr = u->path; + if(!ptr) { + ptr = u->path = strdup("/"); + if(!u->path) + return CURLUE_OUT_OF_MEMORY; + } + break; + case CURLUPART_QUERY: + ptr = u->query; + ifmissing = CURLUE_NO_QUERY; + plusdecode = urldecode; + break; + case CURLUPART_FRAGMENT: + ptr = u->fragment; + ifmissing = CURLUE_NO_FRAGMENT; + break; + case CURLUPART_URL: { + char *url; + char *scheme; + char *options = u->options; + char *port = u->port; + if(u->scheme && strcasecompare("file", u->scheme)) { + url = aprintf("file://%s%s%s", + u->path, + u->fragment? "#": "", + u->fragment? u->fragment : ""); + } + else if(!u->host) + return CURLUE_NO_HOST; + else { + const struct Curl_handler *h = NULL; + if(u->scheme) + scheme = u->scheme; + else if(flags & CURLU_DEFAULT_SCHEME) + scheme = (char *) DEFAULT_SCHEME; + else + return CURLUE_NO_SCHEME; + + if(scheme) { + h = Curl_builtin_scheme(scheme); + if(!port && (flags & CURLU_DEFAULT_PORT)) { + /* there's no stored port number, but asked to deliver + a default one for the scheme */ + if(h) { + snprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + port = portbuf; + } + } + else if(port) { + /* there is a stored port number, but asked to inhibit if it matches + the default one for the scheme */ + if(h && (h->defport == u->portnum) && + (flags & CURLU_NO_DEFAULT_PORT)) + port = NULL; + } + } + if(h && !(h->flags & PROTOPT_URLOPTIONS)) + options = NULL; + + url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + scheme, + u->user ? u->user : "", + u->password ? ":": "", + u->password ? u->password : "", + options ? ";" : "", + options ? options : "", + (u->user || u->password || options) ? "@": "", + u->host, + port ? ":": "", + port ? port : "", + (u->path && (u->path[0] != '/')) ? "/": "", + u->path ? u->path : "/", + u->query? "?": "", + u->query? u->query : "", + u->fragment? "#": "", + u->fragment? u->fragment : ""); + } + if(!url) + return CURLUE_OUT_OF_MEMORY; + *part = url; + return CURLUE_OK; + break; + } + default: + ptr = NULL; + } + if(ptr) { + *part = strdup(ptr); + if(!*part) + return CURLUE_OUT_OF_MEMORY; + if(plusdecode) { + /* convert + to space */ + char *plus; + for(plus = *part; *plus; ++plus) { + if(*plus == '+') + *plus = ' '; + } + } + if(urldecode) { + char *decoded; + size_t dlen; + CURLcode res = Curl_urldecode(NULL, *part, 0, &decoded, &dlen, TRUE); + free(*part); + if(res) { + *part = NULL; + return CURLUE_URLDECODE; + } + *part = decoded; + } + return CURLUE_OK; + } + else + return ifmissing; +} + +CURLUcode curl_url_set(CURLU *u, CURLUPart what, + const char *part, unsigned int flags) +{ + char **storep = NULL; + long port = 0; + bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0; + bool plusencode = FALSE; + bool urlskipslash = FALSE; + bool appendquery = FALSE; + + if(!u) + return CURLUE_BAD_HANDLE; + if(!part) { + /* setting a part to NULL clears it */ + switch(what) { + case CURLUPART_URL: + break; + case CURLUPART_SCHEME: + storep = &u->scheme; + break; + case CURLUPART_USER: + storep = &u->user; + break; + case CURLUPART_PASSWORD: + storep = &u->password; + break; + case CURLUPART_OPTIONS: + storep = &u->options; + break; + case CURLUPART_HOST: + storep = &u->host; + break; + case CURLUPART_PORT: + storep = &u->port; + break; + case CURLUPART_PATH: + storep = &u->path; + break; + case CURLUPART_QUERY: + storep = &u->query; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; + break; + default: + return CURLUE_UNKNOWN_PART; + } + if(storep && *storep) { + free(*storep); + *storep = NULL; + } + return CURLUE_OK; + } + + switch(what) { + case CURLUPART_SCHEME: + if(!(flags & CURLU_NON_SUPPORT_SCHEME) && + /* verify that it is a fine scheme */ + !Curl_builtin_scheme(part)) + return CURLUE_UNSUPPORTED_SCHEME; + storep = &u->scheme; + urlencode = FALSE; /* never */ + break; + case CURLUPART_USER: + storep = &u->user; + break; + case CURLUPART_PASSWORD: + storep = &u->password; + break; + case CURLUPART_OPTIONS: + storep = &u->options; + break; + case CURLUPART_HOST: + storep = &u->host; + break; + case CURLUPART_PORT: + urlencode = FALSE; /* never */ + port = strtol(part, NULL, 10); /* Port number must be decimal */ + if((port <= 0) || (port > 0xffff)) + return CURLUE_BAD_PORT_NUMBER; + storep = &u->port; + break; + case CURLUPART_PATH: + urlskipslash = TRUE; + storep = &u->path; + break; + case CURLUPART_QUERY: + plusencode = urlencode; + appendquery = (flags & CURLU_APPENDQUERY)?1:0; + storep = &u->query; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; + break; + case CURLUPART_URL: { + /* + * Allow a new URL to replace the existing (if any) contents. + * + * If the existing contents is enough for a URL, allow a relative URL to + * replace it. + */ + CURLUcode result; + char *oldurl; + char *redired_url; + CURLU *handle2; + + if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) { + handle2 = curl_url(); + if(!handle2) + return CURLUE_OUT_OF_MEMORY; + result = parseurl(part, handle2, flags); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + /* extract the full "old" URL to do the redirect on */ + result = curl_url_get(u, CURLUPART_URL, &oldurl, flags); + if(result) { + /* couldn't get the old URL, just use the new! */ + handle2 = curl_url(); + if(!handle2) + return CURLUE_OUT_OF_MEMORY; + result = parseurl(part, handle2, flags); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + + /* apply the relative part to create a new URL */ + redired_url = Curl_concat_url(oldurl, part); + free(oldurl); + if(!redired_url) + return CURLUE_OUT_OF_MEMORY; + + /* now parse the new URL */ + handle2 = curl_url(); + if(!handle2) { + free(redired_url); + return CURLUE_OUT_OF_MEMORY; + } + result = parseurl(redired_url, handle2, flags); + free(redired_url); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + default: + return CURLUE_UNKNOWN_PART; + } + if(storep) { + const char *newp = part; + size_t nalloc = strlen(part); + + if(urlencode) { + const char *i; + char *o; + bool free_part = FALSE; + char *enc = malloc(nalloc * 3 + 1); /* for worst case! */ + if(!enc) + return CURLUE_OUT_OF_MEMORY; + if(plusencode) { + /* space to plus */ + i = part; + for(o = enc; *i; ++o, ++i) + *o = (*i == ' ') ? '+' : *i; + *o = 0; /* zero terminate */ + part = strdup(enc); + if(!part) { + free(enc); + return CURLUE_OUT_OF_MEMORY; + } + free_part = TRUE; + } + for(i = part, o = enc; *i; i++) { + if(Curl_isunreserved(*i) || + ((*i == '/') && urlskipslash) || + ((*i == '=') && appendquery) || + ((*i == '+') && plusencode)) { + *o = *i; + o++; + } + else { + snprintf(o, 4, "%%%02x", *i); + o += 3; + } + } + *o = 0; /* zero terminate */ + newp = enc; + if(free_part) + free((char *)part); + } + else { + char *p; + newp = strdup(part); + if(!newp) + return CURLUE_OUT_OF_MEMORY; + p = (char *)newp; + while(*p) { + /* make sure percent encoded are lower case */ + if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) && + (ISUPPER(p[1]) || ISUPPER(p[2]))) { + p[1] = (char)TOLOWER(p[1]); + p[2] = (char)TOLOWER(p[2]); + p += 3; + } + else + p++; + } + } + + if(appendquery) { + /* Append the string onto the old query. Add a '&' separator if none is + present at the end of the exsting query already */ + size_t querylen = u->query ? strlen(u->query) : 0; + bool addamperand = querylen && (u->query[querylen -1] != '&'); + if(querylen) { + size_t newplen = strlen(newp); + char *p = malloc(querylen + addamperand + newplen + 1); + if(!p) { + free((char *)newp); + return CURLUE_OUT_OF_MEMORY; + } + strcpy(p, u->query); /* original query */ + if(addamperand) + p[querylen] = '&'; /* ampersand */ + strcpy(&p[querylen + addamperand], newp); /* new suffix */ + free((char *)newp); + free(*storep); + *storep = p; + return CURLUE_OK; + } + } + + free(*storep); + *storep = (char *)newp; + } + /* set after the string, to make it not assigned if the allocation above + fails */ + if(port) + u->portnum = port; + return CURLUE_OK; +} diff --git a/lib/urldata.h b/lib/urldata.h index 67db3b2..11a6a22 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -142,14 +142,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include #endif /* HAVE_LIBSSH2_H */ -/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as - it needs to hold a full buffer as could be sent in a write callback. - - The size was 16KB for many years but was bumped to 64KB because it makes - libcurl able to do significantly faster uploads in some circumstances. Even - larger buffers can help further, but this is deemed a fair memory/speed - compromise. */ -#define UPLOAD_BUFSIZE 65536 /* The "master buffer" is for HTTP pipelining */ #define MASTERBUF_SIZE 16384 @@ -476,7 +468,6 @@ struct hostname { #define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) -#ifdef CURLRES_ASYNCH struct Curl_async { char *hostname; int port; @@ -485,7 +476,6 @@ struct Curl_async { int status; /* if done is TRUE, this is the status from the callback */ void *os_specific; /* 'struct thread_data' for Windows */ }; -#endif #define FIRSTSOCKET 0 #define SECONDARYSOCKET 1 @@ -511,6 +501,28 @@ enum upgrade101 { UPGR101_WORKING /* talking upgraded protocol */ }; +struct dohresponse { + unsigned char *memory; + size_t size; +}; + +/* one of these for each DoH request */ +struct dnsprobe { + CURL *easy; + int dnstype; + unsigned char dohbuffer[512]; + size_t dohlen; + struct dohresponse serverdoh; +}; + +struct dohdata { + struct curl_slist *headers; + struct dnsprobe probe[2]; + unsigned int pending; /* still outstanding requests */ + const char *host; + int port; +}; + /* * Request specific data in the easy handle (Curl_easy). Previously, * these members were on the connectdata struct but since a conn struct may @@ -606,6 +618,7 @@ struct SingleRequest { void *protop; /* Allocated protocol-specific data. Each protocol handler makes sure this points to data it needs. */ + struct dohdata doh; /* DoH specific data for this request */ }; /* @@ -636,7 +649,7 @@ struct Curl_handler { */ CURLcode (*connect_it)(struct connectdata *, bool *done); - /* See above. Currently only used for FTP. */ + /* See above. */ CURLcode (*connecting)(struct connectdata *, bool *done); CURLcode (*doing)(struct connectdata *, bool *done); @@ -716,6 +729,7 @@ struct Curl_handler { #define CONNCHECK_NONE 0 /* No checks */ #define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */ +#define CONNCHECK_KEEPALIVE (1<<1) /* Perform any keepalive function. */ #define CONNRESULT_NONE 0 /* No extra information. */ #define CONNRESULT_DEAD (1<<0) /* The connection is dead. */ @@ -892,6 +906,13 @@ struct connectdata { long ip_version; /* copied from the Curl_easy at creation time */ + /* Protocols can use a custom keepalive mechanism to keep connections alive. + This allows those protocols to track the last time the keepalive mechanism + was used on this connection. */ + struct curltime keepalive; + + long upkeep_interval_ms; /* Time between calls for connection upkeep. */ + /**** curl_get() phase fields */ curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ @@ -969,11 +990,8 @@ struct connectdata { #endif char syserr_buf [256]; /* buffer for Curl_strerror() */ - -#ifdef CURLRES_ASYNCH /* data used for the asynch name resolve callback */ struct Curl_async async; -#endif /* These three are used for chunked-encoding trailer support */ char *trailer; /* allocated buffer to store trailer in */ @@ -1206,6 +1224,18 @@ struct time_node { expire_id eid; }; +/* individual pieces of the URL */ +struct urlpieces { + char *scheme; + char *hostname; + char *port; + char *user; + char *password; + char *options; + char *path; + char *query; +}; + struct UrlState { /* Points to the connection cache */ @@ -1225,7 +1255,7 @@ struct UrlState { size_t headersize; /* size of the allocation */ char *buffer; /* download buffer */ - char *ulbuf; /* alloced upload buffer or NULL */ + char *ulbuf; /* allocated upload buffer or NULL */ curl_off_t current_speed; /* the ProgressShow() function sets this, bytes / second */ bool this_is_a_follow; /* this is a followed Location: request */ @@ -1296,9 +1326,6 @@ struct UrlState { /* for FTP downloads: how many CRLFs did we converted to LFs? */ curl_off_t crlf_conversions; #endif - char *pathbuffer;/* allocated buffer to store the URL's path part in */ - char *path; /* path to use, points to somewhere within the pathbuffer - area */ bool slash_removed; /* set TRUE if the 'path' points to a path where the initial URL slash separator has been taken off */ bool use_range; @@ -1332,6 +1359,8 @@ struct UrlState { #ifdef CURLDEBUG bool conncache_lock; #endif + CURLU *uh; /* URL handle for the current parsed URL */ + struct urlpieces up; }; @@ -1442,18 +1471,23 @@ enum dupstring { STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ #endif STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ + STRING_DOH, /* CURLOPT_DOH_URL */ /* -- end of zero-terminated strings -- */ STRING_LASTZEROTERMINATED, - /* -- below this are pointers to binary data that cannot be strdup'ed. - Each such pointer must be added manually to Curl_dupset() --- */ + /* -- below this are pointers to binary data that cannot be strdup'ed. --- */ STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ STRING_LAST /* not used, just an end-of-list marker */ }; +/* callback that gets called when this easy handle is completed within a multi + handle. Only used for internally created transfers, like for example + DoH. */ +typedef int (*multidone_func)(struct Curl_easy *easy, CURLcode result); + struct UserDefined { FILE *err; /* the stderr user data goes here */ void *debugdata; /* the data that will be passed to fdebug */ @@ -1562,8 +1596,8 @@ struct UserDefined { curl_proxytype proxytype; /* what kind of proxy that is in use */ long dns_cache_timeout; /* DNS cache timeout */ long buffer_size; /* size of receive buffer to use */ - long upload_buffer_size; /* size of upload buffer to use, - keep it >= CURL_MAX_WRITE_SIZE */ + size_t upload_buffer_size; /* size of upload buffer to use, + keep it >= CURL_MAX_WRITE_SIZE */ void *private_data; /* application-private data */ struct curl_slist *http200aliases; /* linked list of aliases for http200 */ @@ -1689,6 +1723,11 @@ struct UserDefined { before resolver start */ void *resolver_start_client; /* pointer to pass to resolver start callback */ bool disallow_username_in_url; /* disallow username in url */ + long upkeep_interval_ms; /* Time between calls for connection upkeep. */ + bool doh; /* DNS-over-HTTPS enabled */ + bool doh_get; /* use GET for DoH requests, instead of POST */ + multidone_func fmultidone; + struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ }; struct Names { diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c index 5d61ce6..be6d611 100644 --- a/lib/vauth/cleartext.c +++ b/lib/vauth/cleartext.c @@ -50,7 +50,7 @@ * * data [in] - The session handle. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. @@ -74,7 +74,7 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, plen = strlen(passwdp); /* Compute binary message length. Check for overflows. */ - if((ulen > SIZE_T_MAX/2) || (plen > (SIZE_T_MAX/2 - 2))) + if((ulen > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2))) return CURLE_OUT_OF_MEMORY; plainlen = 2 * ulen + plen + 2; diff --git a/lib/vauth/cram.c b/lib/vauth/cram.c index 3074a16..d148618 100644 --- a/lib/vauth/cram.c +++ b/lib/vauth/cram.c @@ -81,7 +81,7 @@ CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, * data [in] - The session handle. * chlg [in] - The challenge. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c index cc6f169..ab5156e 100644 --- a/lib/vauth/digest.c +++ b/lib/vauth/digest.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -342,7 +342,7 @@ bool Curl_auth_is_digest_supported(void) * data [in] - The session handle. * chlg64 [in] - The base64 encoded challenge message. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -668,7 +668,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, * * data [in] - The session handle. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * request [in] - The HTTP request. * uripath [in] - The path of the HTTP uri. * digest [in/out] - The digest data struct being used and modified. @@ -781,6 +781,8 @@ static CURLcode _Curl_auth_create_digest_http_message( */ hashthis = (unsigned char *) aprintf("%s:%s", request, uripath); + if(!hashthis) + return CURLE_OUT_OF_MEMORY; if(digest->qop && strcasecompare(digest->qop, "auth-int")) { /* We don't support auth-int for PUT or POST at the moment. @@ -932,7 +934,7 @@ static CURLcode _Curl_auth_create_digest_http_message( * * data [in] - The session handle. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * request [in] - The HTTP request. * uripath [in] - The path of the HTTP uri. * digest [in/out] - The digest data struct being used and modified. diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c index a3f96ed..9287557 100644 --- a/lib/vauth/digest_sspi.c +++ b/lib/vauth/digest_sspi.c @@ -75,7 +75,7 @@ bool Curl_auth_is_digest_supported(void) * data [in] - The session handle. * chlg64 [in] - The base64 encoded challenge message. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -391,7 +391,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * request [in] - The HTTP request. * uripath [in] - The path of the HTTP uri. * digest [in/out] - The digest data struct being used and modified. diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c index 560ecc5..55daec1 100644 --- a/lib/vauth/krb5_gssapi.c +++ b/lib/vauth/krb5_gssapi.c @@ -65,7 +65,7 @@ bool Curl_auth_is_gssapi_supported(void) * * data [in] - The session handle. * userp [in] - The user name. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in[ - The host name. * mutual_auth [in] - Flag specifying whether or not mutual authentication diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c index 9afb971..cb11ed9 100644 --- a/lib/vauth/krb5_sspi.c +++ b/lib/vauth/krb5_sspi.c @@ -71,7 +71,7 @@ bool Curl_auth_is_gssapi_supported(void) * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * mutual_auth [in] - Flag specifying whether or not mutual authentication diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c index cdb8d8f..11f42f5 100644 --- a/lib/vauth/ntlm.c +++ b/lib/vauth/ntlm.c @@ -354,7 +354,7 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. @@ -481,7 +481,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c index 089c1a6..b66cfe7 100644 --- a/lib/vauth/ntlm_sspi.c +++ b/lib/vauth/ntlm_sspi.c @@ -69,7 +69,7 @@ bool Curl_auth_is_ntlm_supported(void) * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. @@ -234,7 +234,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c index 5196c27..4a48bdd 100644 --- a/lib/vauth/spnego_gssapi.c +++ b/lib/vauth/spnego_gssapi.c @@ -64,7 +64,7 @@ bool Curl_auth_is_spnego_supported(void) * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * chlg64 [in] - The optional base64 encoded challenge message. diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c index 1fe19e3..77d1895 100644 --- a/lib/vauth/spnego_sspi.c +++ b/lib/vauth/spnego_sspi.c @@ -71,8 +71,8 @@ bool Curl_auth_is_spnego_supported(void) * Parameters: * * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * user [in] - The user name in the format User or Domain\User. + * password [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * chlg64 [in] - The optional base64 encoded challenge message. diff --git a/lib/vtls/axtls.h b/lib/vtls/axtls.h index 3f1e129..cb81872 100644 --- a/lib/vtls/axtls.h +++ b/lib/vtls/axtls.h @@ -31,4 +31,3 @@ extern const struct Curl_ssl Curl_ssl_axtls; #endif /* USE_AXTLS */ #endif /* HEADER_CURL_AXTLS_H */ - diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c index 1aea0dc..e8116b8 100644 --- a/lib/vtls/darwinssl.c +++ b/lib/vtls/darwinssl.c @@ -64,6 +64,7 @@ #define CURL_BUILD_IOS 0 #define CURL_BUILD_IOS_7 0 +#define CURL_BUILD_IOS_9 0 #define CURL_BUILD_IOS_11 0 #define CURL_BUILD_MAC 1 /* This is the maximum API level we are allowed to use when building: */ @@ -72,6 +73,7 @@ #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 +#define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 #define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 /* These macros mean "the following code is present to allow runtime backward compatibility with at least this cat or earlier": @@ -86,6 +88,7 @@ #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE #define CURL_BUILD_IOS 1 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 +#define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 #define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 #define CURL_BUILD_MAC 0 #define CURL_BUILD_MAC_10_5 0 @@ -93,6 +96,7 @@ #define CURL_BUILD_MAC_10_7 0 #define CURL_BUILD_MAC_10_8 0 #define CURL_BUILD_MAC_10_9 0 +#define CURL_BUILD_MAC_10_11 0 #define CURL_BUILD_MAC_10_13 0 #define CURL_SUPPORT_MAC_10_5 0 #define CURL_SUPPORT_MAC_10_6 0 @@ -116,6 +120,7 @@ #include "vtls.h" #include "darwinssl.h" #include "curl_printf.h" +#include "strdup.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -945,7 +950,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data, if(!c) { failf(data, "SSL: invalid CA certificate subject"); - return CURLE_OUT_OF_MEMORY; + return CURLE_SSL_CACERT; } /* If the subject is already available as UTF-8 encoded (ie 'direct') then @@ -1299,8 +1304,6 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version << 16; - break; case CURL_SSLVERSION_MAX_DEFAULT: ssl_version_max = max_supported_version_by_os; break; @@ -1646,6 +1649,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, } CFRelease(cert); + if(result == CURLE_SSL_CACERT) + return CURLE_SSL_CERTPROBLEM; if(result) return result; } @@ -1781,107 +1786,118 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, higher priority, but it's probably better that we not connect at all than to give the user a false sense of security if the server only supports insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ - (void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count); + err = SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", + err); + return CURLE_SSL_CIPHER; + } all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(all_ciphers && allowed_ciphers && - SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers, - &all_ciphers_count) == noErr) { - for(i = 0UL ; i < all_ciphers_count ; i++) { -#if CURL_BUILD_MAC - /* There's a known bug in early versions of Mountain Lion where ST's ECC - ciphers (cipher suite 0xC001 through 0xC032) simply do not work. - Work around the problem here by disabling those ciphers if we are - running in an affected version of OS X. */ - if(darwinver_maj == 12 && darwinver_min <= 3 && - all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { - continue; - } -#endif /* CURL_BUILD_MAC */ - switch(all_ciphers[i]) { - /* Disable NULL ciphersuites: */ - case SSL_NULL_WITH_NULL_NULL: - case SSL_RSA_WITH_NULL_MD5: - case SSL_RSA_WITH_NULL_SHA: - case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ - case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ - case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ - case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ - case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ - case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ - case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ - case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ - case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ - case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ - case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ - case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ - case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ - /* Disable anonymous ciphersuites: */ - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - case SSL_DH_anon_WITH_RC4_128_MD5: - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_anon_WITH_DES_CBC_SHA: - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ - case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ - case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ - case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ - case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ - case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ - case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ - case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ - case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ - /* Disable weak key ciphersuites: */ - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_RSA_WITH_DES_CBC_SHA: - case SSL_DH_DSS_WITH_DES_CBC_SHA: - case SSL_DH_RSA_WITH_DES_CBC_SHA: - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - /* Disable IDEA: */ - case SSL_RSA_WITH_IDEA_CBC_SHA: - case SSL_RSA_WITH_IDEA_CBC_MD5: - /* Disable RC4: */ - case SSL_RSA_WITH_RC4_128_MD5: - case SSL_RSA_WITH_RC4_128_SHA: - case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ - case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ - case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ - case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ - case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ - case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ - case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ - break; - default: /* enable everything else */ - allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; - break; - } - } - err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers, - allowed_ciphers_count); - if(err != noErr) { - failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } + if(!all_ciphers) { + failf(data, "SSL: Failed to allocate memory for all ciphers"); + return CURLE_OUT_OF_MEMORY; } - else { + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!allowed_ciphers) { Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); failf(data, "SSL: Failed to allocate memory for allowed ciphers"); return CURLE_OUT_OF_MEMORY; } + err = SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers, + &all_ciphers_count); + if(err != noErr) { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + return CURLE_SSL_CIPHER; + } + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* There's a known bug in early versions of Mountain Lion where ST's ECC + ciphers (cipher suite 0xC001 through 0xC032) simply do not work. + Work around the problem here by disabling those ciphers if we are + running in an affected version of OS X. */ + if(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + switch(all_ciphers[i]) { + /* Disable NULL ciphersuites: */ + case SSL_NULL_WITH_NULL_NULL: + case SSL_RSA_WITH_NULL_MD5: + case SSL_RSA_WITH_NULL_SHA: + case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ + case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ + case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ + case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ + case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ + case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ + case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ + case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ + case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ + case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ + case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ + case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ + case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ + /* Disable anonymous ciphersuites: */ + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + case SSL_DH_anon_WITH_RC4_128_MD5: + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_anon_WITH_DES_CBC_SHA: + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ + case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ + case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ + case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ + case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ + case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ + case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ + case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ + case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ + /* Disable weak key ciphersuites: */ + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_RSA_WITH_DES_CBC_SHA: + case SSL_DH_DSS_WITH_DES_CBC_SHA: + case SSL_DH_RSA_WITH_DES_CBC_SHA: + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + /* Disable IDEA: */ + case SSL_RSA_WITH_IDEA_CBC_SHA: + case SSL_RSA_WITH_IDEA_CBC_MD5: + /* Disable RC4: */ + case SSL_RSA_WITH_RC4_128_MD5: + case SSL_RSA_WITH_RC4_128_SHA: + case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ + case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ + case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ + case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ + case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ + case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ + case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ + break; + default: /* enable everything else */ + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + break; + } + } + err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers, + allowed_ciphers_count); Curl_safefree(all_ciphers); Curl_safefree(allowed_ciphers); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 /* We want to enable 1/n-1 when using a CBC cipher unless the user @@ -2039,7 +2055,7 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen) if(len + n >= cap) { cap *= 2; - data = realloc(data, cap); + data = Curl_saferealloc(data, cap); if(!data) { close(fd); return -1; @@ -2057,35 +2073,6 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen) return 0; } -static int sslerr_to_curlerr(struct Curl_easy *data, int err) -{ - switch(err) { - case errSSLXCertChainInvalid: - failf(data, "SSL certificate problem: Invalid certificate chain"); - return CURLE_SSL_CACERT; - case errSSLUnknownRootCert: - failf(data, "SSL certificate problem: Untrusted root certificate"); - return CURLE_SSL_CACERT; - case errSSLNoRootCert: - failf(data, "SSL certificate problem: No root certificate"); - return CURLE_SSL_CACERT; - case errSSLCertExpired: - failf(data, "SSL certificate problem: Certificate chain had an " - "expired certificate"); - return CURLE_SSL_CACERT; - case errSSLBadCert: - failf(data, "SSL certificate problem: Couldn't understand the server " - "certificate format"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLHostNameMismatch: - failf(data, "SSL certificate peer hostname mismatch"); - return CURLE_PEER_FAILED_VERIFICATION; - default: - failf(data, "SSL unexpected certificate error %d", err); - return CURLE_SSL_CACERT; - } -} - static int append_cert_to_array(struct Curl_easy *data, unsigned char *buf, size_t buflen, CFMutableArrayRef array) @@ -2103,13 +2090,20 @@ static int append_cert_to_array(struct Curl_easy *data, CFRelease(certdata); if(!cacert) { failf(data, "SSL: failed to create SecCertificate from CA certificate"); - return CURLE_SSL_CACERT; + return CURLE_SSL_CACERT_BADFILE; } /* Check if cacert is valid. */ result = CopyCertSubject(data, cacert, &certp); - if(result) - return result; + switch(result) { + case CURLE_OK: + break; + case CURLE_PEER_FAILED_VERIFICATION: + return CURLE_SSL_CACERT_BADFILE; + case CURLE_OUT_OF_MEMORY: + default: + return result; + } free(certp); CFArrayAppendValue(array, cacert); @@ -2128,7 +2122,7 @@ static int verify_cert(const char *cafile, struct Curl_easy *data, if(read_cert(cafile, &certbuf, &buflen) < 0) { failf(data, "SSL: failed to read or invalid CA certificate"); - return CURLE_SSL_CACERT; + return CURLE_SSL_CACERT_BADFILE; } /* @@ -2161,7 +2155,7 @@ static int verify_cert(const char *cafile, struct Curl_easy *data, CFRelease(array); failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle", n, offset); - return CURLE_SSL_CACERT; + return CURLE_SSL_CACERT_BADFILE; } offset += res; @@ -2195,22 +2189,27 @@ static int verify_cert(const char *cafile, struct Curl_easy *data, if(trust == NULL) { failf(data, "SSL: error getting certificate chain"); CFRelease(array); - return CURLE_OUT_OF_MEMORY; + return CURLE_PEER_FAILED_VERIFICATION; } else if(ret != noErr) { CFRelease(array); - return sslerr_to_curlerr(data, ret); + failf(data, "SSLCopyPeerTrust() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; } ret = SecTrustSetAnchorCertificates(trust, array); if(ret != noErr) { + CFRelease(array); CFRelease(trust); - return sslerr_to_curlerr(data, ret); + failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; } ret = SecTrustSetAnchorCertificatesOnly(trust, true); if(ret != noErr) { + CFRelease(array); CFRelease(trust); - return sslerr_to_curlerr(data, ret); + failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; } SecTrustResultType trust_eval = 0; @@ -2218,7 +2217,8 @@ static int verify_cert(const char *cafile, struct Curl_easy *data, CFRelease(array); CFRelease(trust); if(ret != noErr) { - return sslerr_to_curlerr(data, ret); + failf(data, "SecTrustEvaluate() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; } switch(trust_eval) { @@ -2379,6 +2379,53 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) /* the documentation says we need to call SSLHandshake() again */ return darwinssl_connect_step2(conn, sockindex); + /* Problem with encrypt / decrypt */ + case errSSLPeerDecodeError: + failf(data, "Decode failed"); + break; + case errSSLDecryptionFail: + case errSSLPeerDecryptionFail: + failf(data, "Decryption failed"); + break; + case errSSLPeerDecryptError: + failf(data, "A decryption error occurred"); + break; + case errSSLBadCipherSuite: + failf(data, "A bad SSL cipher suite was encountered"); + break; + case errSSLCrypto: + failf(data, "An underlying cryptographic error was encountered"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + case errSSLWeakPeerEphemeralDHKey: + failf(data, "Indicates a weak ephemeral Diffie-Hellman key"); + break; +#endif + + /* Problem with the message record validation */ + case errSSLBadRecordMac: + case errSSLPeerBadRecordMac: + failf(data, "A record with a bad message authentication code (MAC) " + "was encountered"); + break; + case errSSLRecordOverflow: + case errSSLPeerRecordOverflow: + failf(data, "A record overflow occurred"); + break; + + /* Problem with zlib decompression */ + case errSSLPeerDecompressFail: + failf(data, "Decompression failed"); + break; + + /* Problem with access */ + case errSSLPeerAccessDenied: + failf(data, "Access was denied"); + break; + case errSSLPeerInsufficientSecurity: + failf(data, "There is insufficient security for this operation"); + break; + /* These are all certificate problems with the server: */ case errSSLXCertChainInvalid: failf(data, "SSL certificate problem: Invalid certificate chain"); @@ -2389,28 +2436,44 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) case errSSLNoRootCert: failf(data, "SSL certificate problem: No root certificate"); return CURLE_SSL_CACERT; + case errSSLCertNotYetValid: + failf(data, "SSL certificate problem: The certificate chain had a " + "certificate that is not yet valid"); + return CURLE_SSL_CACERT; case errSSLCertExpired: + case errSSLPeerCertExpired: failf(data, "SSL certificate problem: Certificate chain had an " "expired certificate"); return CURLE_SSL_CACERT; case errSSLBadCert: + case errSSLPeerBadCert: failf(data, "SSL certificate problem: Couldn't understand the server " "certificate format"); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CACERT; + case errSSLPeerUnsupportedCert: + failf(data, "SSL certificate problem: An unsupported certificate " + "format was encountered"); + return CURLE_SSL_CACERT; + case errSSLPeerCertRevoked: + failf(data, "SSL certificate problem: The certificate was revoked"); + return CURLE_SSL_CACERT; + case errSSLPeerCertUnknown: + failf(data, "SSL certificate problem: The certificate is unknown"); + return CURLE_SSL_CACERT; /* These are all certificate problems with the client: */ case errSecAuthFailed: failf(data, "SSL authentication failed"); - return CURLE_SSL_CONNECT_ERROR; + break; case errSSLPeerHandshakeFail: failf(data, "SSL peer handshake failed, the server most likely " "requires a client certificate to connect"); - return CURLE_SSL_CONNECT_ERROR; + break; case errSSLPeerUnknownCA: failf(data, "SSL server rejected the client certificate due to " "the certificate being signed by an unknown certificate " "authority"); - return CURLE_SSL_CONNECT_ERROR; + break; /* This error is raised if the server's cert didn't match the server's host name: */ @@ -2419,30 +2482,98 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) "certificate did not match \"%s\"\n", conn->host.dispname); return CURLE_PEER_FAILED_VERIFICATION; + /* Problem with SSL / TLS negotiation */ + case errSSLNegotiation: + failf(data, "Could not negotiate an SSL cipher suite with the server"); + break; + case errSSLBadConfiguration: + failf(data, "A configuration error occurred"); + break; + case errSSLProtocol: + failf(data, "SSL protocol error"); + break; + case errSSLPeerProtocolVersion: + failf(data, "A bad protocol version was encountered"); + break; + case errSSLPeerNoRenegotiation: + failf(data, "No renegotiation is allowed"); + break; + /* Generic handshake errors: */ case errSSLConnectionRefused: failf(data, "Server dropped the connection during the SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; + break; case errSSLClosedAbort: failf(data, "Server aborted the SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLNegotiation: - failf(data, "Could not negotiate an SSL cipher suite with the server"); - return CURLE_SSL_CONNECT_ERROR; + break; + case errSSLClosedGraceful: + failf(data, "The connection closed gracefully"); + break; + case errSSLClosedNoNotify: + failf(data, "The server closed the session with no notification"); + break; /* Sometimes paramErr happens with buggy ciphers: */ - case paramErr: case errSSLInternal: + case paramErr: + case errSSLInternal: + case errSSLPeerInternalError: failf(data, "Internal SSL engine error encountered during the " "SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; + break; case errSSLFatalAlert: failf(data, "Fatal SSL engine error encountered during the SSL " "handshake"); - return CURLE_SSL_CONNECT_ERROR; + break; + /* Unclassified error */ + case errSSLBufferOverflow: + failf(data, "An insufficient buffer was provided"); + break; + case errSSLIllegalParam: + failf(data, "An illegal parameter was encountered"); + break; + case errSSLModuleAttach: + failf(data, "Module attach failure"); + break; + case errSSLSessionNotFound: + failf(data, "An attempt to restore an unknown session failed"); + break; + case errSSLPeerExportRestriction: + failf(data, "An export restriction occurred"); + break; + case errSSLPeerUserCancelled: + failf(data, "The user canceled the operation"); + break; + case errSSLPeerUnexpectedMsg: + failf(data, "Peer rejected unexpected message"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + /* Treaing non-fatal error as fatal like before */ + case errSSLClientHelloReceived: + failf(data, "A non-fatal result for providing a server name " + "indication"); + break; +#endif + + /* Error codes defined in the enum but should never be returned. + We list them here just in case. */ +#if CURL_BUILD_MAC_10_6 + /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ + case errSSLClientCertRequested: + failf(data, "The server has requested a client certificate"); + break; +#endif +#if CURL_BUILD_MAC_10_9 + /* Alias for errSSLLast, end of error range */ + case errSSLUnexpectedRecord: + failf(data, "Unexpected (skipped) record in DTLS"); + break; +#endif default: + /* May also return codes listed in Security Framework Result Codes */ failf(data, "Unknown SSL protocol error in connection to %s:%d", hostname, err); - return CURLE_SSL_CONNECT_ERROR; + break; } + return CURLE_SSL_CONNECT_ERROR; } else { /* we have been connected fine, we're not waiting for anything else. */ diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c index a0b4960..8d1b3d6 100644 --- a/lib/vtls/gskit.c +++ b/lib/vtls/gskit.c @@ -766,8 +766,6 @@ set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn) long i = ssl_version; switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version; - break; case CURL_SSLVERSION_MAX_DEFAULT: ssl_version_max = CURL_SSLVERSION_TLSv1_2; break; @@ -1316,8 +1314,7 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex) static size_t Curl_gskit_version(char *buffer, size_t size) { - strncpy(buffer, "GSKit", size); - return strlen(buffer); + return snprintf(buffer, size, "GSKit"); } diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 207b0fd..37662a7 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -94,6 +94,10 @@ static bool gtls_inited = FALSE; # endif #endif +#if (GNUTLS_VERSION_NUMBER >= 0x030603) +#define HAS_TLS13 +#endif + #ifdef HAS_OCSP # include #endif @@ -390,9 +394,10 @@ set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn) switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version << 16; - break; case CURL_SSLVERSION_MAX_DEFAULT: +#ifdef HAS_TLS13 + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; +#endif ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; } @@ -410,8 +415,13 @@ set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn) protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2; break; case CURL_SSLVERSION_TLSv1_3: +#ifdef HAS_TLS13 + protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_3; + break; +#else failf(data, "GnuTLS: TLS 1.3 is not yet supported"); return CURLE_SSL_CONNECT_ERROR; +#endif } } return CURLE_OK; @@ -429,13 +439,9 @@ set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn) struct Curl_easy *data = conn->data; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); - if(ssl_version == CURL_SSLVERSION_TLSv1_3 || - ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) { - failf(data, "GnuTLS: TLS 1.3 is not yet supported"); - return CURLE_SSL_CONNECT_ERROR; - } + if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) { - ssl_version_max = ssl_version << 16; + ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; } switch(ssl_version | ssl_version_max) { case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: @@ -447,7 +453,6 @@ set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn) "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP; return CURLE_OK; case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP; return CURLE_OK; @@ -456,15 +461,54 @@ set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn) "+VERS-TLS1.1:" GNUTLS_SRP; return CURLE_OK; case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP; return CURLE_OK; case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" "+VERS-TLS1.2:" GNUTLS_SRP; return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: +#ifdef HAS_TLS13 + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.3:" GNUTLS_SRP; + return CURLE_OK; +#else + failf(data, "GnuTLS: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; +#endif + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; } failf(data, "GnuTLS: cannot set ssl protocol"); @@ -677,6 +721,9 @@ gtls_connect_step1(struct connectdata *conn, protocol_priority[0] = GNUTLS_TLS1_0; protocol_priority[1] = GNUTLS_TLS1_1; protocol_priority[2] = GNUTLS_TLS1_2; +#ifdef HAS_TLS13 + protocol_priority[3] = GNUTLS_TLS1_3; +#endif break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: @@ -709,11 +756,14 @@ gtls_connect_step1(struct connectdata *conn, switch(SSL_CONN_CONFIG(version)) { case CURL_SSLVERSION_SSLv3: prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0"; - sni = false; break; case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP; + prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: @@ -1102,8 +1152,8 @@ gtls_connect_step3(struct connectdata *conn, return CURLE_SSL_INVALIDCERTSTATUS; } - rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); + (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, + &status, NULL, NULL, NULL, &reason); switch(status) { case GNUTLS_OCSP_CERT_GOOD: @@ -1589,7 +1639,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) ssize_t result; int retval = 0; struct Curl_easy *data = conn->data; - int done = 0; + bool done = FALSE; char buf[120]; /* This has only been tested on the proftpd server, and the mod_tls code @@ -1613,7 +1663,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) case 0: /* This is the expected response. There was no data but only the close notify alert */ - done = 1; + done = TRUE; break; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: @@ -1621,21 +1671,20 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) break; default: retval = -1; - done = 1; + done = TRUE; break; } } else if(0 == what) { /* timeout */ failf(data, "SSL shutdown timeout"); - done = 1; - break; + done = TRUE; } else { /* anything that gets here is fatally bad */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); retval = -1; - done = 1; + done = TRUE; } } gnutls_deinit(BACKEND->session); diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index d7759dc..c5ed887 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -205,14 +205,11 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: ssl_version = CURL_SSLVERSION_TLSv1_0; - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; } switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version << 16; - break; case CURL_SSLVERSION_MAX_DEFAULT: ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c new file mode 100644 index 0000000..6a2b67e --- /dev/null +++ b/lib/vtls/mesalink.c @@ -0,0 +1,627 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2017-2018, Yiming Jing, + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all MesaLink-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +/* + * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * Thanks for code and inspiration! + */ + +#include "curl_setup.h" + +#ifdef USE_MESALINK + +#include +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" + +#include "mesalink.h" +#include +#include + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define MESALINK_MAX_ERROR_SZ 80 + +struct ssl_backend_data +{ + SSL_CTX *ctx; + SSL *handle; +}; + +#define BACKEND connssl->backend + +static Curl_recv mesalink_recv; +static Curl_send mesalink_send; + +/* + * This function loads all the client/CA certificates and CRLs. Setup the TLS + * layer and do all necessary magic. + */ +static CURLcode +mesalink_connect_step1(struct connectdata *conn, int sockindex) +{ + char *ciphers; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char *const ssl_capath = SSL_CONN_CONFIG(CApath); + struct in_addr addr4; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + const char *const hostname = + SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + size_t hostname_len = strlen(hostname); + + SSL_METHOD *req_method = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; + + if(connssl->state == ssl_connection_complete) + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "MesaLink does not support to set maximum SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv3: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + failf(data, "MesaLink does not support SSL 3.0, TLS 1.0, or TLS 1.1"); + return CURLE_NOT_BUILT_IN; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1_2: + req_method = TLSv1_2_client_method(); + break; + case CURL_SSLVERSION_TLSv1_3: + req_method = TLSv1_3_client_method(); + break; + case CURL_SSLVERSION_SSLv2: + failf(data, "MesaLink does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(!req_method) { + failf(data, "SSL: couldn't create a method!"); + return CURLE_OUT_OF_MEMORY; + } + + if(BACKEND->ctx) + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = SSL_CTX_new(req_method); + + if(!BACKEND->ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + + SSL_CTX_set_verify( + BACKEND->ctx, verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); + + if(ssl_cafile || ssl_capath) { + if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) { + if(verifypeer) { + failf(data, + "error setting certificate verify locations:\n" + " CAfile: %s\n CApath: %s", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + infof(data, + "error setting certificate verify locations," + " continuing anyway:\n"); + } + else { + infof(data, "successfully set certificate verify locations:\n"); + } + infof(data, + " CAfile: %s\n" + " CApath: %s\n", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { +#ifdef MESALINK_HAVE_CIPHER + if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } +#endif + infof(data, "Cipher selection: %s\n", ciphers); + } + + if(BACKEND->handle) + SSL_free(BACKEND->handle); + BACKEND->handle = SSL_new(BACKEND->ctx); + if(!BACKEND->handle) { + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + + if((hostname_len < USHRT_MAX) && + (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) +#ifdef ENABLE_IPV6 + && (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) +#endif + ) { + /* hostname is not a valid IP address */ + if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) { + failf(data, + "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#ifdef CURLDEBUG + /* Check if the hostname is 127.0.0.1 or [::1]; + * otherwise reject because MesaLink always wants a valid DNS Name + * specified in RFC 5280 Section 7.2 */ + if(strncmp(hostname, "127.0.0.1", 9) == 0 +#ifdef ENABLE_IPV6 + || strncmp(hostname, "[::1]", 5) == 0 +#endif + ) { + SSL_set_tlsext_host_name(BACKEND->handle, "localhost"); + } + else +#endif + { + failf(data, + "ERROR: MesaLink does not accept an IP address as a hostname\n"); + return CURLE_SSL_CONNECT_ERROR; + } + } + +#ifdef MESALINK_HAVE_SESSION + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(conn); + failf( + data, + "SSL: SSL_set_session failed: %s", + ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } +#endif /* MESALINK_HAVE_SESSION */ + + if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) { + failf(data, "SSL: SSL_set_fd failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static CURLcode +mesalink_connect_step2(struct connectdata *conn, int sockindex) +{ + int ret = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + conn->recv[sockindex] = mesalink_recv; + conn->send[sockindex] = mesalink_send; + + ret = SSL_connect(BACKEND->handle); + if(ret != SSL_SUCCESS) { + char error_buffer[MESALINK_MAX_ERROR_SZ]; + int detail = SSL_get_error(BACKEND->handle, ret); + + if(SSL_ERROR_WANT_CONNECT == detail) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else { + failf(data, + "SSL_connect failed with error %d: %s", + detail, + ERR_error_string_n(detail, error_buffer, sizeof(error_buffer))); + ERR_print_errors_fp(stderr); + if(detail && SSL_CONN_CONFIG(verifypeer)) { + detail &= ~0xFF; + if(detail == TLS_ERROR_WEBPKI_ERRORS) { + failf(data, "Cert verify failed"); + return CURLE_PEER_FAILED_VERIFICATION; + } + } + return CURLE_SSL_CONNECT_ERROR; + } + } + + connssl->connecting_state = ssl_connect_3; + infof(data, + "SSL connection using %s / %s\n", + SSL_get_version(BACKEND->handle), + SSL_get_cipher_name(BACKEND->handle)); + + return CURLE_OK; +} + +static CURLcode +mesalink_connect_step3(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + +#ifdef MESALINK_HAVE_SESSION + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + SSL_SESSION *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = SSL_get_session(BACKEND->handle); + + Curl_ssl_sessionid_lock(conn); + incache = + !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + result = Curl_ssl_addsessionid( + conn, our_ssl_sessionid, 0 /* unknown size */, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "failed to store ssl session"); + return result; + } + } + Curl_ssl_sessionid_unlock(conn); + } +#endif /* MESALINK_HAVE_SESSION */ + + connssl->connecting_state = ssl_connect_done; + + return result; +} + +static ssize_t +mesalink_send(struct connectdata *conn, int sockindex, const void *mem, + size_t len, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + char error_buffer[MESALINK_MAX_ERROR_SZ]; + int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + int rc = SSL_write(BACKEND->handle, mem, memlen); + + if(rc < 0) { + int err = SSL_get_error(BACKEND->handle, rc); + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_write() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, + "SSL write: %s, errno %d", + ERR_error_string_n(err, error_buffer, sizeof(error_buffer)), + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + return rc; +} + +static void +Curl_mesalink_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + (void)SSL_shutdown(BACKEND->handle); + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + if(BACKEND->ctx) { + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = NULL; + } +} + +static ssize_t +mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + char error_buffer[MESALINK_MAX_ERROR_SZ]; + int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + int nread = SSL_read(BACKEND->handle, buf, buffsize); + + if(nread <= 0) { + int err = SSL_get_error(BACKEND->handle, nread); + + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + case IO_ERROR_CONNECTION_ABORTED: + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, + "SSL read: %s, errno %d", + ERR_error_string_n(err, error_buffer, sizeof(error_buffer)), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + return nread; +} + +static size_t +Curl_mesalink_version(char *buffer, size_t size) +{ + return snprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING); +} + +static int +Curl_mesalink_init(void) +{ + return (SSL_library_init() == SSL_SUCCESS); +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int +Curl_mesalink_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + return retval; +} + +static CURLcode +mesalink_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = mesalink_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = + ssl_connect_2_writing == connssl->connecting_state ? sockfd + : CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == connssl->connecting_state + ? sockfd + : CURL_SOCKET_BAD; + + what = Curl_socket_check( + readfd, CURL_SOCKET_BAD, writefd, nonblocking ? 0 : timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = mesalink_connect_step2(conn, sockindex); + + if(result || + (nonblocking && (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) { + return result; + } + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = mesalink_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = mesalink_recv; + conn->send[sockindex] = mesalink_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode +Curl_mesalink_connect_nonblocking(struct connectdata *conn, int sockindex, + bool *done) +{ + return mesalink_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode +Curl_mesalink_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = mesalink_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static void * +Curl_mesalink_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_mesalink = { + { CURLSSLBACKEND_MESALINK, "MesaLink" }, /* info */ + + SSLSUPP_SSL_CTX, + + sizeof(struct ssl_backend_data), + + Curl_mesalink_init, /* init */ + Curl_none_cleanup, /* cleanup */ + Curl_mesalink_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_mesalink_shutdown, /* shutdown */ + Curl_none_data_pending, /* data_pending */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_mesalink_connect, /* connect */ + Curl_mesalink_connect_nonblocking, /* connect_nonblocking */ + Curl_mesalink_get_internals, /* get_internals */ + Curl_mesalink_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +#endif diff --git a/lib/amigaos.h b/lib/vtls/mesalink.h similarity index 74% copy from lib/amigaos.h copy to lib/vtls/mesalink.h index 02bee16..54cb94a 100644 --- a/lib/amigaos.h +++ b/lib/vtls/mesalink.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_AMIGAOS_H -#define HEADER_CURL_AMIGAOS_H +#ifndef HEADER_CURL_MESALINK_H +#define HEADER_CURL_MESALINK_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,7 +7,8 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * Copyright (C) 2017-2018, Yiming Jing, + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,17 +24,9 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(__AMIGA__) && !defined(__ixemul__) +#ifdef USE_MESALINK -bool Curl_amiga_init(); -void Curl_amiga_cleanup(); - -#else - -#define Curl_amiga_init() 1 -#define Curl_amiga_cleanup() Curl_nop_stmt - -#endif - -#endif /* HEADER_CURL_AMIGAOS_H */ +extern const struct Curl_ssl Curl_ssl_mesalink; +#endif /* USE_MESALINK */ +#endif /* HEADER_CURL_MESALINK_H */ diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index 89f8183..a3d3e58 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -217,10 +217,15 @@ static const cipher_s cipherlist[] = { #endif }; +#ifdef WIN32 +static const char *pem_library = "nsspem.dll"; +static const char *trust_library = "nssckbi.dll"; +#else static const char *pem_library = "libnsspem.so"; -static SECMODModule *pem_module = NULL; - static const char *trust_library = "libnssckbi.so"; +#endif + +static SECMODModule *pem_module = NULL; static SECMODModule *trust_module = NULL; /* NSPR I/O layer we use to detect blocking direction during SSL handshake */ @@ -1522,7 +1527,6 @@ static bool is_nss_error(CURLcode err) { switch(err) { case CURLE_PEER_FAILED_VERIFICATION: - case CURLE_SSL_CACERT: case CURLE_SSL_CERTPROBLEM: case CURLE_SSL_CONNECT_ERROR: case CURLE_SSL_ISSUER_ERROR: @@ -1579,8 +1583,9 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, infof(data, "%s %s\n", (result) ? "failed to load" : "loaded", trust_library); if(result == CURLE_FAILED_INIT) - /* make the error non-fatal if we are not going to verify peer */ - result = CURLE_SSL_CACERT_BADFILE; + /* If libnssckbi.so is not available (or fails to load), one can still + use CA certificates stored in NSS database. Ignore the failure. */ + result = CURLE_OK; } else if(!use_trust_module && trust_module) { /* libnssckbi.so not needed but already loaded --> unload it! */ @@ -1715,8 +1720,6 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); return result; } - if(max == CURL_SSLVERSION_MAX_NONE) - sslver->max = sslver->min; } switch(max) { diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index a487f55..4c5e8c1 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -69,7 +69,7 @@ #include #endif -#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && /* 1.0.0 or later */ \ +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && /* 0.9.8 or later */ \ !defined(OPENSSL_NO_ENGINE) #define USE_OPENSSL_ENGINE #include @@ -129,16 +129,15 @@ #define X509_get0_notBefore(x) X509_get_notBefore(x) #define X509_get0_notAfter(x) X509_get_notAfter(x) #define CONST_EXTS /* nope */ -#ifdef LIBRESSL_VERSION_NUMBER -static unsigned long OpenSSL_version_num(void) -{ - return LIBRESSL_VERSION_NUMBER; -} -#else +#ifndef LIBRESSL_VERSION_NUMBER #define OpenSSL_version_num() SSLeay() #endif #endif +#ifdef LIBRESSL_VERSION_NUMBER +#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER +#endif + #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ !(defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -178,6 +177,7 @@ static unsigned long OpenSSL_version_num(void) !defined(LIBRESSL_VERSION_NUMBER) && \ !defined(OPENSSL_IS_BORINGSSL)) #define HAVE_SSL_CTX_SET_CIPHERSUITES +#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH #endif #if defined(LIBRESSL_VERSION_NUMBER) @@ -253,7 +253,7 @@ static void ossl_keylog_callback(const SSL *ssl, const char *line) if(!buf) return; } - strncpy(buf, line, linelen); + memcpy(buf, line, linelen); buf[linelen] = '\n'; buf[linelen + 1] = '\0'; @@ -978,7 +978,7 @@ static int Curl_ossl_init(void) OPENSSL_load_builtin_modules(); -#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES +#ifdef USE_OPENSSL_ENGINE ENGINE_load_builtin_engines(); #endif @@ -994,9 +994,11 @@ static int Curl_ossl_init(void) #define CONF_MFLAGS_DEFAULT_SECTION 0x0 #endif +#ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG CONF_modules_load_file(NULL, NULL, CONF_MFLAGS_DEFAULT_SECTION| CONF_MFLAGS_IGNORE_MISSING_FILE); +#endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ !defined(LIBRESSL_VERSION_NUMBER) @@ -1260,7 +1262,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) ssize_t nread; int buffsize; int err; - int done = 0; + bool done = FALSE; /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in @@ -1288,7 +1290,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) case SSL_ERROR_ZERO_RETURN: /* no more data */ /* This is the expected response. There was no data but only the close notify alert */ - done = 1; + done = TRUE; break; case SSL_ERROR_WANT_READ: /* there's data pending, re-invoke SSL_read() */ @@ -1297,7 +1299,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) case SSL_ERROR_WANT_WRITE: /* SSL wants a write. Really odd. Let's bail out. */ infof(data, "SSL_ERROR_WANT_WRITE\n"); - done = 1; + done = TRUE; break; default: /* openssl/ssl.h says "look at error stack/return value/errno" */ @@ -1307,20 +1309,20 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) ossl_strerror(sslerror, buf, sizeof(buf)) : SSL_ERROR_to_str(err)), SOCKERRNO); - done = 1; + done = TRUE; break; } } else if(0 == what) { /* timeout */ failf(data, "SSL shutdown timeout"); - done = 1; + done = TRUE; } else { /* anything that gets here is fatally bad */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); retval = -1; - done = 1; + done = TRUE; } } /* while()-loop for the select() */ @@ -1416,6 +1418,10 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, } #else { +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)dispname; + (void)data; +#endif if(Curl_cert_hostcheck(match_pattern, hostname)) { infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", dispname, match_pattern); @@ -2080,6 +2086,7 @@ select_next_proto_cb(SSL *ssl, } #endif /* HAS_NPN */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS static const char * get_ssl_version_txt(SSL *ssl) { @@ -2106,6 +2113,7 @@ get_ssl_version_txt(SSL *ssl) } return "unknown"; } +#endif static CURLcode set_ssl_version_min_max(long *ctx_options, struct connectdata *conn, @@ -2171,7 +2179,6 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn, #endif break; case CURL_SSLVERSION_MAX_TLSv1_3: - case CURL_SSLVERSION_MAX_DEFAULT: #ifdef TLS1_3_VERSION break; #else @@ -2459,7 +2466,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) char *ciphers13 = SSL_CONN_CONFIG(cipher_list13); if(ciphers13) { if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) { - failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers); + failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); return CURLE_SSL_CIPHER; } infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13); @@ -2467,6 +2474,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) } #endif +#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH + /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ + SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1); +#endif + #ifdef USE_TLS_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) { char * const ssl_username = SSL_SET_OPTION(username); @@ -2521,7 +2533,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) } #ifdef CURL_CA_FALLBACK else if(verifypeer) { - /* verfying the peer without any CA certificates won't + /* verifying the peer without any CA certificates won't work so use openssl's built in default as fallback */ SSL_CTX_set_default_verify_paths(BACKEND->ctx); } @@ -3187,7 +3199,7 @@ static CURLcode servercert(struct connectdata *conn, { CURLcode result = CURLE_OK; int rc; - long lerr, len; + long lerr; struct Curl_easy *data = conn->data; X509 *issuer; BIO *fp = NULL; @@ -3210,7 +3222,7 @@ static CURLcode servercert(struct connectdata *conn, ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)) ); BIO_free(mem); - return 0; + return CURLE_OUT_OF_MEMORY; } BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle); @@ -3230,15 +3242,20 @@ static CURLcode servercert(struct connectdata *conn, buffer, sizeof(buffer)); infof(data, " subject: %s\n", rc?"[NONE]":buffer); - ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert)); - len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " start date: %.*s\n", len, ptr); - (void)BIO_reset(mem); +#ifndef CURL_DISABLE_VERBOSE_STRINGS + { + long len; + ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert)); + len = BIO_get_mem_data(mem, (char **) &ptr); + infof(data, " start date: %.*s\n", len, ptr); + (void)BIO_reset(mem); - ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert)); - len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " expire date: %.*s\n", len, ptr); - (void)BIO_reset(mem); + ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert)); + len = BIO_get_mem_data(mem, (char **) &ptr); + infof(data, " expire date: %.*s\n", len, ptr); + (void)BIO_reset(mem); + } +#endif BIO_free(mem); @@ -3257,7 +3274,7 @@ static CURLcode servercert(struct connectdata *conn, if(rc) { if(strict) failf(data, "SSL: couldn't get X509-issuer name!"); - result = CURLE_SSL_CONNECT_ERROR; + result = CURLE_PEER_FAILED_VERIFICATION; } else { infof(data, " issuer: %s\n", buffer); diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c index 604cb4c..27af0cc 100644 --- a/lib/vtls/polarssl.c +++ b/lib/vtls/polarssl.c @@ -185,14 +185,11 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: ssl_version = CURL_SSLVERSION_TLSv1_0; - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; } switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version << 16; - break; case CURL_SSLVERSION_MAX_DEFAULT: ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 8f6c301..e442692 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -180,8 +180,6 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: - ssl_version_max = ssl_version << 16; - break; case CURL_SSLVERSION_MAX_DEFAULT: ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; break; @@ -363,7 +361,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, sep = _tcschr(path, TEXT('\\')); if(sep == NULL) - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; store_name_len = sep - path; @@ -387,19 +385,19 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; else - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; *store_path = sep + 1; sep = _tcschr(*store_path, TEXT('\\')); if(sep == NULL) - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; *sep = 0; *thumbprint = sep + 1; if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; return CURLE_OK; } @@ -612,7 +610,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) "last error is %x", cert_store_name, cert_store_path, GetLastError()); Curl_unicodefree(cert_path); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; } cert_thumbprint.pbData = cert_thumbprint_data; @@ -623,7 +621,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) cert_thumbprint_data, &cert_thumbprint.cbData, NULL, NULL)) { Curl_unicodefree(cert_path); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_SSL_CERTPROBLEM; } client_certs[0] = CertFindCertificateInStore( @@ -636,6 +634,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) schannel_cred.cCreds = 1; schannel_cred.paCred = client_certs; } + else { + /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ + return CURLE_SSL_CERTPROBLEM; + } CertCloseStore(cert_store, 0); } @@ -672,14 +674,20 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) CertFreeCertificateContext(client_certs[0]); if(sspi_status != SEC_E_OK) { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + failf(data, "schannel: AcquireCredentialsHandle failed: %s", + Curl_sspi_strerror(conn, sspi_status)); Curl_safefree(BACKEND->cred); - return CURLE_SSL_CONNECT_ERROR; + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + return CURLE_OUT_OF_MEMORY; + case SEC_E_NO_CREDENTIALS: + case SEC_E_SECPKG_NOT_FOUND: + case SEC_E_NOT_OWNER: + case SEC_E_UNKNOWN_CREDENTIALS: + case SEC_E_INTERNAL_ERROR: + default: + return CURLE_SSL_CONNECT_ERROR; + } } } @@ -782,14 +790,32 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_unicodefree(host_name); if(sspi_status != SEC_I_CONTINUE_NEEDED) { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); Curl_safefree(BACKEND->ctxt); - return CURLE_SSL_CONNECT_ERROR; + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_SSL_CONNECT_ERROR; + } } infof(data, "schannel: sending initial handshake data: " @@ -1004,14 +1030,31 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } } else { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - return sspi_status == SEC_E_UNTRUSTED_ROOT ? - CURLE_SSL_CACERT : CURLE_SSL_CONNECT_ERROR; + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(conn, sspi_status)); + return CURLE_SSL_CONNECT_ERROR; + } } /* check if there was additional remaining encrypted data */ @@ -1192,7 +1235,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { failf(data, "schannel: failed to retrieve remote cert context"); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_PEER_FAILED_VERIFICATION; } result = Curl_ssl_init_certinfo(data, 1); diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h index 51417af..e491bd4 100644 --- a/lib/vtls/schannel.h +++ b/lib/vtls/schannel.h @@ -41,7 +41,7 @@ * typedef struct X509_name_st X509_NAME; * etc. * - * this wil cause all kinds of C-preprocessing paste errors in + * this will cause all kinds of C-preprocessing paste errors in * BoringSSL's : So just undefine those defines here * (and only here). */ diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 5a7092a..2516f56 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -135,7 +135,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, failf(data, "schannel: CA file exceeds max size of %u bytes", MAX_CAFILE_SIZE); - result = CURLE_OUT_OF_MEMORY; + result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -244,7 +244,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, CertFreeCertificateContext(cert_context); if(!add_cert_result) { failf(data, - "schannel: failed to add certificate from CA file '%s'" + "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", ca_file, Curl_strerror(conn, GetLastError())); result = CURLE_SSL_CACERT_BADFILE; @@ -319,6 +319,10 @@ static CURLcode verify_host(struct Curl_easy *data, * embedded null bytes. This appears to be undocumented behavior. */ cert_hostname_buff = (LPTSTR)malloc(len * sizeof(TCHAR)); + if(!cert_hostname_buff) { + result = CURLE_OUT_OF_MEMORY; + goto cleanup; + } actual_len = CertGetNameString(pCertContextServer, CERT_NAME_DNS_TYPE, name_flags, diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index b61c640..6af39fe 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -1190,6 +1190,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_polarssl; #elif defined(USE_SCHANNEL) &Curl_ssl_schannel; +#elif defined(USE_MESALINK) + &Curl_ssl_mesalink; #else #error "Missing struct Curl_ssl for selected SSL backend" #endif @@ -1225,6 +1227,9 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_SCHANNEL) &Curl_ssl_schannel, #endif +#if defined(USE_MESALINK) + &Curl_ssl_mesalink, +#endif NULL }; diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index 40f9d74..5cd1160 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -108,6 +108,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "schannel.h" /* Schannel SSPI version */ #include "darwinssl.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ +#include "mesalink.h" /* MesaLink versions */ #ifndef MAX_PINNED_PUBKEY_SIZE #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ diff --git a/lib/x509asn1.c b/lib/x509asn1.c index 72a0b4a..a576fc7 100644 --- a/lib/x509asn1.c +++ b/lib/x509asn1.c @@ -103,6 +103,9 @@ static const curl_OID OIDtable[] = { * Please note there is no pretention here to rewrite a full SSL library. */ +static const char *getASN1Element(curl_asn1Element *elem, + const char *beg, const char *end) + WARN_UNUSED_RESULT; static const char *getASN1Element(curl_asn1Element *elem, const char *beg, const char *end) @@ -223,7 +226,7 @@ static const char *bit2str(const char *beg, const char *end) static const char *int2str(const char *beg, const char *end) { - long val = 0; + unsigned long val = 0; size_t n = end - beg; /* Convert an ASN.1 integer value into its string representation. @@ -243,7 +246,7 @@ static const char *int2str(const char *beg, const char *end) do val = (val << 8) | *(const unsigned char *) beg++; while(beg < end); - return curl_maprintf("%s%lx", (val < 0 || val >= 10)? "0x": "", val); + return curl_maprintf("%s%lx", val >= 10? "0x": "", val); } static ssize_t @@ -602,10 +605,17 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) for(p1 = dn->beg; p1 < dn->end;) { p1 = getASN1Element(&rdn, p1, dn->end); + if(!p1) + return -1; for(p2 = rdn.beg; p2 < rdn.end;) { p2 = getASN1Element(&atv, p2, rdn.end); + if(!p2) + return -1; p3 = getASN1Element(&oid, atv.beg, atv.end); - getASN1Element(&value, p3, atv.end); + if(!p3) + return -1; + if(!getASN1Element(&value, p3, atv.end)) + return -1; str = ASN1tostr(&oid, 0); if(!str) return -1; @@ -697,10 +707,15 @@ int Curl_parseX509(curl_X509certificate *cert, /* Get tbsCertificate. */ beg = getASN1Element(&tbsCertificate, beg, end); + if(!beg) + return -1; /* Skip the signatureAlgorithm. */ beg = getASN1Element(&cert->signatureAlgorithm, beg, end); + if(!beg) + return -1; /* Get the signatureValue. */ - getASN1Element(&cert->signature, beg, end); + if(!getASN1Element(&cert->signature, beg, end)) + return -1; /* Parse TBSCertificate. */ beg = tbsCertificate.beg; @@ -710,28 +725,47 @@ int Curl_parseX509(curl_X509certificate *cert, cert->version.beg = &defaultVersion; cert->version.end = &defaultVersion + sizeof(defaultVersion); beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; if(elem.tag == 0) { - getASN1Element(&cert->version, elem.beg, elem.end); + if(!getASN1Element(&cert->version, elem.beg, elem.end)) + return -1; beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; } cert->serialNumber = elem; /* Get signature algorithm. */ beg = getASN1Element(&cert->signatureAlgorithm, beg, end); /* Get issuer. */ beg = getASN1Element(&cert->issuer, beg, end); + if(!beg) + return -1; /* Get notBefore and notAfter. */ beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end); - getASN1Element(&cert->notAfter, ccp, elem.end); + if(!ccp) + return -1; + if(!getASN1Element(&cert->notAfter, ccp, elem.end)) + return -1; /* Get subject. */ beg = getASN1Element(&cert->subject, beg, end); + if(!beg) + return -1; /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */ beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end); + if(!beg) + return -1; ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm, - cert->subjectPublicKeyInfo.beg, - cert->subjectPublicKeyInfo.end); - getASN1Element(&cert->subjectPublicKey, ccp, - cert->subjectPublicKeyInfo.end); + cert->subjectPublicKeyInfo.beg, + cert->subjectPublicKeyInfo.end); + if(!ccp) + return -1; + if(!getASN1Element(&cert->subjectPublicKey, ccp, + cert->subjectPublicKeyInfo.end)) + return -1; /* Get optional issuerUiqueID, subjectUniqueID and extensions. */ cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; cert->extensions.tag = elem.tag = 0; @@ -740,20 +774,30 @@ int Curl_parseX509(curl_X509certificate *cert, cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; cert->extensions.header = NULL; cert->extensions.beg = cert->extensions.end = ""; - if(beg < end) + if(beg < end) { beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } if(elem.tag == 1) { cert->issuerUniqueID = elem; - if(beg < end) + if(beg < end) { beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } } if(elem.tag == 2) { cert->subjectUniqueID = elem; - if(beg < end) + if(beg < end) { beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } } if(elem.tag == 3) - getASN1Element(&cert->extensions, elem.beg, elem.end); + if(!getASN1Element(&cert->extensions, elem.beg, elem.end)) + return -1; return 0; } @@ -782,11 +826,14 @@ static const char *dumpAlgo(curl_asn1Element *param, /* Get algorithm parameters and return algorithm name. */ beg = getASN1Element(&oid, beg, end); + if(!beg) + return NULL; param->header = NULL; param->tag = 0; param->beg = param->end = end; if(beg < end) - getASN1Element(param, beg, end); + if(!getASN1Element(param, beg, end)) + return NULL; return OID2str(oid.beg, oid.end, TRUE); } @@ -821,10 +868,14 @@ static void do_pubkey(struct Curl_easy *data, int certnum, /* Generate all information records for the public key. */ /* Get the public key (single element). */ - getASN1Element(&pk, pubkey->beg + 1, pubkey->end); + if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end)) + return; if(strcasecompare(algo, "rsaEncryption")) { p = getASN1Element(&elem, pk.beg, pk.end); + if(!p) + return; + /* Compute key length. */ for(q = elem.beg; !*q && q < elem.end; q++) ; @@ -845,30 +896,34 @@ static void do_pubkey(struct Curl_easy *data, int certnum, } /* Generate coefficients. */ do_pubkey_field(data, certnum, "rsa(n)", &elem); - getASN1Element(&elem, p, pk.end); + if(!getASN1Element(&elem, p, pk.end)) + return; do_pubkey_field(data, certnum, "rsa(e)", &elem); } else if(strcasecompare(algo, "dsa")) { p = getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dsa(p)", &elem); - p = getASN1Element(&elem, p, param->end); - do_pubkey_field(data, certnum, "dsa(q)", &elem); - getASN1Element(&elem, p, param->end); - do_pubkey_field(data, certnum, "dsa(g)", &elem); - do_pubkey_field(data, certnum, "dsa(pub_key)", &pk); + if(p) { + do_pubkey_field(data, certnum, "dsa(p)", &elem); + p = getASN1Element(&elem, p, param->end); + if(p) { + do_pubkey_field(data, certnum, "dsa(q)", &elem); + if(getASN1Element(&elem, p, param->end)) { + do_pubkey_field(data, certnum, "dsa(g)", &elem); + do_pubkey_field(data, certnum, "dsa(pub_key)", &pk); + } + } + } } else if(strcasecompare(algo, "dhpublicnumber")) { p = getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dh(p)", &elem); - getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dh(g)", &elem); - do_pubkey_field(data, certnum, "dh(pub_key)", &pk); - } -#if 0 /* Patent-encumbered. */ - else if(strcasecompare(algo, "ecPublicKey")) { - /* Left TODO. */ + if(p) { + do_pubkey_field(data, certnum, "dh(p)", &elem); + if(getASN1Element(&elem, param->beg, param->end)) { + do_pubkey_field(data, certnum, "dh(g)", &elem); + do_pubkey_field(data, certnum, "dh(pub_key)", &pk); + } + } } -#endif } CURLcode Curl_extract_certinfo(struct connectdata *conn, @@ -896,7 +951,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn, /* Extract the certificate ASN.1 elements. */ if(Curl_parseX509(&cert, beg, end)) - return CURLE_OUT_OF_MEMORY; + return CURLE_PEER_FAILED_VERIFICATION; /* Subject. */ ccp = DNtostr(&cert.subject); @@ -1107,18 +1162,29 @@ CURLcode Curl_verifyhost(struct connectdata *conn, /* Process extensions. */ for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) { p = getASN1Element(&ext, p, cert.extensions.end); + if(!p) + return CURLE_PEER_FAILED_VERIFICATION; + /* Check if extension is a subjectAlternativeName. */ ext.beg = checkOID(ext.beg, ext.end, sanOID); if(ext.beg) { ext.beg = getASN1Element(&elem, ext.beg, ext.end); + if(!ext.beg) + return CURLE_PEER_FAILED_VERIFICATION; /* Skip critical if present. */ - if(elem.tag == CURL_ASN1_BOOLEAN) + if(elem.tag == CURL_ASN1_BOOLEAN) { ext.beg = getASN1Element(&elem, ext.beg, ext.end); + if(!ext.beg) + return CURLE_PEER_FAILED_VERIFICATION; + } /* Parse the octet string contents: is a single sequence. */ - getASN1Element(&elem, elem.beg, elem.end); + if(!getASN1Element(&elem, elem.beg, elem.end)) + return CURLE_PEER_FAILED_VERIFICATION; /* Check all GeneralNames. */ for(q = elem.beg; matched != 1 && q < elem.end;) { q = getASN1Element(&name, q, elem.end); + if(!q) + break; switch(name.tag) { case 2: /* DNS name. */ len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING, @@ -1131,8 +1197,8 @@ CURLcode Curl_verifyhost(struct connectdata *conn, break; case 7: /* IP address. */ - matched = (size_t) (name.end - q) == addrlen && - !memcmp(&addr, q, addrlen); + matched = (size_t) (name.end - name.beg) == addrlen && + !memcmp(&addr, name.beg, addrlen); break; } } @@ -1159,8 +1225,12 @@ CURLcode Curl_verifyhost(struct connectdata *conn, distinguished one to get the most significant one. */ while(q < cert.subject.end) { q = getASN1Element(&dn, q, cert.subject.end); + if(!q) + break; for(p = dn.beg; p < dn.end;) { p = getASN1Element(&elem, p, dn.end); + if(!p) + return CURLE_PEER_FAILED_VERIFICATION; /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */ elem.beg = checkOID(elem.beg, elem.end, cnOID); if(elem.beg) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9c6574795c404417939c889d8cb45095c4175474 commit 9c6574795c404417939c889d8cb45095c4175474 Author: Brad King AuthorDate: Wed Oct 31 09:40:47 2018 -0400 Commit: Brad King CommitDate: Wed Oct 31 09:40:47 2018 -0400 curl: Update script to get curl 7.62.0 diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash index 3d31e38..fb46052 100755 --- a/Utilities/Scripts/update-curl.bash +++ b/Utilities/Scripts/update-curl.bash @@ -8,7 +8,7 @@ readonly name="curl" readonly ownership="Curl Upstream " readonly subtree="Utilities/cmcurl" readonly repo="https://github.com/curl/curl.git" -readonly tag="curl-7_61_1" +readonly tag="curl-7_62_0" readonly shortlog=false readonly paths=" CMake/* ----------------------------------------------------------------------- Summary of changes: Source/cmAddCustomCommandCommand.cxx | 6 - Source/cmAddCustomTargetCommand.cxx | 7 - Source/cmCustomCommandGenerator.cxx | 6 + Tests/CustomCommandWorkingDirectory/CMakeLists.txt | 4 +- Utilities/.gitattributes | 1 + Utilities/Scripts/update-curl.bash | 2 +- Utilities/cmcurl/CMake/CMakeConfigurableFile.in | 1 - Utilities/cmcurl/CMake/CurlTests.c | 16 + Utilities/cmcurl/CMake/curl-config.cmake.in | 66 +- Utilities/cmcurl/CMakeLists.txt | 93 +- Utilities/cmcurl/curltest.c | 184 +-- Utilities/cmcurl/include/curl/curl.h | 25 +- Utilities/cmcurl/include/curl/curlver.h | 8 +- Utilities/cmcurl/include/curl/easy.h | 10 + Utilities/cmcurl/include/curl/system.h | 2 +- Utilities/cmcurl/include/curl/typecheck-gcc.h | 6 +- Utilities/cmcurl/include/curl/urlapi.h | 120 ++ Utilities/cmcurl/lib/CMakeLists.txt | 17 +- Utilities/cmcurl/lib/Makefile.inc | 9 +- Utilities/cmcurl/lib/amigaos.h | 1 - Utilities/cmcurl/lib/arpa_telnet.h | 6 +- Utilities/cmcurl/lib/cookie.c | 26 +- Utilities/cmcurl/lib/curl_config.h.cmake | 3 + Utilities/cmcurl/lib/curl_ldap.h | 1 - Utilities/cmcurl/lib/curl_ntlm_wb.c | 18 +- Utilities/cmcurl/lib/curl_path.c | 4 +- Utilities/cmcurl/lib/curl_path.h | 2 +- Utilities/cmcurl/lib/curl_rtmp.c | 4 +- Utilities/cmcurl/lib/curl_setup.h | 5 +- Utilities/cmcurl/lib/curl_setup_once.h | 1 - Utilities/cmcurl/lib/curl_sspi.c | 7 +- Utilities/cmcurl/lib/curl_threads.c | 14 +- Utilities/cmcurl/lib/curl_threads.h | 3 +- Utilities/cmcurl/lib/curlx.h | 1 - Utilities/cmcurl/lib/dict.c | 2 +- Utilities/cmcurl/lib/doh.c | 920 ++++++++++++++ Utilities/cmcurl/lib/doh.h | 105 ++ Utilities/cmcurl/lib/dotdot.c | 2 + Utilities/cmcurl/lib/dotdot.h | 2 +- Utilities/cmcurl/lib/easy.c | 23 +- Utilities/cmcurl/lib/easyif.h | 1 - Utilities/cmcurl/lib/escape.c | 20 +- Utilities/cmcurl/lib/escape.h | 4 +- Utilities/cmcurl/lib/file.c | 33 +- Utilities/cmcurl/lib/file.h | 1 - Utilities/cmcurl/lib/ftp.c | 46 +- Utilities/cmcurl/lib/ftp.h | 2 + Utilities/cmcurl/lib/getinfo.c | 1 - Utilities/cmcurl/lib/gopher.c | 2 +- Utilities/cmcurl/lib/hostasyn.c | 25 - Utilities/cmcurl/lib/hostcheck.h | 1 - Utilities/cmcurl/lib/hostip.c | 78 +- Utilities/cmcurl/lib/hostip.h | 13 +- Utilities/cmcurl/lib/http.c | 245 ++-- Utilities/cmcurl/lib/http.h | 19 +- Utilities/cmcurl/lib/http2.c | 135 +- Utilities/cmcurl/lib/http2.h | 1 - Utilities/cmcurl/lib/http_chunks.h | 1 - Utilities/cmcurl/lib/http_proxy.c | 14 +- Utilities/cmcurl/lib/imap.c | 84 +- Utilities/cmcurl/lib/imap.h | 1 + Utilities/cmcurl/lib/inet_ntop.h | 1 - Utilities/cmcurl/lib/inet_pton.h | 1 - Utilities/cmcurl/lib/krb5.c | 6 +- Utilities/cmcurl/lib/ldap.c | 18 +- Utilities/cmcurl/lib/llist.h | 1 - Utilities/cmcurl/lib/md4.c | 2 +- Utilities/cmcurl/lib/md5.c | 2 +- Utilities/cmcurl/lib/multi.c | 77 +- Utilities/cmcurl/lib/netrc.c | 48 +- Utilities/cmcurl/lib/nonblock.c | 3 +- Utilities/cmcurl/lib/nonblock.h | 1 - Utilities/cmcurl/lib/nwlib.c | 7 +- Utilities/cmcurl/lib/parsedate.h | 1 - Utilities/cmcurl/lib/pop3.c | 5 +- Utilities/cmcurl/lib/progress.h | 1 - Utilities/cmcurl/lib/rand.c | 4 +- Utilities/cmcurl/lib/rtsp.c | 27 +- Utilities/cmcurl/lib/rtsp.h | 1 - Utilities/cmcurl/lib/security.c | 6 +- Utilities/cmcurl/lib/select.h | 1 - Utilities/cmcurl/lib/sendf.h | 2 +- Utilities/cmcurl/lib/setopt.c | 31 + Utilities/cmcurl/lib/slist.c | 1 - Utilities/cmcurl/lib/slist.h | 1 - Utilities/cmcurl/lib/smb.c | 5 +- Utilities/cmcurl/lib/smtp.c | 9 +- Utilities/cmcurl/lib/sockaddr.h | 1 - Utilities/cmcurl/lib/socks.c | 3 +- Utilities/cmcurl/lib/socks.h | 1 - Utilities/cmcurl/lib/splay.c | 1 - Utilities/cmcurl/lib/ssh.c | 2 +- Utilities/cmcurl/lib/strdup.c | 2 +- Utilities/cmcurl/lib/strerror.c | 9 +- Utilities/cmcurl/lib/telnet.h | 1 - Utilities/cmcurl/lib/tftp.c | 4 +- Utilities/cmcurl/lib/tftp.h | 1 - Utilities/cmcurl/lib/timeval.c | 23 +- Utilities/cmcurl/lib/transfer.c | 369 +----- Utilities/cmcurl/lib/transfer.h | 1 - Utilities/cmcurl/lib/url.c | 1096 +++++----------- Utilities/cmcurl/lib/url.h | 25 +- .../cmcurl/lib/{curl_range.h => urlapi-int.h} | 17 +- Utilities/cmcurl/lib/urlapi.c | 1340 ++++++++++++++++++++ Utilities/cmcurl/lib/urldata.h | 83 +- Utilities/cmcurl/lib/vauth/cleartext.c | 4 +- Utilities/cmcurl/lib/vauth/cram.c | 2 +- Utilities/cmcurl/lib/vauth/digest.c | 10 +- Utilities/cmcurl/lib/vauth/digest_sspi.c | 4 +- Utilities/cmcurl/lib/vauth/krb5_gssapi.c | 2 +- Utilities/cmcurl/lib/vauth/krb5_sspi.c | 2 +- Utilities/cmcurl/lib/vauth/ntlm.c | 4 +- Utilities/cmcurl/lib/vauth/ntlm_sspi.c | 4 +- Utilities/cmcurl/lib/vauth/spnego_gssapi.c | 2 +- Utilities/cmcurl/lib/vauth/spnego_sspi.c | 4 +- Utilities/cmcurl/lib/vtls/axtls.h | 1 - Utilities/cmcurl/lib/vtls/darwinssl.c | 429 ++++--- Utilities/cmcurl/lib/vtls/gskit.c | 5 +- Utilities/cmcurl/lib/vtls/gtls.c | 91 +- Utilities/cmcurl/lib/vtls/mbedtls.c | 3 - Utilities/cmcurl/lib/vtls/mesalink.c | 627 +++++++++ Utilities/cmcurl/lib/vtls/{cyassl.h => mesalink.h} | 13 +- Utilities/cmcurl/lib/vtls/nss.c | 17 +- Utilities/cmcurl/lib/vtls/openssl.c | 75 +- Utilities/cmcurl/lib/vtls/polarssl.c | 3 - Utilities/cmcurl/lib/vtls/schannel.c | 105 +- Utilities/cmcurl/lib/vtls/schannel.h | 2 +- Utilities/cmcurl/lib/vtls/schannel_verify.c | 8 +- Utilities/cmcurl/lib/vtls/vtls.c | 5 + Utilities/cmcurl/lib/vtls/vtls.h | 1 + Utilities/cmcurl/lib/x509asn1.c | 144 ++- 131 files changed, 5060 insertions(+), 2208 deletions(-) create mode 100644 Utilities/cmcurl/include/curl/urlapi.h create mode 100644 Utilities/cmcurl/lib/doh.c create mode 100644 Utilities/cmcurl/lib/doh.h copy Utilities/cmcurl/lib/{curl_range.h => urlapi-int.h} (69%) create mode 100644 Utilities/cmcurl/lib/urlapi.c create mode 100644 Utilities/cmcurl/lib/vtls/mesalink.c copy Utilities/cmcurl/lib/vtls/{cyassl.h => mesalink.h} (80%) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 5 07:55:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 5 Nov 2018 07:55:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-334-ge5d298b Message-ID: <20181105125505.9AC2C126645@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via e5d298b8fdb12283291f37048ae8f68a60a6becb (commit) via 066db7576dda43c6a716b4201c0399a1e3ae9c2b (commit) via 36280e6157e883fb5257f211d24582b5e7ff4244 (commit) via 4cd059480a40cc4a2c7e326f8bb1fe11fe46ba0c (commit) via 85aceda0262bff58a0126b2d4e75756e0507fe3c (commit) from b83420e45d963e2decd94336b97c127c75eed990 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e5d298b8fdb12283291f37048ae8f68a60a6becb commit e5d298b8fdb12283291f37048ae8f68a60a6becb Merge: 066db75 85aceda Author: Brad King AuthorDate: Mon Nov 5 12:50:13 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 5 07:50:20 2018 -0500 Merge topic 'lwyu-hides-link-error' 85aceda026 cmNinjaNormalTargetGenerator: don't use `|| true` for link-what-you-use Acked-by: Kitware Robot Merge-request: !2546 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=066db7576dda43c6a716b4201c0399a1e3ae9c2b commit 066db7576dda43c6a716b4201c0399a1e3ae9c2b Merge: b83420e 36280e6 Author: Brad King AuthorDate: Mon Nov 5 07:49:06 2018 -0500 Commit: Brad King CommitDate: Mon Nov 5 07:49:06 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=85aceda0262bff58a0126b2d4e75756e0507fe3c commit 85aceda0262bff58a0126b2d4e75756e0507fe3c Author: Ben Boeckel AuthorDate: Mon Oct 29 15:49:44 2018 -0400 Commit: Ben Boeckel CommitDate: Fri Nov 2 10:25:56 2018 -0400 cmNinjaNormalTargetGenerator: don't use `|| true` for link-what-you-use With the `|| true`, a linker error before running link-what-you-use would also use the `|| true` fragment and unconditionally succeed. Just skip the addition since `--lwyu=` ignores the return value anyways. Fixes #18524 diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 6436969..1386706 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -506,7 +506,6 @@ std::vector cmNinjaNormalTargetGenerator::ComputeLinkCmd() gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact, /*realname=*/true)); cmakeCommand += targetOutputReal; - cmakeCommand += " || true"; linkCmds.push_back(std::move(cmakeCommand)); } return linkCmds; ----------------------------------------------------------------------- Summary of changes: Source/cmNinjaNormalTargetGenerator.cxx | 1 - 1 file changed, 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 5 07:55:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 5 Nov 2018 07:55:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-38-g36280e6 Message-ID: <20181105125506.B1668126646@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 36280e6157e883fb5257f211d24582b5e7ff4244 (commit) via 4cd059480a40cc4a2c7e326f8bb1fe11fe46ba0c (commit) via 98d59417b0c6ac3ea85e315133337030dad93496 (commit) via c1ad5118deb0eb52c2130e0fb3363f44c25bf42e (commit) via 03bf934fbe93ef04d6c62c64912d2f212db997b7 (commit) via 2b3c1bb9b014cf34ab882b8ab9569846c274cc8a (commit) via 636bcefeab3b386e65efe03b199b9b2614d8a78d (commit) via 9835e9075037db3d23ade0ef865c562b08cf6023 (commit) via 9c6574795c404417939c889d8cb45095c4175474 (commit) from 03d00d63dfc2ee5ed3775eccdbd012245acba6ce (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/cmAddCustomCommandCommand.cxx | 6 - Source/cmAddCustomTargetCommand.cxx | 7 - Source/cmCustomCommandGenerator.cxx | 6 + Tests/CustomCommandWorkingDirectory/CMakeLists.txt | 4 +- Utilities/.gitattributes | 1 + Utilities/Scripts/update-curl.bash | 2 +- Utilities/cmcurl/CMake/CMakeConfigurableFile.in | 1 - Utilities/cmcurl/CMake/CurlTests.c | 16 + Utilities/cmcurl/CMake/curl-config.cmake.in | 66 +- Utilities/cmcurl/CMakeLists.txt | 93 +- Utilities/cmcurl/curltest.c | 184 +-- Utilities/cmcurl/include/curl/curl.h | 25 +- Utilities/cmcurl/include/curl/curlver.h | 8 +- Utilities/cmcurl/include/curl/easy.h | 10 + Utilities/cmcurl/include/curl/system.h | 2 +- Utilities/cmcurl/include/curl/typecheck-gcc.h | 6 +- Utilities/cmcurl/include/curl/urlapi.h | 120 ++ Utilities/cmcurl/lib/CMakeLists.txt | 17 +- Utilities/cmcurl/lib/Makefile.inc | 9 +- Utilities/cmcurl/lib/amigaos.h | 1 - Utilities/cmcurl/lib/arpa_telnet.h | 6 +- Utilities/cmcurl/lib/cookie.c | 26 +- Utilities/cmcurl/lib/curl_config.h.cmake | 3 + Utilities/cmcurl/lib/curl_ldap.h | 1 - Utilities/cmcurl/lib/curl_ntlm_wb.c | 18 +- Utilities/cmcurl/lib/curl_path.c | 4 +- Utilities/cmcurl/lib/curl_path.h | 2 +- Utilities/cmcurl/lib/curl_rtmp.c | 4 +- Utilities/cmcurl/lib/curl_setup.h | 5 +- Utilities/cmcurl/lib/curl_setup_once.h | 1 - Utilities/cmcurl/lib/curl_sspi.c | 7 +- Utilities/cmcurl/lib/curl_threads.c | 14 +- Utilities/cmcurl/lib/curl_threads.h | 3 +- Utilities/cmcurl/lib/curlx.h | 1 - Utilities/cmcurl/lib/dict.c | 2 +- Utilities/cmcurl/lib/doh.c | 920 ++++++++++++++ Utilities/cmcurl/lib/doh.h | 105 ++ Utilities/cmcurl/lib/dotdot.c | 2 + Utilities/cmcurl/lib/dotdot.h | 2 +- Utilities/cmcurl/lib/easy.c | 23 +- Utilities/cmcurl/lib/easyif.h | 1 - Utilities/cmcurl/lib/escape.c | 20 +- Utilities/cmcurl/lib/escape.h | 4 +- Utilities/cmcurl/lib/file.c | 33 +- Utilities/cmcurl/lib/file.h | 1 - Utilities/cmcurl/lib/ftp.c | 46 +- Utilities/cmcurl/lib/ftp.h | 2 + Utilities/cmcurl/lib/getinfo.c | 1 - Utilities/cmcurl/lib/gopher.c | 2 +- Utilities/cmcurl/lib/hostasyn.c | 25 - Utilities/cmcurl/lib/hostcheck.h | 1 - Utilities/cmcurl/lib/hostip.c | 78 +- Utilities/cmcurl/lib/hostip.h | 13 +- Utilities/cmcurl/lib/http.c | 245 ++-- Utilities/cmcurl/lib/http.h | 19 +- Utilities/cmcurl/lib/http2.c | 135 +- Utilities/cmcurl/lib/http2.h | 1 - Utilities/cmcurl/lib/http_chunks.h | 1 - Utilities/cmcurl/lib/http_proxy.c | 14 +- Utilities/cmcurl/lib/imap.c | 84 +- Utilities/cmcurl/lib/imap.h | 1 + Utilities/cmcurl/lib/inet_ntop.h | 1 - Utilities/cmcurl/lib/inet_pton.h | 1 - Utilities/cmcurl/lib/krb5.c | 6 +- Utilities/cmcurl/lib/ldap.c | 18 +- Utilities/cmcurl/lib/llist.h | 1 - Utilities/cmcurl/lib/md4.c | 2 +- Utilities/cmcurl/lib/md5.c | 2 +- Utilities/cmcurl/lib/multi.c | 77 +- Utilities/cmcurl/lib/netrc.c | 48 +- Utilities/cmcurl/lib/nonblock.c | 3 +- Utilities/cmcurl/lib/nonblock.h | 1 - Utilities/cmcurl/lib/nwlib.c | 7 +- Utilities/cmcurl/lib/parsedate.h | 1 - Utilities/cmcurl/lib/pop3.c | 5 +- Utilities/cmcurl/lib/progress.h | 1 - Utilities/cmcurl/lib/rand.c | 4 +- Utilities/cmcurl/lib/rtsp.c | 27 +- Utilities/cmcurl/lib/rtsp.h | 1 - Utilities/cmcurl/lib/security.c | 6 +- Utilities/cmcurl/lib/select.h | 1 - Utilities/cmcurl/lib/sendf.h | 2 +- Utilities/cmcurl/lib/setopt.c | 31 + Utilities/cmcurl/lib/slist.c | 1 - Utilities/cmcurl/lib/slist.h | 1 - Utilities/cmcurl/lib/smb.c | 5 +- Utilities/cmcurl/lib/smtp.c | 9 +- Utilities/cmcurl/lib/sockaddr.h | 1 - Utilities/cmcurl/lib/socks.c | 3 +- Utilities/cmcurl/lib/socks.h | 1 - Utilities/cmcurl/lib/splay.c | 1 - Utilities/cmcurl/lib/ssh.c | 2 +- Utilities/cmcurl/lib/strdup.c | 2 +- Utilities/cmcurl/lib/strerror.c | 9 +- Utilities/cmcurl/lib/telnet.h | 1 - Utilities/cmcurl/lib/tftp.c | 4 +- Utilities/cmcurl/lib/tftp.h | 1 - Utilities/cmcurl/lib/timeval.c | 23 +- Utilities/cmcurl/lib/transfer.c | 369 +----- Utilities/cmcurl/lib/transfer.h | 1 - Utilities/cmcurl/lib/url.c | 1096 +++++----------- Utilities/cmcurl/lib/url.h | 25 +- .../cmcurl/lib/{curl_range.h => urlapi-int.h} | 17 +- Utilities/cmcurl/lib/urlapi.c | 1340 ++++++++++++++++++++ Utilities/cmcurl/lib/urldata.h | 83 +- Utilities/cmcurl/lib/vauth/cleartext.c | 4 +- Utilities/cmcurl/lib/vauth/cram.c | 2 +- Utilities/cmcurl/lib/vauth/digest.c | 10 +- Utilities/cmcurl/lib/vauth/digest_sspi.c | 4 +- Utilities/cmcurl/lib/vauth/krb5_gssapi.c | 2 +- Utilities/cmcurl/lib/vauth/krb5_sspi.c | 2 +- Utilities/cmcurl/lib/vauth/ntlm.c | 4 +- Utilities/cmcurl/lib/vauth/ntlm_sspi.c | 4 +- Utilities/cmcurl/lib/vauth/spnego_gssapi.c | 2 +- Utilities/cmcurl/lib/vauth/spnego_sspi.c | 4 +- Utilities/cmcurl/lib/vtls/axtls.h | 1 - Utilities/cmcurl/lib/vtls/darwinssl.c | 429 ++++--- Utilities/cmcurl/lib/vtls/gskit.c | 5 +- Utilities/cmcurl/lib/vtls/gtls.c | 91 +- Utilities/cmcurl/lib/vtls/mbedtls.c | 3 - Utilities/cmcurl/lib/vtls/mesalink.c | 627 +++++++++ Utilities/cmcurl/lib/vtls/{cyassl.h => mesalink.h} | 13 +- Utilities/cmcurl/lib/vtls/nss.c | 17 +- Utilities/cmcurl/lib/vtls/openssl.c | 75 +- Utilities/cmcurl/lib/vtls/polarssl.c | 3 - Utilities/cmcurl/lib/vtls/schannel.c | 105 +- Utilities/cmcurl/lib/vtls/schannel.h | 2 +- Utilities/cmcurl/lib/vtls/schannel_verify.c | 8 +- Utilities/cmcurl/lib/vtls/vtls.c | 5 + Utilities/cmcurl/lib/vtls/vtls.h | 1 + Utilities/cmcurl/lib/x509asn1.c | 144 ++- 131 files changed, 5060 insertions(+), 2208 deletions(-) create mode 100644 Utilities/cmcurl/include/curl/urlapi.h create mode 100644 Utilities/cmcurl/lib/doh.c create mode 100644 Utilities/cmcurl/lib/doh.h copy Utilities/cmcurl/lib/{curl_range.h => urlapi-int.h} (69%) create mode 100644 Utilities/cmcurl/lib/urlapi.c create mode 100644 Utilities/cmcurl/lib/vtls/mesalink.c copy Utilities/cmcurl/lib/vtls/{cyassl.h => mesalink.h} (80%) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 00:05:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 00:05:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-335-g4476005 Message-ID: <20181106050504.77433126724@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 44760059fcbd9e84bd560c2be9ea00c5483da8f2 (commit) from e5d298b8fdb12283291f37048ae8f68a60a6becb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=44760059fcbd9e84bd560c2be9ea00c5483da8f2 commit 44760059fcbd9e84bd560c2be9ea00c5483da8f2 Author: Kitware Robot AuthorDate: Tue Nov 6 00:01:08 2018 -0500 Commit: Kitware Robot CommitDate: Tue Nov 6 00:01:08 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index cfce90d..7918d80 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 13) -set(CMake_VERSION_PATCH 20181105) +set(CMake_VERSION_PATCH 20181106) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 11:33:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 11:33:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-343-gf55b7bd Message-ID: <20181106163306.17929126B27@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via f55b7bdc5dd0dbc6897cb2d5f4673516a6afc4db (commit) via 1674a5b0a4c2432b9fe7c8ceb4287312c46ad763 (commit) via c752edfcb39e53edb972374eff795f027f85b4c7 (commit) via 3f22656d8ca3ab264a714d95c4cdfd2cb9972650 (commit) via 1e08b625c291e0bb57d253b6656e812dc8848bd8 (commit) via f1a3e4eca8310e8357a1fe0c0bfe75021952b874 (commit) via 970b18e9a5dca2c5bb6d1ecc79f3f9d1c727d641 (commit) via 20d5e77a270639a124fea587bb68b2fb6a5356fc (commit) from 44760059fcbd9e84bd560c2be9ea00c5483da8f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f55b7bdc5dd0dbc6897cb2d5f4673516a6afc4db commit f55b7bdc5dd0dbc6897cb2d5f4673516a6afc4db Merge: 1674a5b 3f22656 Author: Brad King AuthorDate: Tue Nov 6 16:30:01 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 11:31:55 2018 -0500 Merge topic 'FindBoost-explicit-arch-tag' 3f22656d8c Merge branch 'backport-FindBoost-explicit-arch-tag' 1e08b625c2 FindBoost: Add explicit Boost_ARCHITECTURE option Acked-by: Kitware Robot Merge-request: !2568 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1674a5b0a4c2432b9fe7c8ceb4287312c46ad763 commit 1674a5b0a4c2432b9fe7c8ceb4287312c46ad763 Merge: c752edf 20d5e77 Author: Brad King AuthorDate: Tue Nov 6 16:29:46 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 11:30:27 2018 -0500 Merge topic 'rename-cpack-ext-generator' 20d5e77a27 CPack: Rename Ext generator to External Acked-by: Kitware Robot Merge-request: !2566 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c752edfcb39e53edb972374eff795f027f85b4c7 commit c752edfcb39e53edb972374eff795f027f85b4c7 Merge: 4476005 f1a3e4e Author: Brad King AuthorDate: Tue Nov 6 16:29:24 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 11:29:42 2018 -0500 Merge topic 'blaslapack95' f1a3e4eca8 FindLAPACK: Correct library name and symbol searched in LAPACK95 wrapper 970b18e9a5 FindBLAS: Correct symbol searched in BLAS95 wrapper Acked-by: Kitware Robot Merge-request: !2560 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3f22656d8ca3ab264a714d95c4cdfd2cb9972650 commit 3f22656d8ca3ab264a714d95c4cdfd2cb9972650 Merge: e5d298b 1e08b62 Author: Brad King AuthorDate: Mon Nov 5 11:45:58 2018 -0500 Commit: Brad King CommitDate: Mon Nov 5 11:45:58 2018 -0500 Merge branch 'backport-FindBoost-explicit-arch-tag' diff --cc Modules/FindBoost.cmake index 23f636e,e983941..889dbf1 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@@ -1,238 -1,240 +1,241 @@@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindBoost -# --------- -# -# Find Boost include dirs and libraries -# -# Use this module by invoking find_package with the form:: -# -# find_package(Boost -# [version] [EXACT] # Minimum or EXACT version e.g. 1.67.0 -# [REQUIRED] # Fail with error if Boost is not found -# [COMPONENTS ...] # Boost libraries by their canonical name -# # e.g. "date_time" for "libboost_date_time" -# [OPTIONAL_COMPONENTS ...] -# # Optional Boost libraries by their canonical name) -# ) # e.g. "date_time" for "libboost_date_time" -# -# This module finds headers and requested component libraries OR a CMake -# package configuration file provided by a "Boost CMake" build. For the -# latter case skip to the "Boost CMake" section below. For the former -# case results are reported in variables:: -# -# Boost_FOUND - True if headers and requested libraries were found -# Boost_INCLUDE_DIRS - Boost include directories -# Boost_LIBRARY_DIRS - Link directories for Boost libraries -# Boost_LIBRARIES - Boost component libraries to be linked -# Boost__FOUND - True if component was found ( is upper-case) -# Boost__LIBRARY - Libraries to link for component (may include -# target_link_libraries debug/optimized keywords) -# Boost_VERSION - BOOST_VERSION value from boost/version.hpp -# Boost_LIB_VERSION - Version string appended to library filenames -# Boost_MAJOR_VERSION - Boost major version number (X in X.y.z) -# Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z) -# Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z) -# Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) -# - Pass to add_definitions() to have diagnostic -# information about Boost's automatic linking -# displayed during compilation -# -# Note that Boost Python components require a Python version suffix -# (Boost 1.67 and later), e.g. ``python36`` or ``python27`` for the -# versions built against Python 3.6 and 2.7, respectively. This also -# applies to additional components using Python including -# ``mpi_python`` and ``numpy``. Earlier Boost releases may use -# distribution-specific suffixes such as ``2``, ``3`` or ``2.7``. -# These may also be used as suffixes, but note that they are not -# portable. -# -# This module reads hints about search locations from variables:: -# -# BOOST_ROOT - Preferred installation prefix -# (or BOOSTROOT) -# BOOST_INCLUDEDIR - Preferred include directory e.g. /include -# BOOST_LIBRARYDIR - Preferred library directory e.g. /lib -# Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not -# specified by these hint variables. Default is OFF. -# Boost_ADDITIONAL_VERSIONS -# - List of Boost versions not known to this module -# (Boost install locations may contain the version) -# -# and saves search results persistently in CMake cache entries:: -# -# Boost_INCLUDE_DIR - Directory containing Boost headers -# Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries -# Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries -# Boost__LIBRARY_DEBUG - Component library debug variant -# Boost__LIBRARY_RELEASE - Component library release variant -# -# The following :prop_tgt:`IMPORTED` targets are also defined:: -# -# Boost::boost - Target for header-only dependencies -# (Boost include directory) -# Boost:: - Target for specific component dependency -# (shared or static library); is lower- -# case -# Boost::diagnostic_definitions - interface target to enable diagnostic -# information about Boost's automatic linking -# during compilation (adds BOOST_LIB_DIAGNOSTIC) -# Boost::disable_autolinking - interface target to disable automatic -# linking with MSVC (adds BOOST_ALL_NO_LIB) -# Boost::dynamic_linking - interface target to enable dynamic linking -# linking with MSVC (adds BOOST_ALL_DYN_LINK) -# -# Implicit dependencies such as Boost::filesystem requiring -# Boost::system will be automatically detected and satisfied, even -# if system is not specified when using find_package and if -# Boost::system is not added to target_link_libraries. If using -# Boost::thread, then Threads::Threads will also be added automatically. -# -# It is important to note that the imported targets behave differently -# than variables created by this module: multiple calls to -# find_package(Boost) in the same directory or sub-directories with -# different options (e.g. static or shared) will not override the -# values of the targets created by the first call. -# -# Users may set these hints or results as cache entries. Projects -# should not read these entries directly but instead use the above -# result variables. Note that some hint names start in upper-case -# "BOOST". One may specify these as environment variables if they are -# not specified as CMake variables or cache entries. -# -# This module first searches for the Boost header files using the above -# hint variables (excluding BOOST_LIBRARYDIR) and saves the result in -# Boost_INCLUDE_DIR. Then it searches for requested component libraries -# using the above hints (excluding BOOST_INCLUDEDIR and -# Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR, -# and the library name configuration settings below. It saves the -# library directories in Boost_LIBRARY_DIR_DEBUG and -# Boost_LIBRARY_DIR_RELEASE and individual library -# locations in Boost__LIBRARY_DEBUG and Boost__LIBRARY_RELEASE. -# When one changes settings used by previous searches in the same build -# tree (excluding environment variables) this module discards previous -# search results affected by the changes and searches again. -# -# Boost libraries come in many variants encoded in their file name. -# Users or projects may tell this module which variant to find by -# setting variables:: -# -# Boost_USE_DEBUG_LIBS - Set to ON or OFF to specify whether to search -# and use the debug libraries. Default is ON. -# Boost_USE_RELEASE_LIBS - Set to ON or OFF to specify whether to search -# and use the release libraries. Default is ON. -# Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded -# libraries ('mt' tag). Default is ON. -# Boost_USE_STATIC_LIBS - Set to ON to force the use of the static -# libraries. Default is OFF. -# Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use -# libraries linked statically to the C++ runtime -# ('s' tag). Default is platform dependent. -# Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use -# libraries linked to the MS debug C++ runtime -# ('g' tag). Default is ON. -# Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a -# debug Python build ('y' tag). Default is OFF. -# Boost_USE_STLPORT - Set to ON to use libraries compiled with -# STLPort ('p' tag). Default is OFF. -# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS -# - Set to ON to use libraries compiled with -# STLPort deprecated "native iostreams" -# ('n' tag). Default is OFF. -# Boost_COMPILER - Set to the compiler-specific library suffix -# (e.g. "-gcc43"). Default is auto-computed -# for the C++ compiler in use. A list may be -# used if multiple compatible suffixes should -# be tested for, in decreasing order of -# preference. -# Boost_ARCHITECTURE - Set to the architecture-specific library suffix -# (e.g. "-x64"). Default is auto-computed for the -# C++ compiler in use. -# Boost_THREADAPI - Suffix for "thread" component library name, -# such as "pthread" or "win32". Names with -# and without this suffix will both be tried. -# Boost_NAMESPACE - Alternate namespace used to build boost with -# e.g. if set to "myboost", will search for -# myboost_thread instead of boost_thread. -# -# Other variables one may set to control this module are:: -# -# Boost_DEBUG - Set to ON to enable debug output from FindBoost. -# Please enable this before filing any bug report. -# Boost_DETAILED_FAILURE_MSG -# - Set to ON to add detailed information to the -# failure message even when the REQUIRED option -# is not given to the find_package call. -# Boost_REALPATH - Set to ON to resolve symlinks for discovered -# libraries to assist with packaging. For example, -# the "system" component library may be resolved to -# "/usr/lib/libboost_system.so.1.67.0" instead of -# "/usr/lib/libboost_system.so". This does not -# affect linking and should not be enabled unless -# the user needs this information. -# Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and -# Boost_LIBRARY_DIR_DEBUG. -# -# On Visual Studio and Borland compilers Boost headers request automatic -# linking to corresponding libraries. This requires matching libraries -# to be linked explicitly or available in the link library search path. -# In this case setting Boost_USE_STATIC_LIBS to OFF may not achieve -# dynamic linking. Boost automatic linking typically requests static -# libraries with a few exceptions (such as Boost.Python). Use:: -# -# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) -# -# to ask Boost to report information about automatic linking requests. -# -# Example to find Boost headers only:: -# -# find_package(Boost 1.36.0) -# if(Boost_FOUND) -# include_directories(${Boost_INCLUDE_DIRS}) -# add_executable(foo foo.cc) -# endif() -# -# Example to find Boost libraries and use imported targets:: -# -# find_package(Boost 1.56 REQUIRED COMPONENTS -# date_time filesystem iostreams) -# add_executable(foo foo.cc) -# target_link_libraries(foo Boost::date_time Boost::filesystem -# Boost::iostreams) -# -# Example to find Boost Python 3.6 libraries and use imported targets:: -# -# find_package(Boost 1.67 REQUIRED COMPONENTS -# python36 numpy36) -# add_executable(foo foo.cc) -# target_link_libraries(foo Boost::python36 Boost::numpy36) -# -# Example to find Boost headers and some *static* (release only) libraries:: -# -# set(Boost_USE_STATIC_LIBS ON) # only find static libs -# set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and -# set(Boost_USE_RELEASE_LIBS ON) # only find release libs -# set(Boost_USE_MULTITHREADED ON) -# set(Boost_USE_STATIC_RUNTIME OFF) -# find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...) -# if(Boost_FOUND) -# include_directories(${Boost_INCLUDE_DIRS}) -# add_executable(foo foo.cc) -# target_link_libraries(foo ${Boost_LIBRARIES}) -# endif() -# -# Boost CMake -# ^^^^^^^^^^^ -# -# If Boost was built using the boost-cmake project it provides a package -# configuration file for use with find_package's Config mode. This -# module looks for the package configuration file called -# BoostConfig.cmake or boost-config.cmake and stores the result in cache -# entry "Boost_DIR". If found, the package configuration file is loaded -# and this module returns with no further action. See documentation of -# the Boost CMake package configuration for details on what it provides. -# -# Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. +#[=======================================================================[.rst: +FindBoost +--------- + +Find Boost include dirs and libraries + +Use this module by invoking find_package with the form:: + + find_package(Boost + [version] [EXACT] # Minimum or EXACT version e.g. 1.67.0 + [REQUIRED] # Fail with error if Boost is not found + [COMPONENTS ...] # Boost libraries by their canonical name + # e.g. "date_time" for "libboost_date_time" + [OPTIONAL_COMPONENTS ...] + # Optional Boost libraries by their canonical name) + ) # e.g. "date_time" for "libboost_date_time" + +This module finds headers and requested component libraries OR a CMake +package configuration file provided by a "Boost CMake" build. For the +latter case skip to the "Boost CMake" section below. For the former +case results are reported in variables:: + + Boost_FOUND - True if headers and requested libraries were found + Boost_INCLUDE_DIRS - Boost include directories + Boost_LIBRARY_DIRS - Link directories for Boost libraries + Boost_LIBRARIES - Boost component libraries to be linked + Boost__FOUND - True if component was found ( is upper-case) + Boost__LIBRARY - Libraries to link for component (may include + target_link_libraries debug/optimized keywords) + Boost_VERSION - BOOST_VERSION value from boost/version.hpp + Boost_LIB_VERSION - Version string appended to library filenames + Boost_MAJOR_VERSION - Boost major version number (X in X.y.z) + Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z) + Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z) + Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) + - Pass to add_definitions() to have diagnostic + information about Boost's automatic linking + displayed during compilation + +Note that Boost Python components require a Python version suffix +(Boost 1.67 and later), e.g. ``python36`` or ``python27`` for the +versions built against Python 3.6 and 2.7, respectively. This also +applies to additional components using Python including +``mpi_python`` and ``numpy``. Earlier Boost releases may use +distribution-specific suffixes such as ``2``, ``3`` or ``2.7``. +These may also be used as suffixes, but note that they are not +portable. + +This module reads hints about search locations from variables:: + + BOOST_ROOT - Preferred installation prefix + (or BOOSTROOT) + BOOST_INCLUDEDIR - Preferred include directory e.g. /include + BOOST_LIBRARYDIR - Preferred library directory e.g. /lib + Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not + specified by these hint variables. Default is OFF. + Boost_ADDITIONAL_VERSIONS + - List of Boost versions not known to this module + (Boost install locations may contain the version) + +and saves search results persistently in CMake cache entries:: + + Boost_INCLUDE_DIR - Directory containing Boost headers + Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries + Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries + Boost__LIBRARY_DEBUG - Component library debug variant + Boost__LIBRARY_RELEASE - Component library release variant + +The following :prop_tgt:`IMPORTED` targets are also defined:: + + Boost::boost - Target for header-only dependencies + (Boost include directory) + Boost:: - Target for specific component dependency + (shared or static library); is lower- + case + Boost::diagnostic_definitions - interface target to enable diagnostic + information about Boost's automatic linking + during compilation (adds BOOST_LIB_DIAGNOSTIC) + Boost::disable_autolinking - interface target to disable automatic + linking with MSVC (adds BOOST_ALL_NO_LIB) + Boost::dynamic_linking - interface target to enable dynamic linking + linking with MSVC (adds BOOST_ALL_DYN_LINK) + +Implicit dependencies such as Boost::filesystem requiring +Boost::system will be automatically detected and satisfied, even +if system is not specified when using find_package and if +Boost::system is not added to target_link_libraries. If using +Boost::thread, then Threads::Threads will also be added automatically. + +It is important to note that the imported targets behave differently +than variables created by this module: multiple calls to +find_package(Boost) in the same directory or sub-directories with +different options (e.g. static or shared) will not override the +values of the targets created by the first call. + +Users may set these hints or results as cache entries. Projects +should not read these entries directly but instead use the above +result variables. Note that some hint names start in upper-case +"BOOST". One may specify these as environment variables if they are +not specified as CMake variables or cache entries. + +This module first searches for the Boost header files using the above +hint variables (excluding BOOST_LIBRARYDIR) and saves the result in +Boost_INCLUDE_DIR. Then it searches for requested component libraries +using the above hints (excluding BOOST_INCLUDEDIR and +Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR, +and the library name configuration settings below. It saves the +library directories in Boost_LIBRARY_DIR_DEBUG and +Boost_LIBRARY_DIR_RELEASE and individual library +locations in Boost__LIBRARY_DEBUG and Boost__LIBRARY_RELEASE. +When one changes settings used by previous searches in the same build +tree (excluding environment variables) this module discards previous +search results affected by the changes and searches again. + +Boost libraries come in many variants encoded in their file name. +Users or projects may tell this module which variant to find by +setting variables:: + + Boost_USE_DEBUG_LIBS - Set to ON or OFF to specify whether to search + and use the debug libraries. Default is ON. + Boost_USE_RELEASE_LIBS - Set to ON or OFF to specify whether to search + and use the release libraries. Default is ON. + Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded + libraries ('mt' tag). Default is ON. + Boost_USE_STATIC_LIBS - Set to ON to force the use of the static + libraries. Default is OFF. + Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use + libraries linked statically to the C++ runtime + ('s' tag). Default is platform dependent. + Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use + libraries linked to the MS debug C++ runtime + ('g' tag). Default is ON. + Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a + debug Python build ('y' tag). Default is OFF. + Boost_USE_STLPORT - Set to ON to use libraries compiled with + STLPort ('p' tag). Default is OFF. + Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS + - Set to ON to use libraries compiled with + STLPort deprecated "native iostreams" + ('n' tag). Default is OFF. + Boost_COMPILER - Set to the compiler-specific library suffix + (e.g. "-gcc43"). Default is auto-computed + for the C++ compiler in use. A list may be + used if multiple compatible suffixes should + be tested for, in decreasing order of + preference. ++ Boost_ARCHITECTURE - Set to the architecture-specific library suffix ++ (e.g. "-x64"). Default is auto-computed for the ++ C++ compiler in use. + Boost_THREADAPI - Suffix for "thread" component library name, + such as "pthread" or "win32". Names with + and without this suffix will both be tried. + Boost_NAMESPACE - Alternate namespace used to build boost with + e.g. if set to "myboost", will search for + myboost_thread instead of boost_thread. + +Other variables one may set to control this module are:: + + Boost_DEBUG - Set to ON to enable debug output from FindBoost. + Please enable this before filing any bug report. + Boost_DETAILED_FAILURE_MSG + - Set to ON to add detailed information to the + failure message even when the REQUIRED option + is not given to the find_package call. + Boost_REALPATH - Set to ON to resolve symlinks for discovered + libraries to assist with packaging. For example, + the "system" component library may be resolved to + "/usr/lib/libboost_system.so.1.67.0" instead of + "/usr/lib/libboost_system.so". This does not + affect linking and should not be enabled unless + the user needs this information. + Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and + Boost_LIBRARY_DIR_DEBUG. + +On Visual Studio and Borland compilers Boost headers request automatic +linking to corresponding libraries. This requires matching libraries +to be linked explicitly or available in the link library search path. +In this case setting Boost_USE_STATIC_LIBS to OFF may not achieve +dynamic linking. Boost automatic linking typically requests static +libraries with a few exceptions (such as Boost.Python). Use:: + + add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) + +to ask Boost to report information about automatic linking requests. + +Example to find Boost headers only:: + + find_package(Boost 1.36.0) + if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + add_executable(foo foo.cc) + endif() + +Example to find Boost libraries and use imported targets:: + + find_package(Boost 1.56 REQUIRED COMPONENTS + date_time filesystem iostreams) + add_executable(foo foo.cc) + target_link_libraries(foo Boost::date_time Boost::filesystem + Boost::iostreams) + +Example to find Boost Python 3.6 libraries and use imported targets:: + + find_package(Boost 1.67 REQUIRED COMPONENTS + python36 numpy36) + add_executable(foo foo.cc) + target_link_libraries(foo Boost::python36 Boost::numpy36) + +Example to find Boost headers and some *static* (release only) libraries:: + + set(Boost_USE_STATIC_LIBS ON) # only find static libs + set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and + set(Boost_USE_RELEASE_LIBS ON) # only find release libs + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...) + if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + add_executable(foo foo.cc) + target_link_libraries(foo ${Boost_LIBRARIES}) + endif() + +Boost CMake +^^^^^^^^^^^ + +If Boost was built using the boost-cmake project it provides a package +configuration file for use with find_package's Config mode. This +module looks for the package configuration file called +BoostConfig.cmake or boost-config.cmake and stores the result in cache +entry "Boost_DIR". If found, the package configuration file is loaded +and this module returns with no further action. See documentation of +the Boost CMake package configuration for details on what it provides. + +Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. +#]=======================================================================] # Save project's policies cmake_policy(PUSH) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1e08b625c291e0bb57d253b6656e812dc8848bd8 commit 1e08b625c291e0bb57d253b6656e812dc8848bd8 Author: Brad King AuthorDate: Mon Nov 5 10:47:04 2018 -0500 Commit: Brad King CommitDate: Mon Nov 5 10:55:15 2018 -0500 FindBoost: Add explicit Boost_ARCHITECTURE option Boost 1.66 and above built with `--layout=versioned` add an architecture tag to the library file names. We already try to compute this tag automatically when `CMAKE_CXX_COMPILER_ARCHITECTURE_ID` is available, but that is currently not computed everywhere. Add an explicit `Boost_ARCHITECTURE` option that a user can set to specify the architecture tag. Issue: #17701 diff --git a/Help/release/3.13.rst b/Help/release/3.13.rst index f547556..605122a 100644 --- a/Help/release/3.13.rst +++ b/Help/release/3.13.rst @@ -138,6 +138,9 @@ Properties Modules ------- +* The :module:`FindBoost` module gained a ``Boost_ARCHITECTURE`` option + to specify a Boost architecture-specific library filename fragment. + * The :module:`FindCURL` module learned to find debug and release variants separately. diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index e0f0517..e983941 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -147,6 +147,9 @@ # used if multiple compatible suffixes should # be tested for, in decreasing order of # preference. +# Boost_ARCHITECTURE - Set to the architecture-specific library suffix +# (e.g. "-x64"). Default is auto-computed for the +# C++ compiler in use. # Boost_THREADAPI - Suffix for "thread" component library name, # such as "pthread" or "win32". Names with # and without this suffix will both be tried. @@ -1499,27 +1502,35 @@ endif() # -x86 Architecture and address model tag # First character is the architecture, then word-size, either 32 or 64 # Only used in 'versioned' layout, added in Boost 1.66.0 -set(_boost_ARCHITECTURE_TAG "") -# {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers -if(NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" AND NOT Boost_VERSION VERSION_LESS 106600) - string(APPEND _boost_ARCHITECTURE_TAG "-") - # This needs to be kept in-sync with the section of CMakePlatformId.h.in - # inside 'defined(_WIN32) && defined(_MSC_VER)' - if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "IA64") - string(APPEND _boost_ARCHITECTURE_TAG "i") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "X86" - OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64") - string(APPEND _boost_ARCHITECTURE_TAG "x") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "^ARM") - string(APPEND _boost_ARCHITECTURE_TAG "a") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "MIPS") - string(APPEND _boost_ARCHITECTURE_TAG "m") +if(DEFINED Boost_ARCHITECTURE) + set(_boost_ARCHITECTURE_TAG "${Boost_ARCHITECTURE}") + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "using user-specified Boost_ARCHITECTURE = ${_boost_ARCHITECTURE_TAG}") endif() +else() + set(_boost_ARCHITECTURE_TAG "") + # {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers + if(NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" AND NOT Boost_VERSION VERSION_LESS 106600) + string(APPEND _boost_ARCHITECTURE_TAG "-") + # This needs to be kept in-sync with the section of CMakePlatformId.h.in + # inside 'defined(_WIN32) && defined(_MSC_VER)' + if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "IA64") + string(APPEND _boost_ARCHITECTURE_TAG "i") + elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "X86" + OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64") + string(APPEND _boost_ARCHITECTURE_TAG "x") + elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "^ARM") + string(APPEND _boost_ARCHITECTURE_TAG "a") + elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "MIPS") + string(APPEND _boost_ARCHITECTURE_TAG "m") + endif() - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - string(APPEND _boost_ARCHITECTURE_TAG "64") - else() - string(APPEND _boost_ARCHITECTURE_TAG "32") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + string(APPEND _boost_ARCHITECTURE_TAG "64") + else() + string(APPEND _boost_ARCHITECTURE_TAG "32") + endif() endif() endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f1a3e4eca8310e8357a1fe0c0bfe75021952b874 commit f1a3e4eca8310e8357a1fe0c0bfe75021952b874 Author: Jakub Benda AuthorDate: Sun Nov 4 17:16:32 2018 +0000 Commit: Brad King CommitDate: Mon Nov 5 08:00:02 2018 -0500 FindLAPACK: Correct library name and symbol searched in LAPACK95 wrapper The symbol "CHEEV", originally used to determine if a library provides Fortran 95 wrappers for LAPACK, has been replaced by "cheev_f95". "CHEEV" is provided by libmkl_intel_(i)lp64, which does not provide the generic Fortran 95 wrappers. Instead, libmkl_lapack95_(i)lp64 does; one of the specializations of the type-generic interfaces contained in that library is "lapack_f95". Also, FindLAPACK used libmkl_intel_(i)lp64 instead of the correct libmkl_lapack95_(i)lp64 library for LAPACK95 functionality. This has been fixed, too. diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 7ca9950..2c6145a 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -287,7 +287,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") set(LAPACK_SEARCH_LIBS "") if (BLA_F95) - set(LAPACK_mkl_SEARCH_SYMBOL "CHEEV") + set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95") set(_LIBRARIES LAPACK95_LIBRARIES) set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) @@ -298,7 +298,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") list(APPEND LAPACK_SEARCH_LIBS "mkl_intel_c") list(APPEND LAPACK_SEARCH_LIBS - "mkl_intel_${BLAS_mkl_ILP_MODE}") + "mkl_lapack95_${BLAS_mkl_ILP_MODE}") else() set(LAPACK_mkl_SEARCH_SYMBOL "cheev") set(_LIBRARIES LAPACK_LIBRARIES) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=970b18e9a5dca2c5bb6d1ecc79f3f9d1c727d641 commit 970b18e9a5dca2c5bb6d1ecc79f3f9d1c727d641 Author: Jakub Benda AuthorDate: Sun Nov 4 17:08:15 2018 +0000 Commit: Brad King CommitDate: Mon Nov 5 08:00:02 2018 -0500 FindBLAS: Correct symbol searched in BLAS95 wrapper The symbol "SGEMM", originally used to determine if a library provides Fortran 95 wrappers for BLAS, has been replaced by "sgemm_f95". "SGEMM" is provided by libmkl_intel_(i)lp64, which does not provide the generic Fortran 95 wrappers. Instead, libmkl_blas95_(i)lp does; one of the specializations of the type-generic interfaces contained in that library is "sgemm_f95". diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index e955bc2..efcf355 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -222,7 +222,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") set(BLAS_SEARCH_LIBS "") if(BLA_F95) - set(BLAS_mkl_SEARCH_SYMBOL SGEMM) + set(BLAS_mkl_SEARCH_SYMBOL sgemm_f95) set(_LIBRARIES BLAS95_LIBRARIES) if (WIN32) if (BLA_STATIC) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=20d5e77a270639a124fea587bb68b2fb6a5356fc commit 20d5e77a270639a124fea587bb68b2fb6a5356fc Author: Craig Scott AuthorDate: Mon Nov 5 15:58:24 2018 +1100 Commit: Brad King CommitDate: Mon Nov 5 07:56:03 2018 -0500 CPack: Rename Ext generator to External Ext and External were used inconsistently in the code and the docs. This change converts all uses of Ext to External, including within variable names used by the generator. diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst index f98e1c9..e4912a4 100644 --- a/Help/cpack_gen/external.rst +++ b/Help/cpack_gen/external.rst @@ -21,11 +21,11 @@ install and package files as required. Alternatively CPack can invoke an external packaging software through an optional custom CMake script in -:variable:`CPACK_EXT_PACKAGE_SCRIPT` instead. +:variable:`CPACK_EXTERNAL_PACKAGE_SCRIPT` instead. Staging of installation files may also optionally be taken care of by the generator when enabled through the -:variable:`CPACK_EXT_ENABLE_STAGING` variable. +:variable:`CPACK_EXTERNAL_ENABLE_STAGING` variable. JSON Format ^^^^^^^^^^^ @@ -46,10 +46,10 @@ always of the format ``major.minor``. In other words, it always has exactly two parts, separated by a period. You can request one or more specific versions of the output format as described -below with :variable:`CPACK_EXT_REQUESTED_VERSIONS`. The output format will +below with :variable:`CPACK_EXTERNAL_REQUESTED_VERSIONS`. The output format will have a major version that exactly matches the requested major version, and a minor version that is greater than or equal to the requested minor version. If -no version is requested with :variable:`CPACK_EXT_REQUESTED_VERSIONS`, the +no version is requested with :variable:`CPACK_EXTERNAL_REQUESTED_VERSIONS`, the latest known major version is used by default. Currently, the only supported format is 1.0, which is described below. @@ -234,7 +234,7 @@ following fields in the root: Variables specific to CPack External generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. variable:: CPACK_EXT_REQUESTED_VERSIONS +.. variable:: CPACK_EXTERNAL_REQUESTED_VERSIONS This variable is used to request a specific version of the CPack External generator. It is a list of ``major.minor`` values, separated by semicolons. @@ -248,7 +248,7 @@ Variables specific to CPack External generator The generator knows how to generate the version if it has a versioned generator whose major version exactly matches the requested major version, and whose minor version is greater than or equal to the requested minor - version. For example, if ``CPACK_EXT_REQUESTED_VERSIONS`` contains 1.0, and + version. For example, if ``CPACK_EXTERNAL_REQUESTED_VERSIONS`` contains 1.0, and the CPack External generator knows how to generate 1.1, it will generate 1.1. If the generator doesn't know how to generate a version in the list, it skips the version and looks at the next one. If it doesn't know how to generate any @@ -257,11 +257,11 @@ Variables specific to CPack External generator If this variable is not set, or is empty, the CPack External generator will generate the highest major and minor version that it knows how to generate. - If an invalid version is encountered in ``CPACK_EXT_REQUESTED_VERSIONS`` (one + If an invalid version is encountered in ``CPACK_EXTERNAL_REQUESTED_VERSIONS`` (one that doesn't match ``major.minor``, where ``major`` and ``minor`` are integers), it is ignored. -.. variable:: CPACK_EXT_ENABLE_STAGING +.. variable:: CPACK_EXTERNAL_ENABLE_STAGING This variable can be set to true to enable optional installation into a temporary staging area which can then be picked up @@ -274,7 +274,7 @@ Variables specific to CPack External generator It also contains the staging area ``CPACK_TEMPORARY_DIRECTORY`` into which CPack performs the installation when staging is enabled. -.. variable:: CPACK_EXT_PACKAGE_SCRIPT +.. variable:: CPACK_EXTERNAL_PACKAGE_SCRIPT This variable can optionally specify the full path to a CMake script file to be run as part of the CPack invocation. diff --git a/Modules/Internal/CPack/CPackExt.cmake b/Modules/Internal/CPack/CPackExternal.cmake similarity index 58% rename from Modules/Internal/CPack/CPackExt.cmake rename to Modules/Internal/CPack/CPackExternal.cmake index e52d978..e4d055a 100644 --- a/Modules/Internal/CPack/CPackExt.cmake +++ b/Modules/Internal/CPack/CPackExternal.cmake @@ -1,15 +1,15 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -if(NOT "${CPACK_EXT_REQUESTED_VERSIONS}" STREQUAL "") +if(NOT "${CPACK_EXTERNAL_REQUESTED_VERSIONS}" STREQUAL "") unset(_found_major) - foreach(_req_version IN LISTS CPACK_EXT_REQUESTED_VERSIONS) + foreach(_req_version IN LISTS CPACK_EXTERNAL_REQUESTED_VERSIONS) if(_req_version MATCHES "^([0-9]+)\\.([0-9]+)$") set(_req_major "${CMAKE_MATCH_1}") set(_req_minor "${CMAKE_MATCH_2}") - foreach(_known_version IN LISTS CPACK_EXT_KNOWN_VERSIONS) + foreach(_known_version IN LISTS CPACK_EXTERNAL_KNOWN_VERSIONS) string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _known_version_dummy @@ -33,21 +33,21 @@ if(NOT "${CPACK_EXT_REQUESTED_VERSIONS}" STREQUAL "") endforeach() if(DEFINED _found_major) - set(CPACK_EXT_SELECTED_MAJOR "${_found_major}") - set(CPACK_EXT_SELECTED_MINOR "${_found_minor}") - set(CPACK_EXT_SELECTED_VERSION "${_found_major}.${_found_minor}") + set(CPACK_EXTERNAL_SELECTED_MAJOR "${_found_major}") + set(CPACK_EXTERNAL_SELECTED_MINOR "${_found_minor}") + set(CPACK_EXTERNAL_SELECTED_VERSION "${_found_major}.${_found_minor}") else() message(FATAL_ERROR - "Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS" + "Could not find a suitable version in CPACK_EXTERNAL_REQUESTED_VERSIONS" ) endif() else() - list(GET CPACK_EXT_KNOWN_VERSIONS 0 CPACK_EXT_SELECTED_VERSION) + list(GET CPACK_EXTERNAL_KNOWN_VERSIONS 0 CPACK_EXTERNAL_SELECTED_VERSION) string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _dummy - "${CPACK_EXT_SELECTED_VERSION}" + "${CPACK_EXTERNAL_SELECTED_VERSION}" ) - set(CPACK_EXT_SELECTED_MAJOR "${CMAKE_MATCH_1}") - set(CPACK_EXT_SELECTED_MINOR "${CMAKE_MATCH_2}") + set(CPACK_EXTERNAL_SELECTED_MAJOR "${CMAKE_MATCH_1}") + set(CPACK_EXTERNAL_SELECTED_MINOR "${CMAKE_MATCH_2}") endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3cf6c8f..311f3f4 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -890,7 +890,7 @@ set(CPACK_SRCS CPack/cmCPackArchiveGenerator.cxx CPack/cmCPackComponentGroup.cxx CPack/cmCPackDebGenerator.cxx - CPack/cmCPackExtGenerator.cxx + CPack/cmCPackExternalGenerator.cxx CPack/cmCPackGeneratorFactory.cxx CPack/cmCPackGenerator.cxx CPack/cmCPackLog.cxx diff --git a/Source/CPack/cmCPackExtGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx similarity index 85% rename from Source/CPack/cmCPackExtGenerator.cxx rename to Source/CPack/cmCPackExternalGenerator.cxx index 4c560b9..9f7b236 100644 --- a/Source/CPack/cmCPackExtGenerator.cxx +++ b/Source/CPack/cmCPackExternalGenerator.cxx @@ -1,6 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackExtGenerator.h" +#include "cmCPackExternalGenerator.h" #include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" @@ -16,25 +16,25 @@ #include #include -int cmCPackExtGenerator::InitializeInternal() +int cmCPackExternalGenerator::InitializeInternal() { - this->SetOption("CPACK_EXT_KNOWN_VERSIONS", "1.0"); + this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0"); - if (!this->ReadListFile("Internal/CPack/CPackExt.cmake")) { + if (!this->ReadListFile("Internal/CPack/CPackExternal.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error while executing CPackExt.cmake" << std::endl); + "Error while executing CPackExternal.cmake" << std::endl); return 0; } - std::string major = this->GetOption("CPACK_EXT_SELECTED_MAJOR"); + std::string major = this->GetOption("CPACK_EXTERNAL_SELECTED_MAJOR"); if (major == "1") { - this->Generator = cm::make_unique(this); + this->Generator = cm::make_unique(this); } return this->Superclass::InitializeInternal(); } -int cmCPackExtGenerator::PackageFiles() +int cmCPackExternalGenerator::PackageFiles() { Json::StreamWriterBuilder builder; builder["indentation"] = " "; @@ -57,12 +57,12 @@ int cmCPackExtGenerator::PackageFiles() return 0; } - const char* packageScript = this->GetOption("CPACK_EXT_PACKAGE_SCRIPT"); + const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT"); if (packageScript && *packageScript) { if (!cmSystemTools::FileIsFullPath(packageScript)) { cmCPackLogger( cmCPackLog::LOG_ERROR, - "CPACK_EXT_PACKAGE_SCRIPT does not contain a full file path" + "CPACK_EXTERNAL_PACKAGE_SCRIPT does not contain a full file path" << std::endl); return 0; } @@ -77,12 +77,12 @@ int cmCPackExtGenerator::PackageFiles() return 1; } -bool cmCPackExtGenerator::SupportsComponentInstallation() const +bool cmCPackExternalGenerator::SupportsComponentInstallation() const { return true; } -int cmCPackExtGenerator::InstallProjectViaInstallCommands( +int cmCPackExternalGenerator::InstallProjectViaInstallCommands( bool setDestDir, const std::string& tempInstallDirectory) { if (this->StagingEnabled()) { @@ -93,7 +93,7 @@ int cmCPackExtGenerator::InstallProjectViaInstallCommands( return 1; } -int cmCPackExtGenerator::InstallProjectViaInstallScript( +int cmCPackExternalGenerator::InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory) { if (this->StagingEnabled()) { @@ -104,7 +104,7 @@ int cmCPackExtGenerator::InstallProjectViaInstallScript( return 1; } -int cmCPackExtGenerator::InstallProjectViaInstalledDirectories( +int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories( bool setDestDir, const std::string& tempInstallDirectory, const mode_t* default_dir_mode) { @@ -116,7 +116,7 @@ int cmCPackExtGenerator::InstallProjectViaInstalledDirectories( return 1; } -int cmCPackExtGenerator::RunPreinstallTarget( +int cmCPackExternalGenerator::RunPreinstallTarget( const std::string& installProjectName, const std::string& installDirectory, cmGlobalGenerator* globalGenerator, const std::string& buildConfig) { @@ -128,7 +128,7 @@ int cmCPackExtGenerator::RunPreinstallTarget( return 1; } -int cmCPackExtGenerator::InstallCMakeProject( +int cmCPackExternalGenerator::InstallCMakeProject( bool setDestDir, const std::string& installDirectory, const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode, const std::string& component, bool componentInstall, @@ -145,18 +145,19 @@ int cmCPackExtGenerator::InstallCMakeProject( return 1; } -bool cmCPackExtGenerator::StagingEnabled() const +bool cmCPackExternalGenerator::StagingEnabled() const { - return !cmSystemTools::IsOff(this->GetOption("CPACK_EXT_ENABLE_STAGING")); + return !cmSystemTools::IsOff( + this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING")); } -cmCPackExtGenerator::cmCPackExtVersionGenerator::cmCPackExtVersionGenerator( - cmCPackExtGenerator* parent) +cmCPackExternalGenerator::cmCPackExternalVersionGenerator:: + cmCPackExternalVersionGenerator(cmCPackExternalGenerator* parent) : Parent(parent) { } -int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteVersion( +int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteVersion( Json::Value& root) { root["formatVersionMajor"] = this->GetVersionMajor(); @@ -165,7 +166,7 @@ int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteVersion( return 1; } -int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteToJSON( +int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON( Json::Value& root) { if (!this->WriteVersion(root)) { diff --git a/Source/CPack/cmCPackExtGenerator.h b/Source/CPack/cmCPackExternalGenerator.h similarity index 75% rename from Source/CPack/cmCPackExtGenerator.h rename to Source/CPack/cmCPackExternalGenerator.h index 103e56d..176d6a9 100644 --- a/Source/CPack/cmCPackExtGenerator.h +++ b/Source/CPack/cmCPackExternalGenerator.h @@ -1,7 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackExtGenerator_h -#define cmCPackExtGenerator_h +#ifndef cmCPackExternalGenerator_h +#define cmCPackExternalGenerator_h #include "cmCPackGenerator.h" #include "cm_sys_stat.h" @@ -14,13 +14,13 @@ namespace Json { class Value; } -/** \class cmCPackExtGenerator +/** \class cmCPackExternalGenerator * \brief A generator for CPack External packaging tools */ -class cmCPackExtGenerator : public cmCPackGenerator +class cmCPackExternalGenerator : public cmCPackGenerator { public: - cmCPackTypeMacro(cmCPackExtGenerator, cmCPackGenerator); + cmCPackTypeMacro(cmCPackExternalGenerator, cmCPackGenerator); const char* GetOutputExtension() override { return ".json"; } @@ -54,12 +54,12 @@ protected: private: bool StagingEnabled() const; - class cmCPackExtVersionGenerator + class cmCPackExternalVersionGenerator { public: - cmCPackExtVersionGenerator(cmCPackExtGenerator* parent); + cmCPackExternalVersionGenerator(cmCPackExternalGenerator* parent); - virtual ~cmCPackExtVersionGenerator() = default; + virtual ~cmCPackExternalVersionGenerator() = default; virtual int WriteToJSON(Json::Value& root); @@ -69,20 +69,21 @@ private: int WriteVersion(Json::Value& root); - cmCPackExtGenerator* Parent; + cmCPackExternalGenerator* Parent; }; - class cmCPackExtVersion1Generator : public cmCPackExtVersionGenerator + class cmCPackExternalVersion1Generator + : public cmCPackExternalVersionGenerator { public: - using cmCPackExtVersionGenerator::cmCPackExtVersionGenerator; + using cmCPackExternalVersionGenerator::cmCPackExternalVersionGenerator; protected: int GetVersionMajor() override { return 1; } int GetVersionMinor() override { return 0; } }; - std::unique_ptr Generator; + std::unique_ptr Generator; }; #endif diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 8ef24f7..2c5ab4d 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -12,7 +12,7 @@ # include "cmCPackFreeBSDGenerator.h" #endif #include "cmCPackDebGenerator.h" -#include "cmCPackExtGenerator.h" +#include "cmCPackExternalGenerator.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmCPackNSISGenerator.h" @@ -111,9 +111,9 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() this->RegisterGenerator("NuGet", "NuGet packages", cmCPackNuGetGenerator::CreateGenerator); } - if (cmCPackExtGenerator::CanGenerate()) { - this->RegisterGenerator("Ext", "CPack External packages", - cmCPackExtGenerator::CreateGenerator); + if (cmCPackExternalGenerator::CanGenerate()) { + this->RegisterGenerator("External", "CPack External packages", + cmCPackExternalGenerator::CreateGenerator); } #ifdef __APPLE__ if (cmCPackDragNDropGenerator::CanGenerate()) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 90681b9..13ec746 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -433,7 +433,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") add_RunCMake_test(ctest_labels_for_subprojects) endif() -add_RunCMake_test_group(CPack "DEB;RPM;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;Ext") +add_RunCMake_test_group(CPack "DEB;RPM;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External") # add a test to make sure symbols are exported from a shared library # for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used add_RunCMake_test(AutoExportDll) diff --git a/Tests/RunCMake/CPack/Ext/Helpers.cmake b/Tests/RunCMake/CPack/External/Helpers.cmake similarity index 100% rename from Tests/RunCMake/CPack/Ext/Helpers.cmake rename to Tests/RunCMake/CPack/External/Helpers.cmake diff --git a/Tests/RunCMake/CPack/Ext/Prerequirements.cmake b/Tests/RunCMake/CPack/External/Prerequirements.cmake similarity index 100% rename from Tests/RunCMake/CPack/Ext/Prerequirements.cmake rename to Tests/RunCMake/CPack/External/Prerequirements.cmake diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index 91d3cb7..33ddb72 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -18,8 +18,8 @@ run_cpack_test(GENERATE_SHLIBS_LDCONFIG "DEB" true "COMPONENT") run_cpack_test(INSTALL_SCRIPTS "RPM" false "COMPONENT") run_cpack_test(LONG_FILENAMES "DEB" false "MONOLITHIC") run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM" false "COMPONENT") -run_cpack_test(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;Ext" false "MONOLITHIC;COMPONENT") -run_cpack_test_package_target(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;Ext" false "MONOLITHIC;COMPONENT") +run_cpack_test(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT") +run_cpack_test_package_target(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT") run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false "MONOLITHIC") run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM" false "COMPONENT") run_cpack_test(PER_COMPONENT_FIELDS "RPM;DEB" false "COMPONENT") @@ -35,4 +35,4 @@ run_cpack_test(USER_FILELIST "RPM" false "MONOLITHIC") run_cpack_test(MD5SUMS "DEB" false "MONOLITHIC;COMPONENT") run_cpack_test(CPACK_INSTALL_SCRIPT "ZIP" false "MONOLITHIC") run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB" false "MONOLITHIC;COMPONENT") -run_cpack_test_subtests(EXT "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "Ext" false "MONOLITHIC;COMPONENT") +run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT") diff --git a/Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake deleted file mode 100644 index 97b74f7..0000000 --- a/Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake +++ /dev/null @@ -1,3 +0,0 @@ -if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)") - check_ext_json("${src_dir}/tests/EXT/expected-json-1.0.txt" "${FOUND_FILE_1}") -endif() diff --git a/Tests/RunCMake/CPack/tests/EXT/bad_major-stderr.txt b/Tests/RunCMake/CPack/tests/EXT/bad_major-stderr.txt deleted file mode 100644 index 372c5e4..0000000 --- a/Tests/RunCMake/CPack/tests/EXT/bad_major-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\): - Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS - - -CPack Error: Error while executing CPackExt\.cmake -CPack Error: Cannot initialize the generator Ext diff --git a/Tests/RunCMake/CPack/tests/EXT/bad_minor-stderr.txt b/Tests/RunCMake/CPack/tests/EXT/bad_minor-stderr.txt deleted file mode 100644 index 372c5e4..0000000 --- a/Tests/RunCMake/CPack/tests/EXT/bad_minor-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\): - Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS - - -CPack Error: Error while executing CPackExt\.cmake -CPack Error: Cannot initialize the generator Ext diff --git a/Tests/RunCMake/CPack/tests/EXT/invalid_bad-stderr.txt b/Tests/RunCMake/CPack/tests/EXT/invalid_bad-stderr.txt deleted file mode 100644 index 372c5e4..0000000 --- a/Tests/RunCMake/CPack/tests/EXT/invalid_bad-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\): - Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS - - -CPack Error: Error while executing CPackExt\.cmake -CPack Error: Cannot initialize the generator Ext diff --git a/Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/ExpectedFiles.cmake similarity index 100% rename from Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake rename to Tests/RunCMake/CPack/tests/EXTERNAL/ExpectedFiles.cmake diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/VerifyResult.cmake new file mode 100644 index 0000000..bc19d7e --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/VerifyResult.cmake @@ -0,0 +1,3 @@ +if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)") + check_ext_json("${src_dir}/tests/EXTERNAL/expected-json-1.0.txt" "${FOUND_FILE_1}") +endif() diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/bad_major-stderr.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/bad_major-stderr.txt new file mode 100644 index 0000000..f2e160e --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/bad_major-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*/Modules/Internal/CPack/CPackExternal\.cmake:[0-9]+ \(message\): + Could not find a suitable version in CPACK_EXTERNAL_REQUESTED_VERSIONS + + +CPack Error: Error while executing CPackExternal\.cmake +CPack Error: Cannot initialize the generator External diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/bad_minor-stderr.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/bad_minor-stderr.txt new file mode 100644 index 0000000..f2e160e --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/bad_minor-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*/Modules/Internal/CPack/CPackExternal\.cmake:[0-9]+ \(message\): + Could not find a suitable version in CPACK_EXTERNAL_REQUESTED_VERSIONS + + +CPack Error: Error while executing CPackExternal\.cmake +CPack Error: Cannot initialize the generator External diff --git a/Tests/RunCMake/CPack/tests/EXT/create_package.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake similarity index 100% rename from Tests/RunCMake/CPack/tests/EXT/create_package.cmake rename to Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake diff --git a/Tests/RunCMake/CPack/tests/EXT/expected-json-1.0.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt similarity index 90% rename from Tests/RunCMake/CPack/tests/EXT/expected-json-1.0.txt rename to Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt index b96cf0b..18bf617 100644 --- a/Tests/RunCMake/CPack/tests/EXT/expected-json-1.0.txt +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt @@ -150,8 +150,8 @@ \} \}, "packageDescriptionFile" : ".*/Templates/CPack\.GenericDescription\.txt", - "packageDescriptionSummary" : "EXT-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type built using CMake", - "packageName" : "ext", + "packageDescriptionSummary" : "EXTERNAL-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type built using CMake", + "packageName" : "external", "packageVersion" : "0\.1\.1", "projects" :[ ] \[ @@ -164,9 +164,9 @@ "f3", "f4" \], - "directory" : ".*/Tests/RunCMake/Ext/CPack/EXT-build-(none|good(_multi)?|invalid_good)-subtest", + "directory" : ".*/Tests/RunCMake/External/CPack/EXTERNAL-build-(none|good(_multi)?|invalid_good)-subtest", "installationTypes" : \[\], - "projectName" : "EXT-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type", + "projectName" : "EXTERNAL-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type", "subDirectory" : "/" \} \], diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/invalid_bad-stderr.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/invalid_bad-stderr.txt new file mode 100644 index 0000000..f2e160e --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/invalid_bad-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*/Modules/Internal/CPack/CPackExternal\.cmake:[0-9]+ \(message\): + Could not find a suitable version in CPACK_EXTERNAL_REQUESTED_VERSIONS + + +CPack Error: Error while executing CPackExternal\.cmake +CPack Error: Cannot initialize the generator External diff --git a/Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stderr.txt similarity index 100% rename from Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt rename to Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stderr.txt diff --git a/Tests/RunCMake/CPack/tests/EXT/test.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake similarity index 82% rename from Tests/RunCMake/CPack/tests/EXT/test.cmake rename to Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake index 976cb6a..bc9766b 100644 --- a/Tests/RunCMake/CPack/tests/EXT/test.cmake +++ b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake @@ -1,22 +1,22 @@ include(CPackComponent) if(RunCMake_SUBTEST_SUFFIX STREQUAL "none") - unset(CPACK_EXT_REQUESTED_VERSIONS) + unset(CPACK_EXTERNAL_REQUESTED_VERSIONS) elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "good") - set(CPACK_EXT_REQUESTED_VERSIONS "1.0") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "1.0") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "good_multi") - set(CPACK_EXT_REQUESTED_VERSIONS "1.0;2.0") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "1.0;2.0") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "bad_major") - set(CPACK_EXT_REQUESTED_VERSIONS "2.0") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "2.0") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "bad_minor") - set(CPACK_EXT_REQUESTED_VERSIONS "1.1") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "1.1") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid_good") - set(CPACK_EXT_REQUESTED_VERSIONS "1;1.0") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "1;1.0") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid_bad") - set(CPACK_EXT_REQUESTED_VERSIONS "1") + set(CPACK_EXTERNAL_REQUESTED_VERSIONS "1") elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package") - set(CPACK_EXT_ENABLE_STAGING 1) - set(CPACK_EXT_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake") + set(CPACK_EXTERNAL_ENABLE_STAGING 1) + set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake") endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1) ----------------------------------------------------------------------- Summary of changes: Help/cpack_gen/external.rst | 18 ++++---- Help/release/3.13.rst | 3 ++ Modules/FindBLAS.cmake | 2 +- Modules/FindBoost.cmake | 53 +++++++++++++--------- Modules/FindLAPACK.cmake | 4 +- .../CPack/{CPackExt.cmake => CPackExternal.cmake} | 22 ++++----- Source/CMakeLists.txt | 2 +- ...tGenerator.cxx => cmCPackExternalGenerator.cxx} | 45 +++++++++--------- ...ckExtGenerator.h => cmCPackExternalGenerator.h} | 25 +++++----- Source/CPack/cmCPackGeneratorFactory.cxx | 8 ++-- Tests/RunCMake/CMakeLists.txt | 2 +- Tests/RunCMake/CPack/Ext/Prerequirements.cmake | 0 .../RunCMake/CPack/{Ext => External}/Helpers.cmake | 0 .../CPack/External/Prerequirements.cmake} | 0 Tests/RunCMake/CPack/RunCMakeTest.cmake | 6 +-- Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake | 3 -- .../RunCMake/CPack/tests/EXT/bad_major-stderr.txt | 6 --- .../RunCMake/CPack/tests/EXT/bad_minor-stderr.txt | 6 --- .../CPack/tests/EXT/invalid_bad-stderr.txt | 6 --- .../tests/{EXT => EXTERNAL}/ExpectedFiles.cmake | 0 .../CPack/tests/EXTERNAL/VerifyResult.cmake | 3 ++ .../CPack/tests/EXTERNAL/bad_major-stderr.txt | 6 +++ .../CPack/tests/EXTERNAL/bad_minor-stderr.txt | 6 +++ .../tests/{EXT => EXTERNAL}/create_package.cmake | 0 .../tests/{EXT => EXTERNAL}/expected-json-1.0.txt | 8 ++-- .../CPack/tests/EXTERNAL/invalid_bad-stderr.txt | 6 +++ .../{EXT => EXTERNAL}/stage_and_package-stderr.txt | 0 .../CPack/tests/{EXT => EXTERNAL}/test.cmake | 18 ++++---- 28 files changed, 137 insertions(+), 121 deletions(-) rename Modules/Internal/CPack/{CPackExt.cmake => CPackExternal.cmake} (58%) rename Source/CPack/{cmCPackExtGenerator.cxx => cmCPackExternalGenerator.cxx} (85%) rename Source/CPack/{cmCPackExtGenerator.h => cmCPackExternalGenerator.h} (75%) delete mode 100644 Tests/RunCMake/CPack/Ext/Prerequirements.cmake rename Tests/RunCMake/CPack/{Ext => External}/Helpers.cmake (100%) copy Tests/{Wrapping/vtkIncluded.cxx => RunCMake/CPack/External/Prerequirements.cmake} (100%) delete mode 100644 Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake delete mode 100644 Tests/RunCMake/CPack/tests/EXT/bad_major-stderr.txt delete mode 100644 Tests/RunCMake/CPack/tests/EXT/bad_minor-stderr.txt delete mode 100644 Tests/RunCMake/CPack/tests/EXT/invalid_bad-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/ExpectedFiles.cmake (100%) create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/VerifyResult.cmake create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/bad_major-stderr.txt create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/bad_minor-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/create_package.cmake (100%) rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/expected-json-1.0.txt (90%) create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/invalid_bad-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/stage_and_package-stderr.txt (100%) rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/test.cmake (82%) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 11:43:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 11:43:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-360-gbfdd1ba Message-ID: <20181106164304.13BAD1258C3@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via bfdd1ba604a31b3bb9f0baa29ce6fce467ee2e47 (commit) via 7bed0507554bed0208d66610417b690645768503 (commit) via d80aaad40ba0798861431fda2bf491b07099d87f (commit) via 77f8393afed1d8a051ca7b7d67e0979ec9038442 (commit) via 47255060e7788123901012586f0c51c26bd849b6 (commit) via 575e2cc35da7cef40c521bccf0512483012bc136 (commit) via fe997d80e0eaa154910797ee2612d9f05e003cf6 (commit) via 47f9c15c60e2898640fa57aed4c5ff5ee5c0d3ef (commit) via 336893d9eb0ee732683b18e2e9e8a17e86e09d99 (commit) via 846043dd35cbceec4ec114492ad04805b6ee625a (commit) via b71a9598a408a134bd7d003b6586b345f2b961fe (commit) via f74c406501e5ffb5b6a3c8b76c831ca87e8f0168 (commit) via 0669de5d36b853fa7ff81081de719a0a48e2b654 (commit) via b5e895b5d41dc688bf0acdec352cbccc178a7236 (commit) via 7413f29fe63296cf34176c5fc68c2c5354b43202 (commit) via d2235fd2538eca934f542ff82f21249c3ff314be (commit) via 7a801b7dfb38c2f9f77fbda0f45ed88b70ca4b87 (commit) from f55b7bdc5dd0dbc6897cb2d5f4673516a6afc4db (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bfdd1ba604a31b3bb9f0baa29ce6fce467ee2e47 commit bfdd1ba604a31b3bb9f0baa29ce6fce467ee2e47 Merge: 7bed050 575e2cc Author: Brad King AuthorDate: Tue Nov 6 16:40:09 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 11:40:16 2018 -0500 Merge topic 'FindPostgreSQL-target' 575e2cc35d FindPostgreSQL: extract the actual version number 7413f29fe6 Tests/FindPostgreSQL: add a test for FindPostgreSQL d2235fd253 FindPostgreSQL: add an imported target 7a801b7dfb FindPostgreSQL: Modernize documentation layout Acked-by: Kitware Robot Merge-request: !2555 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7bed0507554bed0208d66610417b690645768503 commit 7bed0507554bed0208d66610417b690645768503 Merge: d80aaad 47f9c15 Author: Brad King AuthorDate: Tue Nov 6 16:38:15 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 11:38:23 2018 -0500 Merge topic 'autogen_origin_depends' 47f9c15c60 Autogen: Update _autogen target documentation 336893d9eb Autogen: Separate AUTOGEN_TARGET_DEPENDS tests into own tests suite 846043dd35 Autogen: Rename MocDepends test to AutogenOriginDependsOn b71a9598a4 Autogen: Add test for AUTOGEN_ORIGIN_DEPENDS=OFF f74c406501 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS release notes 0669de5d36 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS documentation b5e895b5d4 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS support Acked-by: Kitware Robot Merge-request: !2518 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d80aaad40ba0798861431fda2bf491b07099d87f commit d80aaad40ba0798861431fda2bf491b07099d87f Merge: f55b7bd 77f8393 Author: Brad King AuthorDate: Tue Nov 6 11:33:41 2018 -0500 Commit: Brad King CommitDate: Tue Nov 6 11:33:41 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=575e2cc35da7cef40c521bccf0512483012bc136 commit 575e2cc35da7cef40c521bccf0512483012bc136 Author: Ben Boeckel AuthorDate: Thu Nov 1 14:45:25 2018 -0400 Commit: Ben Boeckel CommitDate: Mon Nov 5 11:13:33 2018 -0500 FindPostgreSQL: extract the actual version number The `PG_VERSION` variable can be mangled by distributions to indicate things like the name of the distro and package build numbers. However, `PG_VERSION_NUM` is new in 8.2 (2006), so keep the old extraction code around for old versions. diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake index 6832bbe..4b5e60e 100644 --- a/Modules/FindPostgreSQL.cmake +++ b/Modules/FindPostgreSQL.cmake @@ -175,14 +175,34 @@ if (PostgreSQL_INCLUDE_DIR) foreach(_PG_CONFIG_HEADER ${_PG_CONFIG_HEADERS}) if(EXISTS "${_PG_CONFIG_HEADER}") file(STRINGS "${_PG_CONFIG_HEADER}" pgsql_version_str - REGEX "^#define[\t ]+PG_VERSION[\t ]+\".*\"") + REGEX "^#define[\t ]+PG_VERSION_NUM[\t ]+.*") if(pgsql_version_str) - string(REGEX REPLACE "^#define[\t ]+PG_VERSION[\t ]+\"([^\"]*)\".*" - "\\1" PostgreSQL_VERSION_STRING "${pgsql_version_str}") + string(REGEX REPLACE "^#define[\t ]+PG_VERSION_NUM[\t ]+([0-9]*).*" + "\\1" _PostgreSQL_VERSION_NUM "${pgsql_version_str}") break() endif() endif() endforeach() + if (_PostgreSQL_VERSION_NUM) + math(EXPR _PostgreSQL_major_version "${_PostgreSQL_VERSION_NUM} / 10000") + math(EXPR _PostgreSQL_minor_version "${_PostgreSQL_VERSION_NUM} % 10000") + set(PostgreSQL_VERSION_STRING "${_PostgreSQL_major_version}.${_PostgreSQL_minor_version}") + unset(_PostgreSQL_major_version) + unset(_PostgreSQL_minor_version) + else () + foreach(_PG_CONFIG_HEADER ${_PG_CONFIG_HEADERS}) + if(EXISTS "${_PG_CONFIG_HEADER}") + file(STRINGS "${_PG_CONFIG_HEADER}" pgsql_version_str + REGEX "^#define[\t ]+PG_VERSION[\t ]+\".*\"") + if(pgsql_version_str) + string(REGEX REPLACE "^#define[\t ]+PG_VERSION[\t ]+\"([^\"]*)\".*" + "\\1" PostgreSQL_VERSION_STRING "${pgsql_version_str}") + break() + endif() + endif() + endforeach() + endif () + unset(_PostgreSQL_VERSION_NUM) unset(pgsql_version_str) endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=47f9c15c60e2898640fa57aed4c5ff5ee5c0d3ef commit 47f9c15c60e2898640fa57aed4c5ff5ee5c0d3ef Author: Sebastian Holtermann AuthorDate: Sat Nov 3 12:11:24 2018 +0100 Commit: Sebastian Holtermann CommitDate: Mon Nov 5 14:03:01 2018 +0100 Autogen: Update _autogen target documentation diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 724d8ec..0382794 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -44,14 +44,10 @@ Qt Build Tools Qt relies on some bundled tools for code generation, such as ``moc`` for meta-object code generation, ``uic`` for widget layout and population, -and ``rcc`` for virtual filesystem content generation. These tools may be +and ``rcc`` for virtual file system content generation. These tools may be automatically invoked by :manual:`cmake(1)` if the appropriate conditions are met. The automatic tool invocation may be used with both Qt 4 and Qt 5. -The tools are executed as part of a synthesized custom target generated by -CMake. Target dependencies may be added to that custom target by adding them -to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property. - AUTOMOC ^^^^^^^ @@ -214,19 +210,31 @@ overrides options from the :prop_tgt:`AUTORCC_OPTIONS` target property. Source files can be excluded from :prop_tgt:`AUTORCC` processing by enabling :prop_sf:`SKIP_AUTORCC` or the broader :prop_sf:`SKIP_AUTOGEN`. +The ``_autogen`` target +=============================== + +The ``moc`` and ``uic`` tools are executed as part of a synthesized +``_autogen`` :command:`custom target ` generated by +CMake. By default that ``_autogen`` target inherits the dependencies +of the ```` target (see :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`). +Target dependencies may be added to the ``_autogen`` target by adding +them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property. + Visual Studio Generators ======================== -When using the :manual:`Visual Studio generators `, -CMake uses a ``PRE_BUILD`` :command:`custom command ` for -:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`. -If the :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` processing depends on files, -a :command:`custom target ` is used instead. -This happens when - -- The origin target depends on :prop_sf:`GENERATED` files which aren't excluded - from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by :prop_sf:`SKIP_AUTOMOC`, - :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071` +When using the :manual:`Visual Studio generators `, CMake +generates a ``PRE_BUILD`` :command:`custom command ` +instead of the ``_autogen`` :command:`custom target ` +(for :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`). +This isn't always possible though and +an ``_autogen`` :command:`custom target ` is used, +when either + +- the ```` target depends on :prop_sf:`GENERATED` files which aren't + excluded from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by + :prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` + or :policy:`CMP0071` - :prop_tgt:`AUTOGEN_TARGET_DEPENDS` lists a source file qtmain.lib on Windows diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 3bd693a..70d89f2 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -3,8 +3,8 @@ AUTOMOC Should the target be processed with automoc (for Qt projects). -AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc`` -preprocessor automatically, i.e. without having to use the +:prop_tgt:`AUTOMOC` is a boolean specifying whether CMake will handle the Qt +``moc`` preprocessor automatically, i.e. without having to use the :module:`QT4_WRAP_CPP() ` or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are supported. diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst index 3cc5990..99c2b0e 100644 --- a/Help/prop_tgt/AUTORCC.rst +++ b/Help/prop_tgt/AUTORCC.rst @@ -3,7 +3,7 @@ AUTORCC Should the target be processed with autorcc (for Qt projects). -``AUTORCC`` is a boolean specifying whether CMake will handle +:prop_tgt:`AUTORCC` is a boolean specifying whether CMake will handle the Qt ``rcc`` code generator automatically, i.e. without having to use the :module:`QT4_ADD_RESOURCES() ` or ``QT5_ADD_RESOURCES()`` macro. Currently Qt4 and Qt5 are supported. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 4fc603f..8cae0a7 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -3,7 +3,7 @@ AUTOUIC Should the target be processed with autouic (for Qt projects). -``AUTOUIC`` is a boolean specifying whether CMake will handle +:prop_tgt:`AUTOUIC` is a boolean specifying whether CMake will handle the Qt ``uic`` code generator automatically, i.e. without having to use the :module:`QT4_WRAP_UI() ` or ``QT5_WRAP_UI()`` macro. Currently Qt4 and Qt5 are supported. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=336893d9eb0ee732683b18e2e9e8a17e86e09d99 commit 336893d9eb0ee732683b18e2e9e8a17e86e09d99 Author: Sebastian Holtermann AuthorDate: Tue Oct 30 11:41:37 2018 +0100 Commit: Sebastian Holtermann CommitDate: Mon Nov 5 14:03:01 2018 +0100 Autogen: Separate AUTOGEN_TARGET_DEPENDS tests into own tests suite The tests for AUTOGEN_TARGET_DEPENDS were part of the AutogenOriginDependsOn tests suite. This separates them into an own AutogenTargetDepends tests suite. diff --git a/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt b/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt index f70d9ce..60869eb 100644 --- a/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt +++ b/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt @@ -89,51 +89,3 @@ target_link_libraries(SimpleLib ${QT_QTCORE_TARGET}) add_executable(mocDepGenLib testGenLib.cpp) target_link_libraries(mocDepGenLib SimpleLib ${QT_QTCORE_TARGET}) set_target_properties(mocDepGenLib PROPERTIES AUTOMOC TRUE) - - -# -- Test AUTOGEN_TARGET_DEPENDS with GENERATED file dependency -# -# This tests the dependency of the mocDepATDFile_autogen target of -# mocDepATDTarget to the utility target mocDepATDFileUtil. -# If mocDepATDFile_autogen gets built *before* or in *parallel* to -# mocDepATDFileUtil, the build will fail. That's -# because ATDFile.hpp, which is required by mocDepATDFile_autogen, -# is only valid after the mocDepATDFileUtil build has been completed. -# -# The sleep seconds artificially increase the build time of -# mocDepATDFileUtil to simulate a slow utility target build that takes -# longer to run than the build of the mocDepATDFile_autogen target. -add_custom_command( - OUTPUT ${CBD}/ATDFile.hpp - COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_invalid.hpp.in ${CBD}/ATDFile.hpp - COMMAND ${CMAKE_COMMAND} -E sleep 3 - COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_valid.hpp.in ${CBD}/ATDFile.hpp) - -add_executable(mocDepATDFile testATDFile.cpp) -target_link_libraries(mocDepATDFile ${QT_QTCORE_TARGET}) -set_target_properties(mocDepATDFile PROPERTIES AUTOMOC TRUE) -set_target_properties(mocDepATDFile PROPERTIES AUTOGEN_TARGET_DEPENDS ${CBD}/ATDFile.hpp) - - -# -- Test AUTOGEN_TARGET_DEPENDS with target dependency -# -# This tests the dependency of the mocDepATDTarget_autogen target of -# mocDepATDTarget to the utility target mocDepATDTargetUtil. -# If mocDepATDTarget_autogen gets built *before* or in *parallel* to -# mocDepATDTargetUtil, the build will fail. That's -# because ATDTarget.hpp, which is required by mocDepATDTarget_autogen, -# is only valid after the mocDepATDTargetUtil build has been completed. -# -# The sleep seconds artificially increase the build time of -# mocDepATDTargetUtil to simulate a slow utility target build that takes -# longer to run than the build of the mocDepATDTarget_autogen target. -add_custom_target(mocDepATDTargetUtil - BYPRODUCTS ${CBD}/ATDTarget.hpp - COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_invalid.hpp.in ${CBD}/ATDTarget.hpp - COMMAND ${CMAKE_COMMAND} -E sleep 3 - COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_valid.hpp.in ${CBD}/ATDTarget.hpp) - -add_executable(mocDepATDTarget testATDTarget.cpp) -target_link_libraries(mocDepATDTarget ${QT_QTCORE_TARGET}) -set_target_properties(mocDepATDTarget PROPERTIES AUTOMOC TRUE) -set_target_properties(mocDepATDTarget PROPERTIES AUTOGEN_TARGET_DEPENDS mocDepATDTargetUtil) diff --git a/Tests/QtAutogen/AutogenTargetDepends/CMakeLists.txt b/Tests/QtAutogen/AutogenTargetDepends/CMakeLists.txt new file mode 100644 index 0000000..63b7c98 --- /dev/null +++ b/Tests/QtAutogen/AutogenTargetDepends/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.10) +project(AutogenTargetDepends) +include("../AutogenTest.cmake") + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +set(CSD ${CMAKE_CURRENT_SOURCE_DIR}) +set(CBD ${CMAKE_CURRENT_BINARY_DIR}) + +# -- Test AUTOGEN_TARGET_DEPENDS with GENERATED file dependency +# +# This tests the dependency of the mocDepATDFile_autogen target of +# mocDepATDTarget to the utility target mocDepATDFileUtil. +# If mocDepATDFile_autogen gets built *before* or in *parallel* to +# mocDepATDFileUtil, the build will fail. That's +# because ATDFile.hpp, which is required by mocDepATDFile_autogen, +# is only valid after the mocDepATDFileUtil build has been completed. +# +# The sleep seconds artificially increase the build time of +# mocDepATDFileUtil to simulate a slow utility target build that takes +# longer to run than the build of the mocDepATDFile_autogen target. +add_custom_command( + OUTPUT ${CBD}/ATDFile.hpp + COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_invalid.hpp.in ${CBD}/ATDFile.hpp + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_valid.hpp.in ${CBD}/ATDFile.hpp) + +add_executable(mocDepATDFile testATDFile.cpp) +target_link_libraries(mocDepATDFile ${QT_QTCORE_TARGET}) +set_target_properties(mocDepATDFile PROPERTIES AUTOMOC TRUE) +set_target_properties(mocDepATDFile PROPERTIES AUTOGEN_TARGET_DEPENDS ${CBD}/ATDFile.hpp) + + +# -- Test AUTOGEN_TARGET_DEPENDS with target dependency +# +# This tests the dependency of the mocDepATDTarget_autogen target of +# mocDepATDTarget to the utility target mocDepATDTargetUtil. +# If mocDepATDTarget_autogen gets built *before* or in *parallel* to +# mocDepATDTargetUtil, the build will fail. That's +# because ATDTarget.hpp, which is required by mocDepATDTarget_autogen, +# is only valid after the mocDepATDTargetUtil build has been completed. +# +# The sleep seconds artificially increase the build time of +# mocDepATDTargetUtil to simulate a slow utility target build that takes +# longer to run than the build of the mocDepATDTarget_autogen target. +add_custom_target(mocDepATDTargetUtil + BYPRODUCTS ${CBD}/ATDTarget.hpp + COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_invalid.hpp.in ${CBD}/ATDTarget.hpp + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CSD}/object_valid.hpp.in ${CBD}/ATDTarget.hpp) + +add_executable(mocDepATDTarget testATDTarget.cpp) +target_link_libraries(mocDepATDTarget ${QT_QTCORE_TARGET}) +set_target_properties(mocDepATDTarget PROPERTIES AUTOMOC TRUE) +set_target_properties(mocDepATDTarget PROPERTIES AUTOGEN_TARGET_DEPENDS mocDepATDTargetUtil) diff --git a/Tests/QtAutogen/AutogenTargetDepends/object_invalid.hpp.in b/Tests/QtAutogen/AutogenTargetDepends/object_invalid.hpp.in new file mode 100644 index 0000000..854d9a1 --- /dev/null +++ b/Tests/QtAutogen/AutogenTargetDepends/object_invalid.hpp.in @@ -0,0 +1 @@ +#ifndef diff --git a/Tests/QtAutogen/AutogenTargetDepends/object_valid.hpp.in b/Tests/QtAutogen/AutogenTargetDepends/object_valid.hpp.in new file mode 100644 index 0000000..f364f7c --- /dev/null +++ b/Tests/QtAutogen/AutogenTargetDepends/object_valid.hpp.in @@ -0,0 +1,14 @@ +#ifndef OBJECT_HPP +#define OBJECT_HPP + +#include + +class Object : public QObject +{ + Q_OBJECT +public: + Q_SLOT + void aSlot(){}; +}; + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOn/testATDFile.cpp b/Tests/QtAutogen/AutogenTargetDepends/testATDFile.cpp similarity index 100% rename from Tests/QtAutogen/AutogenOriginDependsOn/testATDFile.cpp rename to Tests/QtAutogen/AutogenTargetDepends/testATDFile.cpp diff --git a/Tests/QtAutogen/AutogenOriginDependsOn/testATDTarget.cpp b/Tests/QtAutogen/AutogenTargetDepends/testATDTarget.cpp similarity index 100% rename from Tests/QtAutogen/AutogenOriginDependsOn/testATDTarget.cpp rename to Tests/QtAutogen/AutogenTargetDepends/testATDTarget.cpp diff --git a/Tests/QtAutogen/CommonTests.cmake b/Tests/QtAutogen/CommonTests.cmake index ccbddbd..58d9f0b 100644 --- a/Tests/QtAutogen/CommonTests.cmake +++ b/Tests/QtAutogen/CommonTests.cmake @@ -17,6 +17,7 @@ if(QT_TEST_VERSION GREATER 4) endif() ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff) ADD_AUTOGEN_TEST(AutogenOriginDependsOn) +ADD_AUTOGEN_TEST(AutogenTargetDepends) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) ADD_AUTOGEN_TEST(MocIncludeRelaxed mocIncludeRelaxed) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=846043dd35cbceec4ec114492ad04805b6ee625a commit 846043dd35cbceec4ec114492ad04805b6ee625a Author: Sebastian Holtermann AuthorDate: Tue Oct 30 11:27:49 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sat Nov 3 12:14:40 2018 +0100 Autogen: Rename MocDepends test to AutogenOriginDependsOn diff --git a/Tests/QtAutogen/MocDepends/CMakeLists.txt b/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt similarity index 99% rename from Tests/QtAutogen/MocDepends/CMakeLists.txt rename to Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt index 6ea72be..f70d9ce 100644 --- a/Tests/QtAutogen/MocDepends/CMakeLists.txt +++ b/Tests/QtAutogen/AutogenOriginDependsOn/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(MocDepends) +project(AutogenOriginDependsOn) include("../AutogenTest.cmake") include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/Tests/QtAutogen/MocDepends/object_invalid.hpp.in b/Tests/QtAutogen/AutogenOriginDependsOn/object_invalid.hpp.in similarity index 100% rename from Tests/QtAutogen/MocDepends/object_invalid.hpp.in rename to Tests/QtAutogen/AutogenOriginDependsOn/object_invalid.hpp.in diff --git a/Tests/QtAutogen/MocDepends/object_valid.hpp.in b/Tests/QtAutogen/AutogenOriginDependsOn/object_valid.hpp.in similarity index 100% rename from Tests/QtAutogen/MocDepends/object_valid.hpp.in rename to Tests/QtAutogen/AutogenOriginDependsOn/object_valid.hpp.in diff --git a/Tests/QtAutogen/MocDepends/simpleLib.cpp.in b/Tests/QtAutogen/AutogenOriginDependsOn/simpleLib.cpp.in similarity index 100% rename from Tests/QtAutogen/MocDepends/simpleLib.cpp.in rename to Tests/QtAutogen/AutogenOriginDependsOn/simpleLib.cpp.in diff --git a/Tests/QtAutogen/MocDepends/simpleLib.hpp.in b/Tests/QtAutogen/AutogenOriginDependsOn/simpleLib.hpp.in similarity index 100% rename from Tests/QtAutogen/MocDepends/simpleLib.hpp.in rename to Tests/QtAutogen/AutogenOriginDependsOn/simpleLib.hpp.in diff --git a/Tests/QtAutogen/MocDepends/testATDFile.cpp b/Tests/QtAutogen/AutogenOriginDependsOn/testATDFile.cpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testATDFile.cpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testATDFile.cpp diff --git a/Tests/QtAutogen/MocDepends/testATDTarget.cpp b/Tests/QtAutogen/AutogenOriginDependsOn/testATDTarget.cpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testATDTarget.cpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testATDTarget.cpp diff --git a/Tests/QtAutogen/MocDepends/testGenFile.cpp b/Tests/QtAutogen/AutogenOriginDependsOn/testGenFile.cpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testGenFile.cpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testGenFile.cpp diff --git a/Tests/QtAutogen/MocDepends/testGenLib.cpp b/Tests/QtAutogen/AutogenOriginDependsOn/testGenLib.cpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testGenLib.cpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testGenLib.cpp diff --git a/Tests/QtAutogen/MocDepends/testGenLib.hpp b/Tests/QtAutogen/AutogenOriginDependsOn/testGenLib.hpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testGenLib.hpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testGenLib.hpp diff --git a/Tests/QtAutogen/MocDepends/testGenTarget.cpp b/Tests/QtAutogen/AutogenOriginDependsOn/testGenTarget.cpp similarity index 100% rename from Tests/QtAutogen/MocDepends/testGenTarget.cpp rename to Tests/QtAutogen/AutogenOriginDependsOn/testGenTarget.cpp diff --git a/Tests/QtAutogen/CommonTests.cmake b/Tests/QtAutogen/CommonTests.cmake index 46d56cb..ccbddbd 100644 --- a/Tests/QtAutogen/CommonTests.cmake +++ b/Tests/QtAutogen/CommonTests.cmake @@ -16,7 +16,7 @@ if(QT_TEST_VERSION GREATER 4) ADD_AUTOGEN_TEST(MocMacroName mocMacroName) endif() ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff) -ADD_AUTOGEN_TEST(MocDepends) +ADD_AUTOGEN_TEST(AutogenOriginDependsOn) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) ADD_AUTOGEN_TEST(MocIncludeRelaxed mocIncludeRelaxed) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b71a9598a408a134bd7d003b6586b345f2b961fe commit b71a9598a408a134bd7d003b6586b345f2b961fe Author: Sebastian Holtermann AuthorDate: Tue Oct 30 11:21:12 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sat Nov 3 12:14:40 2018 +0100 Autogen: Add test for AUTOGEN_ORIGIN_DEPENDS=OFF diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt b/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt new file mode 100644 index 0000000..1c2271a --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt @@ -0,0 +1,71 @@ +cmake_minimum_required(VERSION 3.11) +project(AutogenOriginDependsOff) +include("../AutogenTest.cmake") + +set(CSD ${CMAKE_CURRENT_SOURCE_DIR}) +set(CBD ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CSD}) +include_directories(${CBD}) + +# A GENERATED file ensures there will be an _autogen target in VS +add_custom_command ( + OUTPUT "${CBD}/config.hpp" + COMMAND ${CMAKE_COMMAND} -E copy "${CSD}/config.hpp.in" "${CBD}/config.hpp" + ) + + +# Library "a_mc" provides a header that holds a string with the content of +# mocs_compilation.cpp from a_qt. It therefore must depend on a_qt_autogen. +add_custom_target ( a_mc + COMMAND ${CMAKE_COMMAND} -E sleep 2 + COMMAND ${CMAKE_COMMAND} + "-DMCF=${CBD}/a_qt_autogen/mocs_compilation.cpp" + "-DCF_IN=${CSD}/a_mc.hpp.in" + "-DCF_OUT=${CBD}/a_mc.hpp" + -P ${CSD}/configure_content.cmake + ) +add_dependencies ( a_mc a_qt_autogen ) + +# Library "a_qt" +# - depends on a GENERATED file +# - AUTOMOC enabled +# - depends on a target (a_mc) that depends on a_qt_qutogen +add_library ( a_qt a_qt.cpp "${CBD}/config.hpp" ) +add_dependencies ( a_qt a_mc ) +target_link_libraries ( a_qt ${QT_QTCORE_TARGET}) +set_target_properties ( a_qt PROPERTIES AUTOMOC TRUE) +# Disable AUTOGEN_ORIGIN_DEPENDS to avoid loop dependencies +set_target_properties ( a_qt PROPERTIES AUTOGEN_ORIGIN_DEPENDS OFF) + + +# Library "b_mc" provides a header that holds a string function that returns +# the content of mocs_compilation.cpp from b_qt. +# It therefore must depend on b_qt_autogen. +add_custom_command ( + OUTPUT ${CBD}/b_mc.cpp + DEPENDS b_qt_autogen + COMMAND ${CMAKE_COMMAND} -E sleep 2 + COMMAND ${CMAKE_COMMAND} + "-DMCF=${CBD}/b_qt_autogen/mocs_compilation.cpp" + "-DCF_IN=${CSD}/b_mc.cpp.in" + "-DCF_OUT=${CBD}/b_mc.cpp" + -P ${CSD}/configure_content.cmake + ) +add_library ( b_mc ${CSD}/b_mc.hpp ${CBD}/b_mc.cpp ) + +# Library "b_qt" +# - depends on a GENERATED file +# - AUTOMOC enabled +# - depends on a library (b_mc) that depends on b_qt_qutogen +add_library ( b_qt b_qt.cpp "${CBD}/config.hpp" ) +target_link_libraries ( b_qt b_mc ) +target_link_libraries ( b_qt ${QT_QTCORE_TARGET}) +set_target_properties ( b_qt PROPERTIES AUTOMOC TRUE) +# Disable AUTOGEN_ORIGIN_DEPENDS to avoid loop dependencies +set_target_properties ( b_qt PROPERTIES AUTOGEN_ORIGIN_DEPENDS OFF) + + +# The main target depends on both libraries which depend on the _autogen +# target of the main target. +add_executable ( autogenOriginDependsOff main.cpp ) +target_link_libraries ( autogenOriginDependsOff a_qt b_qt ) diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/a_mc.hpp.in b/Tests/QtAutogen/AutogenOriginDependsOff/a_mc.hpp.in new file mode 100644 index 0000000..fe71f67 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/a_mc.hpp.in @@ -0,0 +1,9 @@ +#ifndef A_MC_HPP +#define A_MC_HPP + +namespace a_mc { + +char const* mocs_compilation = "@MOCS_COMPILATION@"; +} + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.cpp b/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.cpp new file mode 100644 index 0000000..e498969 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.cpp @@ -0,0 +1,28 @@ + +#include "a_qt.hpp" +#include + +namespace a_qt { + +/// @brief A source local QObject based class +class Source_QObject : public QObject +{ + Q_OBJECT +public: + Source_QObject() {} + ~Source_QObject() {} + + std::string str; +}; + +std::string mocs_compilation() +{ + // Create and destroy QObject based classes + Header_QObject header_obj; + Source_QObject source_obj; + + return std::string(a_mc::mocs_compilation); +} +} + +#include "a_qt.moc" diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.hpp b/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.hpp new file mode 100644 index 0000000..e2387ee --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/a_qt.hpp @@ -0,0 +1,25 @@ +#ifndef A_QT_HPP +#define A_QT_HPP + +#include +#include +#include + +namespace a_qt { + +/// @brief A header local QObject based class +class Header_QObject : public QObject +{ + Q_OBJECT +public: + Header_QObject() {} + ~Header_QObject() {} + + std::string str; +}; + +/// @brief Function that returns the content of mocs_compilation.cpp +extern std::string mocs_compilation(); +} + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.cpp.in b/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.cpp.in new file mode 100644 index 0000000..0f5ec30 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.cpp.in @@ -0,0 +1,9 @@ +#include + +namespace b_mc { + +char const* mocs_compilation() +{ + return "@MOCS_COMPILATION@"; +} +} diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.hpp b/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.hpp new file mode 100644 index 0000000..0437273 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/b_mc.hpp @@ -0,0 +1,9 @@ +#ifndef B_MC_HPP +#define B_MC_HPP + +namespace b_mc { + +extern char const* mocs_compilation(); +} + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.cpp b/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.cpp new file mode 100644 index 0000000..f72f6ca --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.cpp @@ -0,0 +1,28 @@ + +#include "b_qt.hpp" +#include + +namespace b_qt { + +/// @brief A source local QObject based class +class Source_QObject : public QObject +{ + Q_OBJECT +public: + Source_QObject() {} + ~Source_QObject() {} + + std::string str; +}; + +std::string mocs_compilation() +{ + // Create and destroy QObject based classes + Header_QObject header_obj; + Source_QObject source_obj; + + return std::string(b_mc::mocs_compilation()); +} +} + +#include "b_qt.moc" diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.hpp b/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.hpp new file mode 100644 index 0000000..d7f0311 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/b_qt.hpp @@ -0,0 +1,25 @@ +#ifndef B_QT_HPP +#define B_QT_HPP + +#include +#include +#include + +namespace b_qt { + +/// @brief A header local QObject based class +class Header_QObject : public QObject +{ + Q_OBJECT +public: + Header_QObject() {} + ~Header_QObject() {} + + std::string str; +}; + +/// @brief Function that returns the content of mocs_compilation.cpp +extern std::string mocs_compilation(); +} + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/config.hpp.in b/Tests/QtAutogen/AutogenOriginDependsOff/config.hpp.in new file mode 100644 index 0000000..e415d08 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/config.hpp.in @@ -0,0 +1,8 @@ +#ifndef CONFIG_HPP +#define CONFIG_HPP + +// Application configuration + +enum dummy { NO_OP }; + +#endif diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/configure_content.cmake b/Tests/QtAutogen/AutogenOriginDependsOff/configure_content.cmake new file mode 100644 index 0000000..0fc6e63 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/configure_content.cmake @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.10) + +# Read mocs_compilation.cpp file into variable +file(READ "${MCF}" MOCS_COMPILATION) +string(REPLACE "\\" "\\\\" MOCS_COMPILATION "${MOCS_COMPILATION}" ) +string(REPLACE "\"" "\\\"" MOCS_COMPILATION "${MOCS_COMPILATION}" ) +string(REPLACE "\n" "\"\n\"" MOCS_COMPILATION "${MOCS_COMPILATION}" ) + +# Configure file +configure_file ( "${CF_IN}" "${CF_OUT}" @ONLY ) diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/main.cpp b/Tests/QtAutogen/AutogenOriginDependsOff/main.cpp new file mode 100644 index 0000000..a3425f1 --- /dev/null +++ b/Tests/QtAutogen/AutogenOriginDependsOff/main.cpp @@ -0,0 +1,15 @@ + +#include +#include +#include + +int main() +{ + if (a_qt::mocs_compilation().empty()) { + return -1; + } + if (b_qt::mocs_compilation().empty()) { + return -1; + } + return 0; +} diff --git a/Tests/QtAutogen/CommonTests.cmake b/Tests/QtAutogen/CommonTests.cmake index 01ed7e9..46d56cb 100644 --- a/Tests/QtAutogen/CommonTests.cmake +++ b/Tests/QtAutogen/CommonTests.cmake @@ -15,6 +15,7 @@ ADD_AUTOGEN_TEST(RccSkipSource) if(QT_TEST_VERSION GREATER 4) ADD_AUTOGEN_TEST(MocMacroName mocMacroName) endif() +ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff) ADD_AUTOGEN_TEST(MocDepends) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f74c406501e5ffb5b6a3c8b76c831ca87e8f0168 commit f74c406501e5ffb5b6a3c8b76c831ca87e8f0168 Author: Sebastian Holtermann AuthorDate: Wed Oct 24 11:42:58 2018 +0200 Commit: Sebastian Holtermann CommitDate: Sat Nov 3 12:14:40 2018 +0100 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS release notes diff --git a/Help/release/dev/autogen-origin-depends.rst b/Help/release/dev/autogen-origin-depends.rst new file mode 100644 index 0000000..7310487 --- /dev/null +++ b/Help/release/dev/autogen-origin-depends.rst @@ -0,0 +1,7 @@ +autogen-origin-depends +---------------------- + +* A new :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` variable and + :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property may be set to enable or + disable forwarding of the origin target dependencies to the corresponding + ``_autogen`` target. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0669de5d36b853fa7ff81081de719a0a48e2b654 commit 0669de5d36b853fa7ff81081de719a0a48e2b654 Author: Sebastian Holtermann AuthorDate: Wed Oct 24 11:03:51 2018 +0200 Commit: Sebastian Holtermann CommitDate: Sat Nov 3 12:14:40 2018 +0100 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS documentation diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 1651114..047859d 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -124,6 +124,7 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG /prop_tgt/ARCHIVE_OUTPUT_NAME /prop_tgt/AUTOGEN_BUILD_DIR + /prop_tgt/AUTOGEN_ORIGIN_DEPENDS /prop_tgt/AUTOGEN_PARALLEL /prop_tgt/AUTOGEN_TARGET_DEPENDS /prop_tgt/AUTOMOC_COMPILER_PREDEFINES diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index b88c661..9b12fc5 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -309,6 +309,7 @@ Variables that Control the Build /variable/CMAKE_ANDROID_STL_TYPE /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG + /variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS /variable/CMAKE_AUTOGEN_PARALLEL /variable/CMAKE_AUTOGEN_VERBOSE /variable/CMAKE_AUTOMOC diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst new file mode 100644 index 0000000..f61089a --- /dev/null +++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst @@ -0,0 +1,26 @@ +AUTOGEN_ORIGIN_DEPENDS +---------------------- + +Switch for forwarding origin target dependencies to the corresponding +``_autogen`` target. + +Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property +``ON`` have a corresponding ``_autogen`` target which is used to auto generate +``moc`` and ``uic`` files. As this ``_autogen`` target is created at +generate-time, it is not possible to define dependencies of it, +such as to create inputs for the ``moc`` or ``uic`` executable. + +The dependencies of the ``_autogen`` target are composed from + +- the origin target dependencies + (by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) +- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` + +:prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` decides whether the origin target +dependencies should be forwarded to the ``_autogen`` target or not. + +By default :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` is initialized from +:variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index 7d3dfd1..84c2bfe 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst @@ -9,9 +9,15 @@ Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property generate-time, it is not possible to define dependencies of it, such as to create inputs for the ``moc`` or ``uic`` executable. -The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set instead to a -list of dependencies of the ``_autogen`` target. Dependencies can be target -names or file names. +The dependencies of the ``_autogen`` target are composed from + +- the origin target dependencies + (by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) +- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` + +The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set to a +list of additional dependencies for the ``_autogen`` target. Dependencies +can be target names or file names. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst new file mode 100644 index 0000000..1398e78 --- /dev/null +++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst @@ -0,0 +1,11 @@ +CMAKE_AUTOGEN_ORIGIN_DEPENDS +---------------------------- + +Switch for forwarding origin target dependencies to the corresponding +``_autogen`` targets. + +This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` +property on all the targets. See that target property for additional +information. + +By default :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` is ``ON``. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b5e895b5d41dc688bf0acdec352cbccc178a7236 commit b5e895b5d41dc688bf0acdec352cbccc178a7236 Author: Sebastian Holtermann AuthorDate: Wed Oct 24 11:22:50 2018 +0200 Commit: Sebastian Holtermann CommitDate: Sat Nov 3 12:14:40 2018 +0100 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS support This adds - the variable ``CMAKE_AUTOGEN_ORIGIN_DEPENDS`` which initializes - the target property ``AUTOGEN_ORIGIN_DEPENDS`` which controls whether or not the origin target dependencies should be forwarded to the corresponding ``_autogen`` target. The default value of ``CMAKE_AUTOGEN_ORIGIN_DEPENDS`` is ``ON`` which corresponds to the behavior that is in place since CMake 3.9. Closes: #18493 diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 02cb464..ddfc7bd 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -23,6 +23,8 @@ set(CMAKE_DL_LIBS "dl") set(CMAKE_FIND_LIBRARY_PREFIXES "lib") set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") + +set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE") diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 7700767..a213c84 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -322,6 +322,9 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Autogen target: Compute user defined dependencies { + this->AutogenTarget.DependOrigin = + this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS"); + std::string const deps = this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS"); if (!deps.empty()) { @@ -904,7 +907,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // Add link library target dependencies to the autogen target // dependencies - { + if (this->AutogenTarget.DependOrigin) { // add_dependencies/addUtility do not support generator expressions. // We depend only on the libraries found in all configs therefore. std::map commonTargets; @@ -941,8 +944,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() new cmGeneratorTarget(autogenTarget, localGen)); // Forward origin utilities to autogen target - for (BT const& depName : this->Target->GetUtilities()) { - autogenTarget->AddUtility(depName.Value, makefile); + if (this->AutogenTarget.DependOrigin) { + for (BT const& depName : this->Target->GetUtilities()) { + autogenTarget->AddUtility(depName.Value, makefile); + } } // Add additional autogen target dependencies to autogen target for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index ce00e00..1d3947b 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -107,6 +107,7 @@ private: std::string SettingsFile; std::map ConfigSettingsFile; // Dependencies + bool DependOrigin = false; std::set DependFiles; std::set DependTargets; // Sources to process diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 987bdb3..5d76a02 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -239,6 +239,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("AUTOMOC", nullptr); this->SetPropertyDefault("AUTOUIC", nullptr); this->SetPropertyDefault("AUTORCC", nullptr); + this->SetPropertyDefault("AUTOGEN_ORIGIN_DEPENDS", nullptr); this->SetPropertyDefault("AUTOGEN_PARALLEL", nullptr); this->SetPropertyDefault("AUTOMOC_COMPILER_PREDEFINES", nullptr); this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", nullptr); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7413f29fe63296cf34176c5fc68c2c5354b43202 commit 7413f29fe63296cf34176c5fc68c2c5354b43202 Author: Ben Boeckel AuthorDate: Wed Oct 31 15:06:45 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:23:38 2018 -0400 Tests/FindPostgreSQL: add a test for FindPostgreSQL diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index c7cfa86..f74defb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1461,6 +1461,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindPatch) endif() + if(CMake_TEST_FindPostgreSQL) + add_subdirectory(FindPostgreSQL) + endif() + if(CMake_TEST_FindProtobuf) add_subdirectory(FindProtobuf) endif() diff --git a/Tests/FindPostgreSQL/CMakeLists.txt b/Tests/FindPostgreSQL/CMakeLists.txt new file mode 100644 index 0000000..50151ee --- /dev/null +++ b/Tests/FindPostgreSQL/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindPostgreSQL.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPostgreSQL/Test" + "${CMake_BINARY_DIR}/Tests/FindPostgreSQL/Test" + ${build_generator_args} + --build-project TestFindPostgreSQL + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) diff --git a/Tests/FindPostgreSQL/Test/CMakeLists.txt b/Tests/FindPostgreSQL/Test/CMakeLists.txt new file mode 100644 index 0000000..374e147 --- /dev/null +++ b/Tests/FindPostgreSQL/Test/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.10) +project(TestFindPostgreSQL C) +include(CTest) + +find_package(PostgreSQL REQUIRED) + +add_definitions(-DCMAKE_EXPECTED_POSTGRESQL_VERSION="${PostgreSQL_VERSION_STRING}") + +add_executable(test_tgt main.c) +target_link_libraries(test_tgt PostgreSQL::PostgreSQL) +add_test(NAME test_tgt COMMAND test_tgt) + +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${PostgreSQL_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${PostgreSQL_LIBRARIES}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindPostgreSQL/Test/main.c b/Tests/FindPostgreSQL/Test/main.c new file mode 100644 index 0000000..2cfeed0 --- /dev/null +++ b/Tests/FindPostgreSQL/Test/main.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int main() +{ + int version = PQlibVersion(); + int major = version / 10000; + int minor = version % 10000; + char version_string[100]; + snprintf(version_string, sizeof(version_string), "%d.%d", major, minor); + printf("Found PostgreSQL version %s, expected version %s\n", version_string, + CMAKE_EXPECTED_POSTGRESQL_VERSION); + return strcmp(version_string, CMAKE_EXPECTED_POSTGRESQL_VERSION); +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d2235fd2538eca934f542ff82f21249c3ff314be commit d2235fd2538eca934f542ff82f21249c3ff314be Author: Ben Boeckel AuthorDate: Wed Oct 31 14:36:27 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:23:33 2018 -0400 FindPostgreSQL: add an imported target diff --git a/Help/release/dev/FindPostgreSQL-target.rst b/Help/release/dev/FindPostgreSQL-target.rst new file mode 100644 index 0000000..84f8d1a --- /dev/null +++ b/Help/release/dev/FindPostgreSQL-target.rst @@ -0,0 +1,4 @@ +FindPostgreSQL-target +--------------------- + +* The :module:`FindPostgreSQL` module now provides an imported target. diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake index d59ba50..6832bbe 100644 --- a/Modules/FindPostgreSQL.cmake +++ b/Modules/FindPostgreSQL.cmake @@ -7,6 +7,12 @@ FindPostgreSQL Find the PostgreSQL installation. +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``PostgreSQL::PostgreSQL`` +if PostgreSQL has been found. + Result Variables ^^^^^^^^^^^^^^^^ @@ -56,6 +62,8 @@ This module will set the following variables in your project: # PostgreSQL_LIBRARY_DIRS - Link directories for PostgreSQL libraries # PostgreSQL_LIBRARIES - The PostgreSQL libraries. # +# The ``PostgreSQL::PostgreSQL`` imported target is also created. +# # ---------------------------------------------------------------------------- # If you have installed PostgreSQL in a non-standard location. # (Please note that in the following comments, it is assumed that @@ -187,6 +195,12 @@ set(PostgreSQL_FOUND ${POSTGRESQL_FOUND}) # Now try to get the include and library path. if(PostgreSQL_FOUND) + if (NOT TARGET PostgreSQL::PostgreSQL) + add_library(PostgreSQL::PostgreSQL UNKNOWN IMPORTED) + set_target_properties(PostgreSQL::PostgreSQL PROPERTIES + IMPORTED_LOCATION "${PostgreSQL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${PostgreSQL_INCLUDE_DIR};${PostgreSQL_TYPE_INCLUDE_DIR}") + endif () set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR} ${PostgreSQL_TYPE_INCLUDE_DIR} ) set(PostgreSQL_LIBRARY_DIRS ${PostgreSQL_LIBRARY_DIR} ) set(PostgreSQL_LIBRARIES ${PostgreSQL_LIBRARY}) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7a801b7dfb38c2f9f77fbda0f45ed88b70ca4b87 commit 7a801b7dfb38c2f9f77fbda0f45ed88b70ca4b87 Author: Brad King AuthorDate: Thu Nov 1 13:21:45 2018 -0400 Commit: Brad King CommitDate: Thu Nov 1 13:22:01 2018 -0400 FindPostgreSQL: Modernize documentation layout diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake index 77fa4ed..d59ba50 100644 --- a/Modules/FindPostgreSQL.cmake +++ b/Modules/FindPostgreSQL.cmake @@ -7,14 +7,21 @@ FindPostgreSQL Find the PostgreSQL installation. -This module defines - -:: - - PostgreSQL_LIBRARIES - the PostgreSQL libraries needed for linking - PostgreSQL_INCLUDE_DIRS - the directories of the PostgreSQL headers - PostgreSQL_LIBRARY_DIRS - the link directories for PostgreSQL libraries - PostgreSQL_VERSION_STRING - the version of PostgreSQL found (since CMake 2.8.8) +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``PostgreSQL_FOUND`` + True if PostgreSQL is found. +``PostgreSQL_LIBRARIES`` + the PostgreSQL libraries needed for linking +``PostgreSQL_INCLUDE_DIRS`` + the directories of the PostgreSQL headers +``PostgreSQL_LIBRARY_DIRS`` + the link directories for PostgreSQL libraries +``PostgreSQL_VERSION_STRING`` + the version of PostgreSQL found #]=======================================================================] # ---------------------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-properties.7.rst | 1 + Help/manual/cmake-qt.7.rst | 38 +++++++----- Help/manual/cmake-variables.7.rst | 1 + Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst | 26 ++++++++ Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst | 12 +++- Help/prop_tgt/AUTOMOC.rst | 4 +- Help/prop_tgt/AUTORCC.rst | 2 +- Help/prop_tgt/AUTOUIC.rst | 2 +- Help/release/dev/FindPostgreSQL-target.rst | 4 ++ Help/release/dev/autogen-origin-depends.rst | 7 +++ Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst | 11 ++++ Modules/CMakeGenericSystem.cmake | 2 + Modules/FindPostgreSQL.cmake | 63 +++++++++++++++---- Source/cmQtAutoGenInitializer.cxx | 11 +++- Source/cmQtAutoGenInitializer.h | 1 + Source/cmTarget.cxx | 1 + Tests/CMakeLists.txt | 4 ++ Tests/FindPostgreSQL/CMakeLists.txt | 10 +++ Tests/FindPostgreSQL/Test/CMakeLists.txt | 16 +++++ Tests/FindPostgreSQL/Test/main.c | 15 +++++ .../AutogenOriginDependsOff/CMakeLists.txt | 71 ++++++++++++++++++++++ .../QtAutogen/AutogenOriginDependsOff/a_mc.hpp.in | 9 +++ Tests/QtAutogen/AutogenOriginDependsOff/a_qt.cpp | 28 +++++++++ Tests/QtAutogen/AutogenOriginDependsOff/a_qt.hpp | 25 ++++++++ .../QtAutogen/AutogenOriginDependsOff/b_mc.cpp.in | 9 +++ Tests/QtAutogen/AutogenOriginDependsOff/b_mc.hpp | 9 +++ Tests/QtAutogen/AutogenOriginDependsOff/b_qt.cpp | 28 +++++++++ Tests/QtAutogen/AutogenOriginDependsOff/b_qt.hpp | 25 ++++++++ .../AutogenOriginDependsOff/config.hpp.in | 8 +++ .../configure_content.cmake | 10 +++ Tests/QtAutogen/AutogenOriginDependsOff/main.cpp | 15 +++++ .../CMakeLists.txt | 50 +-------------- .../object_invalid.hpp.in | 0 .../object_valid.hpp.in | 0 .../simpleLib.cpp.in | 0 .../simpleLib.hpp.in | 0 .../testGenFile.cpp | 0 .../testGenLib.cpp | 0 .../testGenLib.hpp | 0 .../testGenTarget.cpp | 0 .../QtAutogen/AutogenTargetDepends/CMakeLists.txt | 54 ++++++++++++++++ .../object_invalid.hpp.in | 0 .../object_valid.hpp.in | 0 .../testATDFile.cpp | 0 .../testATDTarget.cpp | 0 Tests/QtAutogen/CommonTests.cmake | 4 +- 46 files changed, 490 insertions(+), 86 deletions(-) create mode 100644 Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst create mode 100644 Help/release/dev/FindPostgreSQL-target.rst create mode 100644 Help/release/dev/autogen-origin-depends.rst create mode 100644 Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst create mode 100644 Tests/FindPostgreSQL/CMakeLists.txt create mode 100644 Tests/FindPostgreSQL/Test/CMakeLists.txt create mode 100644 Tests/FindPostgreSQL/Test/main.c create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/a_mc.hpp.in create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/a_qt.cpp create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/a_qt.hpp create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/b_mc.cpp.in create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/b_mc.hpp create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/b_qt.cpp create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/b_qt.hpp create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/config.hpp.in create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/configure_content.cmake create mode 100644 Tests/QtAutogen/AutogenOriginDependsOff/main.cpp rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/CMakeLists.txt (64%) copy Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/object_invalid.hpp.in (100%) copy Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/object_valid.hpp.in (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/simpleLib.cpp.in (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/simpleLib.hpp.in (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/testGenFile.cpp (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/testGenLib.cpp (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/testGenLib.hpp (100%) rename Tests/QtAutogen/{MocDepends => AutogenOriginDependsOn}/testGenTarget.cpp (100%) create mode 100644 Tests/QtAutogen/AutogenTargetDepends/CMakeLists.txt rename Tests/QtAutogen/{MocDepends => AutogenTargetDepends}/object_invalid.hpp.in (100%) rename Tests/QtAutogen/{MocDepends => AutogenTargetDepends}/object_valid.hpp.in (100%) rename Tests/QtAutogen/{MocDepends => AutogenTargetDepends}/testATDFile.cpp (100%) rename Tests/QtAutogen/{MocDepends => AutogenTargetDepends}/testATDTarget.cpp (100%) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 11:43:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 11:43:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-45-g77f8393 Message-ID: <20181106164304.A82D912590C@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 77f8393afed1d8a051ca7b7d67e0979ec9038442 (commit) via 47255060e7788123901012586f0c51c26bd849b6 (commit) via 1e08b625c291e0bb57d253b6656e812dc8848bd8 (commit) via fe997d80e0eaa154910797ee2612d9f05e003cf6 (commit) via f1a3e4eca8310e8357a1fe0c0bfe75021952b874 (commit) via 970b18e9a5dca2c5bb6d1ecc79f3f9d1c727d641 (commit) via 20d5e77a270639a124fea587bb68b2fb6a5356fc (commit) from 36280e6157e883fb5257f211d24582b5e7ff4244 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Help/cpack_gen/external.rst | 18 ++++---- Help/release/3.13.rst | 3 ++ Modules/FindBLAS.cmake | 2 +- Modules/FindBoost.cmake | 49 +++++++++++++--------- Modules/FindLAPACK.cmake | 4 +- .../CPack/{CPackExt.cmake => CPackExternal.cmake} | 22 +++++----- Source/CMakeLists.txt | 2 +- ...tGenerator.cxx => cmCPackExternalGenerator.cxx} | 45 ++++++++++---------- ...ckExtGenerator.h => cmCPackExternalGenerator.h} | 25 +++++------ Source/CPack/cmCPackGeneratorFactory.cxx | 8 ++-- Tests/RunCMake/CMakeLists.txt | 2 +- Tests/RunCMake/CPack/Ext/Prerequirements.cmake | 0 .../RunCMake/CPack/{Ext => External}/Helpers.cmake | 0 .../CPack/External/Prerequirements.cmake} | 0 Tests/RunCMake/CPack/RunCMakeTest.cmake | 6 +-- Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake | 3 -- .../RunCMake/CPack/tests/EXT/bad_major-stderr.txt | 6 --- .../RunCMake/CPack/tests/EXT/bad_minor-stderr.txt | 6 --- .../CPack/tests/EXT/invalid_bad-stderr.txt | 6 --- .../tests/{EXT => EXTERNAL}/ExpectedFiles.cmake | 0 .../CPack/tests/EXTERNAL/VerifyResult.cmake | 3 ++ .../CPack/tests/EXTERNAL/bad_major-stderr.txt | 6 +++ .../CPack/tests/EXTERNAL/bad_minor-stderr.txt | 6 +++ .../tests/{EXT => EXTERNAL}/create_package.cmake | 0 .../tests/{EXT => EXTERNAL}/expected-json-1.0.txt | 8 ++-- .../CPack/tests/EXTERNAL/invalid_bad-stderr.txt | 6 +++ .../{EXT => EXTERNAL}/stage_and_package-stderr.txt | 0 .../CPack/tests/{EXT => EXTERNAL}/test.cmake | 18 ++++---- 28 files changed, 135 insertions(+), 119 deletions(-) rename Modules/Internal/CPack/{CPackExt.cmake => CPackExternal.cmake} (58%) rename Source/CPack/{cmCPackExtGenerator.cxx => cmCPackExternalGenerator.cxx} (85%) rename Source/CPack/{cmCPackExtGenerator.h => cmCPackExternalGenerator.h} (75%) delete mode 100644 Tests/RunCMake/CPack/Ext/Prerequirements.cmake rename Tests/RunCMake/CPack/{Ext => External}/Helpers.cmake (100%) copy Tests/{Wrapping/vtkIncluded.cxx => RunCMake/CPack/External/Prerequirements.cmake} (100%) delete mode 100644 Tests/RunCMake/CPack/tests/EXT/VerifyResult.cmake delete mode 100644 Tests/RunCMake/CPack/tests/EXT/bad_major-stderr.txt delete mode 100644 Tests/RunCMake/CPack/tests/EXT/bad_minor-stderr.txt delete mode 100644 Tests/RunCMake/CPack/tests/EXT/invalid_bad-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/ExpectedFiles.cmake (100%) create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/VerifyResult.cmake create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/bad_major-stderr.txt create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/bad_minor-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/create_package.cmake (100%) rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/expected-json-1.0.txt (90%) create mode 100644 Tests/RunCMake/CPack/tests/EXTERNAL/invalid_bad-stderr.txt rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/stage_and_package-stderr.txt (100%) rename Tests/RunCMake/CPack/tests/{EXT => EXTERNAL}/test.cmake (82%) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 13:43:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 13:43:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-364-g437ce22 Message-ID: <20181106184304.3BA541257B6@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 437ce227d927d06b19d59ed2242d78035e61940a (commit) via 242c14ddbd7804531ab8720aa818cacc67bcb4ed (commit) via 263d28b2566facd87fe72dd40fc869fc09ca4172 (commit) via 12deb051b368afcec39f58f9e3beb1c702051e74 (commit) from bfdd1ba604a31b3bb9f0baa29ce6fce467ee2e47 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=437ce227d927d06b19d59ed2242d78035e61940a commit 437ce227d927d06b19d59ed2242d78035e61940a Merge: 242c14d 263d28b Author: Brad King AuthorDate: Tue Nov 6 13:33:40 2018 -0500 Commit: Brad King CommitDate: Tue Nov 6 13:33:40 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=242c14ddbd7804531ab8720aa818cacc67bcb4ed commit 242c14ddbd7804531ab8720aa818cacc67bcb4ed Merge: bfdd1ba 12deb05 Author: Brad King AuthorDate: Tue Nov 6 18:33:11 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 13:33:21 2018 -0500 Merge topic 'cpack-doc-gen-names' 12deb051b3 Help: Use correct CPack generator names Acked-by: Kitware Robot Merge-request: !2563 ----------------------------------------------------------------------- Summary of changes: Help/cpack_gen/deb.rst | 24 ++++++++++++------------ Help/cpack_gen/dmg.rst | 6 +++--- Help/cpack_gen/freebsd.rst | 2 +- Help/cpack_gen/wix.rst | 16 ++++++++-------- Help/module/CPackDMG.rst | 2 +- Help/module/CPackDeb.rst | 2 +- Help/module/CPackWIX.rst | 2 +- Help/release/3.1.rst | 4 ++-- Help/release/3.10.rst | 8 ++++---- Help/release/3.13.rst | 4 ++-- Help/release/3.3.rst | 4 ++-- Help/release/3.4.rst | 6 +++--- Help/release/3.5.rst | 8 ++++---- Help/release/3.6.rst | 16 ++++++++-------- Help/release/3.7.rst | 10 +++++----- Help/release/3.9.rst | 4 ++-- 16 files changed, 59 insertions(+), 59 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 13:43:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 13:43:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-47-g263d28b Message-ID: <20181106184304.5440812590C@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 263d28b2566facd87fe72dd40fc869fc09ca4172 (commit) via 12deb051b368afcec39f58f9e3beb1c702051e74 (commit) from 77f8393afed1d8a051ca7b7d67e0979ec9038442 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Help/cpack_gen/deb.rst | 24 ++++++++++++------------ Help/cpack_gen/dmg.rst | 6 +++--- Help/cpack_gen/freebsd.rst | 2 +- Help/cpack_gen/wix.rst | 16 ++++++++-------- Help/module/CPackDMG.rst | 2 +- Help/module/CPackDeb.rst | 2 +- Help/module/CPackWIX.rst | 2 +- Help/release/3.1.rst | 4 ++-- Help/release/3.10.rst | 8 ++++---- Help/release/3.13.rst | 4 ++-- Help/release/3.3.rst | 4 ++-- Help/release/3.4.rst | 6 +++--- Help/release/3.5.rst | 8 ++++---- Help/release/3.6.rst | 16 ++++++++-------- Help/release/3.7.rst | 10 +++++----- Help/release/3.9.rst | 4 ++-- 16 files changed, 59 insertions(+), 59 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 6 15:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 6 Nov 2018 15:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-366-gc46dfb2 Message-ID: <20181106200304.8E3131266FC@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via c46dfb213997fa9ca26bdb691a2487a85b852720 (commit) via 2a98a0af46b8666eaaeda90f97810b20f7de3844 (commit) from 437ce227d927d06b19d59ed2242d78035e61940a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c46dfb213997fa9ca26bdb691a2487a85b852720 commit c46dfb213997fa9ca26bdb691a2487a85b852720 Merge: 437ce22 2a98a0a Author: Brad King AuthorDate: Tue Nov 6 20:02:02 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 6 15:02:08 2018 -0500 Merge topic 'xref2' 2a98a0af46 Help: Link to cmake.org "Get Involved" page from cmake-developer(7) Acked-by: Kitware Robot Merge-request: !2537 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2a98a0af46b8666eaaeda90f97810b20f7de3844 commit 2a98a0af46b8666eaaeda90f97810b20f7de3844 Author: Joachim Wuttke (h) AuthorDate: Sat Oct 27 11:56:07 2018 +0200 Commit: Brad King CommitDate: Tue Nov 6 14:24:43 2018 -0500 Help: Link to cmake.org "Get Involved" page from cmake-developer(7) diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index f05c4b1..c3bbf28 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -13,6 +13,9 @@ Introduction This manual is intended for reference by developers modifying the CMake source tree itself, and by those authoring externally-maintained modules. +See https://cmake.org/get-involved/ to get involved in development of +CMake upstream. + Adding Compile Features ======================= ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-developer.7.rst | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 00:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 00:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-367-gdf54255 Message-ID: <20181107050304.B3F64126D4D@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via df542558c645f9a704fb5bcc2b2e304f6879ab35 (commit) from c46dfb213997fa9ca26bdb691a2487a85b852720 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=df542558c645f9a704fb5bcc2b2e304f6879ab35 commit df542558c645f9a704fb5bcc2b2e304f6879ab35 Author: Kitware Robot AuthorDate: Wed Nov 7 00:01:09 2018 -0500 Commit: Kitware Robot CommitDate: Wed Nov 7 00:01:09 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 7918d80..ad29c57 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 13) -set(CMake_VERSION_PATCH 20181106) +set(CMake_VERSION_PATCH 20181107) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 07:33:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 07:33:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-391-g7e6b787 Message-ID: <20181107123306.DBCB61272E2@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 7e6b78759904dcf31d780a6e2f14f3821f4f23df (commit) via cf78a7df952a8d7be4228cb1c4a4b38ebc63dae8 (commit) via bb8da283ce40d3bb06df348ea2820dd12213a2e1 (commit) via 389002de96fdabd05b709415712b1d8d8aa264b9 (commit) via fe40570608f43aade8f4262e9ca55d98a2b169fd (commit) via c67ab22cdc680f6322e558b4f2c7cc74b6dbe163 (commit) via 86c07b916557ac83cd77f6250d090fa45b4b9bc2 (commit) via ab1d7df7575503c8eabdf6f8892b5944b06d98e5 (commit) via e0f0f80f0286b7181b1203693799f5fcfcd8b4af (commit) via 2b2b41f038af97b7bca2213cda0198d2a28f6c2e (commit) via e045fb202ddf9100965ac418f4aa22e65256dd8d (commit) via 3fa0a03b7e4094bef1b66e48ed437e1c0b41c49a (commit) via fb423b3c49d21df851b1d4a91fddfe94d835155b (commit) via 867c9c9c0dc2782b2d822557c8dc83c451409b48 (commit) via a85e5e6f4d53dd158392dd74b9632d84fb583722 (commit) via ff1db47728a37a7775a3b870ff9ffdc3249c3d40 (commit) via fe8acf7c0540ca39300bab5b014e428e84077c7a (commit) via 9891adf74becfa95463f6928fda9f8ac17c934bd (commit) via 20b6561e78f5acceecae7c6fc330f7f7de4f2223 (commit) via 873e59c0c456c2e13e66019c15f3632d06dac0f6 (commit) via b2a798fe32ce25e5ea19f6487ce9cadf9852ea83 (commit) via db749f404c29bc91a06f2ea2fb23d8a30c526a9a (commit) via 53a5aec89998a58dff53946b47426ea692c5ad8d (commit) via f92f93467ecc22419c981f8f5283c81fa9d8eb01 (commit) from df542558c645f9a704fb5bcc2b2e304f6879ab35 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7e6b78759904dcf31d780a6e2f14f3821f4f23df commit 7e6b78759904dcf31d780a6e2f14f3821f4f23df Merge: cf78a7d c67ab22 Author: Brad King AuthorDate: Wed Nov 7 12:30:12 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 7 07:30:20 2018 -0500 Merge topic 'string_func_usage' c67ab22cdc Using front() and back() instead of calculations Acked-by: Kitware Robot Merge-request: !2571 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cf78a7df952a8d7be4228cb1c4a4b38ebc63dae8 commit cf78a7df952a8d7be4228cb1c4a4b38ebc63dae8 Merge: bb8da28 53a5aec Author: Brad King AuthorDate: Wed Nov 7 12:27:49 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 7 07:28:02 2018 -0500 Merge topic 'fix-double-warn-uninitialized-in-script-mode' 53a5aec899 CMP0053: Fix double warning on uninitialized variables in -P mode f92f93467e cmMakefile: Rename SuppressWatches to SuppressSideEffects Acked-by: Kitware Robot Merge-request: !2565 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bb8da283ce40d3bb06df348ea2820dd12213a2e1 commit bb8da283ce40d3bb06df348ea2820dd12213a2e1 Merge: 389002d 86c07b9 Author: Brad King AuthorDate: Wed Nov 7 12:26:54 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 7 07:27:27 2018 -0500 Merge topic 'genex' 86c07b9165 Help: Say early on that generator expressions can be nested. ab1d7df757 Help: add section on debugging generator expressions. e0f0f80f02 Help: Explain conversion rules of $. 2b2b41f038 Help: Code example for case-insensitive comparison e045fb202d Help: Terminate explanations with a dot. 3fa0a03b7e Help: Expand placeholders in string comparisons. fb423b3c49 Help: sort conditional expressions below string-valued ones. 867c9c9c0d Help: Add deprecation date of $ ... Acked-by: Kitware Robot Acked-by: Alex Turbov Merge-request: !2564 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=389002de96fdabd05b709415712b1d8d8aa264b9 commit 389002de96fdabd05b709415712b1d8d8aa264b9 Merge: df54255 fe40570 Author: Brad King AuthorDate: Wed Nov 7 12:26:35 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 7 07:26:46 2018 -0500 Merge topic 'FindSQLite3-module' fe40570608 FindSQLite3: Add module to find SQLite3 Acked-by: Kitware Robot Merge-request: !2557 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fe40570608f43aade8f4262e9ca55d98a2b169fd commit fe40570608f43aade8f4262e9ca55d98a2b169fd Author: Chuck Atkins AuthorDate: Thu Nov 1 16:48:56 2018 -0400 Commit: Brad King CommitDate: Tue Nov 6 15:05:04 2018 -0500 FindSQLite3: Add module to find SQLite3 diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index c0bef08..95744df 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -237,6 +237,7 @@ They are normally called through the :command:`find_package` command. /module/FindSDL_ttf /module/FindSelfPackers /module/FindSquish + /module/FindSQLite3 /module/FindSubversion /module/FindSWIG /module/FindTCL diff --git a/Help/module/FindSQLite3.rst b/Help/module/FindSQLite3.rst new file mode 100644 index 0000000..d1910e5 --- /dev/null +++ b/Help/module/FindSQLite3.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindSQLite3.cmake diff --git a/Help/release/dev/FindSQLite3-module.rst b/Help/release/dev/FindSQLite3-module.rst new file mode 100644 index 0000000..733a4d3 --- /dev/null +++ b/Help/release/dev/FindSQLite3-module.rst @@ -0,0 +1,4 @@ +FindSQLite3-module +------------------ + +* The :module:`FindSQLite3` module was added to find the SQLite v3.x library. diff --git a/Modules/FindSQLite3.cmake b/Modules/FindSQLite3.cmake new file mode 100644 index 0000000..374d7af --- /dev/null +++ b/Modules/FindSQLite3.cmake @@ -0,0 +1,66 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindSQLite3 +----------- + +Find the SQLite libraries, v3 + +IMPORTED targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` target: + +``SQLite::SQLite3`` + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables if found: + +``SQLite3_INCLUDE_DIRS`` + where to find sqlite3.h, etc. +``SQLite3_LIBRARIES`` + the libraries to link against to use SQLite3. +``SQLite3_VERSION`` + version of the SQLite3 library found +``SQLite3_FOUND`` + TRUE if found + +#]=======================================================================] + +# Look for the necessary header +find_path(SQLite3_INCLUDE_DIR NAMES sqlite3.h) +mark_as_advanced(SQLite3_INCLUDE_DIR) + +# Look for the necessary library +find_library(SQLite3_LIBRARY NAMES sqlite3 sqlite) +mark_as_advanced(SQLite3_LIBRARY) + +# Extract version information from the header file +if(SQLite3_INCLUDE_DIR) + file(STRINGS ${SQLite3_INCLUDE_DIR}/sqlite3.h _ver_line + REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3_VERSION "${_ver_line}") + unset(_ver_line) +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(SQLite3 + REQUIRED_VARS SQLite3_INCLUDE_DIR SQLite3_LIBRARY + VERSION_VAR SQLite3_VERSION) + +# Create the imported target +if(SQLite3_FOUND) + set(SQLite3_INCLUDE_DIRS ${SQLite3_INCLUDE_DIR}) + set(SQLite3_LIBRARIES ${SQLite3_LIBRARY}) + if(NOT TARGET SQLite::SQLite3) + add_library(SQLite::SQLite3 UNKNOWN IMPORTED) + set_target_properties(SQLite::SQLite3 PROPERTIES + IMPORTED_LOCATION "${SQLite3_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${SQLite3_INCLUDE_DIR}") + endif() +endif() diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 1c49fea..02e56eb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1469,6 +1469,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindProtobuf) endif() + if(CMake_TEST_FindSQLite3) + add_subdirectory(FindSQLite3) + endif() + if(CMake_TEST_FindTIFF) add_subdirectory(FindTIFF) endif() diff --git a/Tests/FindSQLite3/CMakeLists.txt b/Tests/FindSQLite3/CMakeLists.txt new file mode 100644 index 0000000..8bf170e --- /dev/null +++ b/Tests/FindSQLite3/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindSQLite3.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindSQLite3/Test" + "${CMake_BINARY_DIR}/Tests/FindSQLite3/Test" + ${build_generator_args} + --build-project TestFindSQLite3 + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) diff --git a/Tests/FindSQLite3/Test/CMakeLists.txt b/Tests/FindSQLite3/Test/CMakeLists.txt new file mode 100644 index 0000000..bcc6ebd --- /dev/null +++ b/Tests/FindSQLite3/Test/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.4) +project(TestFindSQLite3 C) +include(CTest) + +find_package(SQLite3 REQUIRED) + +add_definitions(-DCMAKE_EXPECTED_SQLite3_VERSION="${SQLite3_VERSION}") + +add_executable(test_tgt main.c) +target_link_libraries(test_tgt SQLite::SQLite3) +add_test(NAME test_tgt COMMAND test_tgt) + +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${SQLite3_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${SQLite3_LIBRARIES}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindSQLite3/Test/main.c b/Tests/FindSQLite3/Test/main.c new file mode 100644 index 0000000..aeb4940 --- /dev/null +++ b/Tests/FindSQLite3/Test/main.c @@ -0,0 +1,10 @@ +#include + +#include + +int main() +{ + char sqlite3_version[] = SQLITE_VERSION; + + return strcmp(sqlite3_version, CMAKE_EXPECTED_SQLite3_VERSION); +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c67ab22cdc680f6322e558b4f2c7cc74b6dbe163 commit c67ab22cdc680f6322e558b4f2c7cc74b6dbe163 Author: Cengizhan Pasaoglu AuthorDate: Tue Nov 6 09:47:40 2018 +0300 Commit: Cengizhan Pasaoglu CommitDate: Tue Nov 6 21:43:33 2018 +0300 Using front() and back() instead of calculations diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 75bd6fb..75e5aa4 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -20,7 +20,7 @@ bool cmAddSubDirectoryCommand::InitialPass( } // store the binpath - std::string const& srcArg = args[0]; + std::string const& srcArg = args.front(); std::string binArg; bool excludeFromAll = false; @@ -84,10 +84,10 @@ bool cmAddSubDirectoryCommand::InitialPass( const std::string& bin = this->Makefile->GetCurrentBinaryDirectory(); size_t srcLen = src.length(); size_t binLen = bin.length(); - if (srcLen > 0 && src[srcLen - 1] == '/') { + if (srcLen > 0 && src.back() == '/') { --srcLen; } - if (binLen > 0 && bin[binLen - 1] == '/') { + if (binLen > 0 && bin.back() == '/') { --binLen; } binPath = bin.substr(0, binLen) + srcPath.substr(srcLen); diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 6031781..3f2e784 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -178,7 +178,7 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix, bool recursive) { if (this->Okay()) { - if (!path.empty() && path[path.size() - 1] == '/') { + if (!path.empty() && path.back() == '/') { path.erase(path.size() - 1); } this->AddPath(path.c_str(), skip, prefix, recursive); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index d0d5db6..9a046db 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -727,7 +727,7 @@ bool cmCTest::UpdateCTestConfiguration() if (line.empty()) { continue; } - while (fin && (line[line.size() - 1] == '\\')) { + while (fin && (line.back() == '\\')) { line = line.substr(0, line.size() - 1); buffer[0] = 0; fin.getline(buffer, 1023); @@ -2575,7 +2575,7 @@ std::string cmCTest::GetShortPathToFile(const char* cfname) cmSystemTools::ConvertToUnixSlashes(*res); path = "./" + *res; - if (path[path.size() - 1] == '/') { + if (path.back() == '/') { path = path.substr(0, path.size() - 1); } } diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index b391dc4..0305677 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -415,8 +415,7 @@ void cmCacheManager::OutputValueNoNewlines(std::ostream& fout, std::string const& value) { // if value has trailing space or tab, enclose it in single quotes - if (!value.empty() && - (value[value.size() - 1] == ' ' || value[value.size() - 1] == '\t')) { + if (!value.empty() && (value.back() == ' ' || value.back() == '\t')) { fout << '\'' << value << '\''; } else { fout << value; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 34f58ad..87ee382 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -976,9 +976,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const lg->GetIndividualFileTargets(objectFileTargets); for (std::string const& f : objectFileTargets) { const char* prefix = "[obj] "; - if (f[f.length() - 1] == 's') { + if (f.back() == 's') { prefix = "[to asm] "; - } else if (f[f.length() - 1] == 'i') { + } else if (f.back() == 'i') { prefix = "[pre] "; } this->AppendTarget(xml, f, make, makeArgs, subdir, prefix); @@ -1035,8 +1035,7 @@ std::string cmExtraEclipseCDT4Generator::GetPathBasename( { std::string outputBasename = path; while (!outputBasename.empty() && - (outputBasename[outputBasename.size() - 1] == '/' || - outputBasename[outputBasename.size() - 1] == '\\')) { + (outputBasename.back() == '/' || outputBasename.back() == '\\')) { outputBasename.resize(outputBasename.size() - 1); } std::string::size_type loc = outputBasename.find_last_of("/\\"); diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index f5c4c93..9410690 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -294,8 +294,7 @@ std::string cmExtraKateGenerator::GetPathBasename( { std::string outputBasename = path; while (!outputBasename.empty() && - (outputBasename[outputBasename.size() - 1] == '/' || - outputBasename[outputBasename.size() - 1] == '\\')) { + (outputBasename.back() == '/' || outputBasename.back() == '\\')) { outputBasename.resize(outputBasename.size() - 1); } std::string::size_type loc = outputBasename.find_last_of("/\\"); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 1f76703..f86e5e2 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2525,7 +2525,7 @@ bool cmFileCommand::HandleCMakePathCommand( // remove double quotes in the path std::string& s = *j; - if (s.size() > 1 && s[0] == '\"' && s[s.size() - 1] == '\"') { + if (s.size() > 1 && s.front() == '\"' && s.back() == '\"') { s = s.substr(1, s.size() - 2); } } diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 865595b..425546a 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -129,13 +129,13 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) this->VariableDocumentation += "the (unknown) library be found"; } else if (this->Names.size() == 1) { this->VariableDocumentation += - "the " + this->Names[0] + " library be found"; + "the " + this->Names.front() + " library be found"; } else { this->VariableDocumentation += "one of the "; this->VariableDocumentation += cmJoin(cmMakeRange(this->Names).retreat(1), ", "); this->VariableDocumentation += - " or " + this->Names[this->Names.size() - 1] + " libraries be found"; + " or " + this->Names.back() + " libraries be found"; } } diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index fbaacfc..009f0e3 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -293,13 +293,13 @@ void cmFindCommon::AddPathSuffix(std::string const& arg) if (suffix.empty()) { return; } - if (suffix[0] == '/') { + if (suffix.front() == '/') { suffix = suffix.substr(1); } if (suffix.empty()) { return; } - if (suffix[suffix.size() - 1] == '/') { + if (suffix.back() == '/') { suffix = suffix.substr(0, suffix.size() - 1); } if (suffix.empty()) { diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 96de6ad..97c1d7d 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1429,7 +1429,7 @@ void cmFindPackageCommand::FillPrefixesUserHints() bool cmFindPackageCommand::SearchDirectory(std::string const& dir) { - assert(!dir.empty() && dir[dir.size() - 1] == '/'); + assert(!dir.empty() && dir.back() == '/'); // Check each path suffix on this directory. for (std::string const& s : this->SearchPathSuffixes) { @@ -1447,7 +1447,7 @@ bool cmFindPackageCommand::SearchDirectory(std::string const& dir) bool cmFindPackageCommand::CheckDirectory(std::string const& dir) { - assert(!dir.empty() && dir[dir.size() - 1] == '/'); + assert(!dir.empty() && dir.back() == '/'); // Look for the file in this directory. std::string d = dir.substr(0, dir.size() - 1); @@ -2001,7 +2001,7 @@ private: bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { - assert(!prefix_in.empty() && prefix_in[prefix_in.size() - 1] == '/'); + assert(!prefix_in.empty() && prefix_in.back() == '/'); if (this->DebugMode) { fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str()); } @@ -2157,7 +2157,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in) { - assert(!prefix_in.empty() && prefix_in[prefix_in.size() - 1] == '/'); + assert(!prefix_in.empty() && prefix_in.back() == '/'); if (this->DebugMode) { fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str()); } @@ -2218,7 +2218,7 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in) bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in) { - assert(!prefix_in.empty() && prefix_in[prefix_in.size() - 1] == '/'); + assert(!prefix_in.empty() && prefix_in.back() == '/'); if (this->DebugMode) { fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str()); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 71947ea..1663400 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -953,7 +953,7 @@ std::vector> cmGeneratorTarget::GetSourceFilePaths( cmSystemTools::ExpandListArgument(entry, items); for (std::string const& item : items) { if (cmHasLiteralPrefix(item, "$') { + item.back() == '>') { continue; } files.push_back(item); @@ -5612,8 +5612,7 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026( std::vector files; cmSystemTools::ExpandListArgument(entry, files); for (std::string const& li : files) { - if (cmHasLiteralPrefix(li, "$') { + if (cmHasLiteralPrefix(li, "$') { std::string objLibName = li.substr(17, li.size() - 18); if (cmGeneratorExpression::Find(objLibName) != std::string::npos) { diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 1b358ab..ffb895e 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -19,8 +19,8 @@ bool cmGetFilenameComponentCommand::InitialPass( // Check and see if the value has been stored in the cache // already, if so use that value - if (args.size() >= 4 && args[args.size() - 1] == "CACHE") { - const char* cacheValue = this->Makefile->GetDefinition(args[0]); + if (args.size() >= 4 && args.back() == "CACHE") { + const char* cacheValue = this->Makefile->GetDefinition(args.front()); if (cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) { return true; } @@ -113,20 +113,20 @@ bool cmGetFilenameComponentCommand::InitialPass( return false; } - if (args.size() >= 4 && args[args.size() - 1] == "CACHE") { + if (args.size() >= 4 && args.back() == "CACHE") { if (!programArgs.empty() && !storeArgs.empty()) { this->Makefile->AddCacheDefinition( storeArgs, programArgs.c_str(), "", args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING); } this->Makefile->AddCacheDefinition( - args[0], result.c_str(), "", + args.front(), result.c_str(), "", args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING); } else { if (!programArgs.empty() && !storeArgs.empty()) { this->Makefile->AddDefinition(storeArgs, programArgs.c_str()); } - this->Makefile->AddDefinition(args[0], result.c_str()); + this->Makefile->AddDefinition(args.front(), result.c_str()); } return true; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 71e844e..cf85473 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2265,7 +2265,7 @@ bool cmGlobalGenerator::NameResolvesToFramework( inline std::string removeQuotes(const std::string& s) { - if (s[0] == '\"' && s[s.size() - 1] == '\"') { + if (s.front() == '\"' && s.back() == '\"') { return s.substr(1, s.size() - 2); } return s; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 8c69f42..fbc756c 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -838,7 +838,7 @@ static void EnsureTrailingSlash(std::string& path) if (path.empty()) { return; } - std::string::value_type last = path[path.size() - 1]; + std::string::value_type last = path.back(); #ifdef _WIN32 if (last != '\\') { path += '\\'; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 596bc6b..b7a361e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -546,7 +546,7 @@ void cmGlobalXCodeGenerator::AddExtraTargets( target->GetType() == cmStateEnums::STATIC_LIBRARY || target->GetType() == cmStateEnums::SHARED_LIBRARY || target->GetType() == cmStateEnums::MODULE_LIBRARY))) { - makeHelper[makeHelper.size() - 1] = // fill placeholder + makeHelper.back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); cmCustomCommandLines commandLines; commandLines.push_back(makeHelper); diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index b2acb90..9b63d24 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -152,7 +152,7 @@ bool cmListCommand::HandleLengthCommand(std::vector const& args) } const std::string& listName = args[1]; - const std::string& variableName = args[args.size() - 1]; + const std::string& variableName = args.back(); std::vector varArgsExpanded; // do not check the return value here // if the list var is not found varArgsExpanded will have size 0 @@ -174,7 +174,7 @@ bool cmListCommand::HandleGetCommand(std::vector const& args) } const std::string& listName = args[1]; - const std::string& variableName = args[args.size() - 1]; + const std::string& variableName = args.back(); // expand the variable std::vector varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { @@ -243,7 +243,7 @@ bool cmListCommand::HandleFindCommand(std::vector const& args) } const std::string& listName = args[1]; - const std::string& variableName = args[args.size() - 1]; + const std::string& variableName = args.back(); // expand the variable std::vector varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { @@ -1176,7 +1176,7 @@ bool cmListCommand::HandleSublistCommand(std::vector const& args) } const std::string& listName = args[1]; - const std::string& variableName = args[args.size() - 1]; + const std::string& variableName = args.back(); // expand the variable std::vector varArgsExpanded; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index a065408..a703f4d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -807,19 +807,19 @@ std::string cmLocalGenerator::GetIncludeFlags( } std::string includePath = this->ConvertToIncludeReference(i, shellFormat, forceFullPaths); - if (quotePaths && !includePath.empty() && includePath[0] != '\"') { + if (quotePaths && !includePath.empty() && includePath.front() != '\"') { includeFlags << "\""; } includeFlags << includePath; - if (quotePaths && !includePath.empty() && includePath[0] != '\"') { + if (quotePaths && !includePath.empty() && includePath.front() != '\"') { includeFlags << "\""; } includeFlags << sep; } std::string flags = includeFlags.str(); // remove trailing separators - if ((sep[0] != ' ') && !flags.empty() && flags[flags.size() - 1] == sep[0]) { - flags[flags.size() - 1] = ' '; + if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) { + flags.back() = ' '; } return flags; } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 1da077e..7630691 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1347,7 +1347,7 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories( d != dirs.end(); ++d) { // Remove any trailing slash and skip empty paths. std::string dir = *d; - if (dir[dir.size() - 1] == '/') { + if (dir.back() == '/') { dir = dir.substr(0, dir.size() - 1); } if (dir.empty()) { diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index f423560..3c46784 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -590,7 +590,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( // mingw32-make incorrectly interprets 'a\ b c' as 'a b' and 'c' // (but 'a\ b "c"' as 'a\', 'b', and 'c'!). Workaround this by // avoiding a trailing backslash in the argument. - targetOutPathCompilePDB[targetOutPathCompilePDB.size() - 1] = '/'; + targetOutPathCompilePDB.back() = '/'; } } cmRulePlaceholderExpander::RuleVariables vars; diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 04a9318..7fd7732 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -186,7 +186,7 @@ bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir) // file name. Usually the soname starts with the library name. std::string base = this->FileName; std::set::const_iterator first = files.lower_bound(base); - ++base[base.size() - 1]; + ++base.back(); std::set::const_iterator last = files.upper_bound(base); if (first != last) { return true; diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index dbe6fa1..43a0107 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -118,11 +118,11 @@ std::string cmOutputConverter::ForceToRelativePath( std::string const& local_path, std::string const& remote_path) { // The paths should never be quoted. - assert(local_path[0] != '\"'); - assert(remote_path[0] != '\"'); + assert(local_path.front() != '\"'); + assert(remote_path.front() != '\"'); // The local path should never have a trailing slash. - assert(local_path.empty() || local_path[local_path.size() - 1] != '/'); + assert(local_path.empty() || local_path.back() != '/'); // If the path is already relative then just return the path. if (!cmSystemTools::FileIsFullPath(remote_path)) { diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index e2de3f9..87c1ec0 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -340,7 +340,7 @@ protected: } else { // try to guess which include path to use for (std::string incpath : this->IncludeDirectories) { - if (!incpath.empty() && incpath[incpath.size() - 1] != '/') { + if (!incpath.empty() && incpath.back() != '/') { incpath = incpath + "/"; } incpath = incpath + path; @@ -421,7 +421,7 @@ protected: } for (std::string path : this->IncludeDirectories) { - if (!path.empty() && path[path.size() - 1] != '/') { + if (!path.empty() && path.back() != '/') { path = path + "/"; } path = path + fname; @@ -435,7 +435,7 @@ protected: if (extraPath) { std::string path = extraPath; - if (!path.empty() && path[path.size() - 1] != '/') { + if (!path.empty() && path.back() != '/') { path = path + "/"; } path = path + fname; diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 32ad0b0..8a04c1f 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -228,8 +228,7 @@ void cmRST::ProcessLine(std::string const& line) else { this->NormalLine(line); this->LastLineEndedInColonColon = - (line.size() >= 2 && line[line.size() - 2] == ':' && - line[line.size() - 1] == ':'); + (line.size() >= 2 && line[line.size() - 2] == ':' && line.back() == ':'); } } diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index a71861a..0dfb797 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -110,7 +110,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( if (replaceValues.Target) { if (variable == "TARGET_QUOTED") { std::string targetQuoted = replaceValues.Target; - if (!targetQuoted.empty() && targetQuoted[0] != '\"') { + if (!targetQuoted.empty() && targetQuoted.front() != '\"') { targetQuoted = '\"'; targetQuoted += replaceValues.Target; targetQuoted += '\"'; @@ -120,7 +120,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( if (variable == "TARGET_UNQUOTED") { std::string unquoted = replaceValues.Target; std::string::size_type sz = unquoted.size(); - if (sz > 2 && unquoted[0] == '\"' && unquoted[sz - 1] == '\"') { + if (sz > 2 && unquoted.front() == '\"' && unquoted.back() == '\"') { unquoted = unquoted.substr(1, sz - 2); } return unquoted; diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 985aac8..1a2d1c6 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -54,7 +54,7 @@ bool cmSetCommand::InitialPass(std::vector const& args, } // SET (VAR PARENT_SCOPE) // Removes the definition of VAR // in the parent scope. - if (args.size() == 2 && args[args.size() - 1] == "PARENT_SCOPE") { + if (args.size() == 2 && args.back() == "PARENT_SCOPE") { this->Makefile->RaiseScope(variable, nullptr); return true; } @@ -74,12 +74,12 @@ bool cmSetCommand::InitialPass(std::vector const& args, unsigned int ignoreLastArgs = 0; // look for PARENT_SCOPE argument - if (args.size() > 1 && args[args.size() - 1] == "PARENT_SCOPE") { + if (args.size() > 1 && args.back() == "PARENT_SCOPE") { parentScope = true; ignoreLastArgs++; } else { // look for FORCE argument - if (args.size() > 4 && args[args.size() - 1] == "FORCE") { + if (args.size() > 4 && args.back() == "FORCE") { force = true; ignoreLastArgs++; } @@ -103,7 +103,7 @@ bool cmSetCommand::InitialPass(std::vector const& args, // we should be nice and try to catch some simple screwups if the last or // next to last args are CACHE then they screwed up. If they used FORCE // without CACHE they screwed up - if ((args[args.size() - 1] == "CACHE") || + if ((args.back() == "CACHE") || (args.size() > 1 && args[args.size() - 2] == "CACHE") || (force && !cache)) { this->SetError("given invalid arguments for CACHE mode."); diff --git a/Source/cmState.cxx b/Source/cmState.cxx index a2008a0..4bbd2e0 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -867,8 +867,8 @@ static bool ParseEntryWithoutType(const std::string& entry, std::string& var, // if value is enclosed in single quotes ('foo') then remove them // it is used to enclose trailing space or tab - if (flag && value.size() >= 2 && value[0] == '\'' && - value[value.size() - 1] == '\'') { + if (flag && value.size() >= 2 && value.front() == '\'' && + value.back() == '\'') { value = value.substr(1, value.size() - 2); } @@ -900,8 +900,8 @@ bool cmState::ParseCacheEntry(const std::string& entry, std::string& var, // if value is enclosed in single quotes ('foo') then remove them // it is used to enclose trailing space or tab - if (flag && value.size() >= 2 && value[0] == '\'' && - value[value.size() - 1] == '\'') { + if (flag && value.size() >= 2 && value.front() == '\'' && + value.back() == '\'') { value = value.substr(1, value.size() - 2); } diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 1605fd7..91d6190 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -156,7 +156,7 @@ bool cmStringCommand::HandleAsciiCommand(std::vector const& args) return false; } std::string::size_type cc; - std::string const& outvar = args[args.size() - 1]; + std::string const& outvar = args.back(); std::string output; for (cc = 1; cc < args.size() - 1; cc++) { int ch = atoi(args[cc].c_str()); @@ -755,7 +755,7 @@ bool cmStringCommand::HandleRandomCommand(std::vector const& args) this->SetError("sub-command RANDOM invoked with bad length."); return false; } - const std::string& variableName = args[args.size() - 1]; + const std::string& variableName = args.back(); std::vector result; @@ -765,8 +765,7 @@ bool cmStringCommand::HandleRandomCommand(std::vector const& args) } const char* alphaPtr = alphabet.c_str(); - int cc; - for (cc = 0; cc < length; cc++) { + for (int cc = 0; cc < length; cc++) { int idx = static_cast(sizeofAlphabet * rand() / (RAND_MAX + 1.0)); result.push_back(*(alphaPtr + idx)); } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 568ee82..9866d13 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1301,7 +1301,7 @@ bool cmSystemTools::SimpleGlob(const std::string& glob, int type /* = 0 */) { files.clear(); - if (glob[glob.size() - 1] != '*') { + if (glob.back() != '*') { return false; } std::string path = cmSystemTools::GetFilenamePath(glob); @@ -1318,7 +1318,7 @@ bool cmSystemTools::SimpleGlob(const std::string& glob, if ((std::string(d.GetFile(i)) != ".") && (std::string(d.GetFile(i)) != "..")) { std::string fname = path; - if (path[path.size() - 1] != '/') { + if (path.back() != '/') { fname += "/"; } fname += d.GetFile(i); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5d76a02..92d5505 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -87,7 +87,7 @@ const char* cmTargetPropertyComputer::GetSources( cmSystemTools::ExpandListArgument(entry, files); for (std::string const& file : files) { if (cmHasLiteralPrefix(file, "$') { + file.back() == '>') { std::string objLibName = file.substr(17, file.size() - 18); if (cmGeneratorExpression::Find(objLibName) != std::string::npos) { diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx index a9acb3f..9353276 100644 --- a/Source/cmVisualStudioSlnParser.cxx +++ b/Source/cmVisualStudioSlnParser.cxx @@ -602,8 +602,8 @@ bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag, } const std::string& arg = cmSystemTools::TrimWhitespace( fullTag.substr(idxLeftParen + 1, idxRightParen - idxLeftParen - 1)); - if (arg[0] == '"') { - if (arg[arg.size() - 1] != '"') { + if (arg.front() == '"') { + if (arg.back() != '"') { this->LastResult.SetError(ResultErrorInputStructure, state.GetCurrentLine()); return false; @@ -620,7 +620,7 @@ bool cmVisualStudioSlnParser::ParseValue(const std::string& value, const std::string& trimmed = cmSystemTools::TrimWhitespace(value); if (trimmed.empty()) parsedLine.AddValue(trimmed); - else if (trimmed[0] == '"' && trimmed[trimmed.size() - 1] == '"') + else if (trimmed.front() == '"' && trimmed.back() == '"') parsedLine.AddQuotedValue(trimmed.substr(1, trimmed.size() - 2)); else parsedLine.AddValue(trimmed); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 79af3e7..35730b8 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2129,7 +2129,7 @@ void cmake::TruncateOutputLog(const char* fname) inline std::string removeQuotes(const std::string& s) { - if (s[0] == '\"' && s[s.size() - 1] == '\"') { + if (s.front() == '\"' && s.back() == '\"') { return s.substr(1, s.size() - 2); } return s; diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx index 0c5bbe2..1a10666 100644 --- a/Source/cmcldeps.cxx +++ b/Source/cmcldeps.cxx @@ -221,7 +221,7 @@ static int process(const std::string& srcfilename, const std::string& dfile, while (std::getline(ss, line)) { if (startsWith(line, prefix)) { std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str()); - if (inc[inc.size() - 1] == '\r') // blech, stupid \r\n + if (inc.back() == '\r') // blech, stupid \r\n inc = inc.substr(0, inc.size() - 1); includes.push_back(inc); } else { diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 8a140e8..45881aa 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -468,18 +468,18 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) // If multiple source files specified, // then destination must be directory if ((args.size() > 4) && - (!cmSystemTools::FileIsDirectory(args[args.size() - 1]))) { - std::cerr << "Error: Target (for copy command) \"" - << args[args.size() - 1] << "\" is not a directory.\n"; + (!cmSystemTools::FileIsDirectory(args.back()))) { + std::cerr << "Error: Target (for copy command) \"" << args.back() + << "\" is not a directory.\n"; return 1; } // If error occurs we want to continue copying next files. bool return_value = false; for (std::string::size_type cc = 2; cc < args.size() - 1; cc++) { if (!cmSystemTools::cmCopyFile(args[cc].c_str(), - args[args.size() - 1].c_str())) { + args.back().c_str())) { std::cerr << "Error copying file \"" << args[cc] << "\" to \"" - << args[args.size() - 1] << "\".\n"; + << args.back() << "\".\n"; return_value = true; } } @@ -491,18 +491,18 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) // If multiple source files specified, // then destination must be directory if ((args.size() > 4) && - (!cmSystemTools::FileIsDirectory(args[args.size() - 1]))) { + (!cmSystemTools::FileIsDirectory(args.back()))) { std::cerr << "Error: Target (for copy_if_different command) \"" - << args[args.size() - 1] << "\" is not a directory.\n"; + << args.back() << "\" is not a directory.\n"; return 1; } // If error occurs we want to continue copying next files. bool return_value = false; for (std::string::size_type cc = 2; cc < args.size() - 1; cc++) { - if (!cmSystemTools::CopyFileIfDifferent( - args[cc].c_str(), args[args.size() - 1].c_str())) { + if (!cmSystemTools::CopyFileIfDifferent(args[cc].c_str(), + args.back().c_str())) { std::cerr << "Error copying file (if different) from \"" << args[cc] - << "\" to \"" << args[args.size() - 1] << "\".\n"; + << "\" to \"" << args.back() << "\".\n"; return_value = true; } } @@ -514,9 +514,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) // If error occurs we want to continue copying next files. bool return_value = false; for (std::string::size_type cc = 2; cc < args.size() - 1; cc++) { - if (!cmSystemTools::CopyADirectory(args[cc], args[args.size() - 1])) { + if (!cmSystemTools::CopyADirectory(args[cc], args.back())) { std::cerr << "Error copying directory from \"" << args[cc] - << "\" to \"" << args[args.size() - 1] << "\".\n"; + << "\" to \"" << args.back() << "\".\n"; return_value = true; } } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=86c07b916557ac83cd77f6250d090fa45b4b9bc2 commit 86c07b916557ac83cd77f6250d090fa45b4b9bc2 Author: Joachim Wuttke (o) AuthorDate: Tue Nov 6 12:54:32 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:25 2018 +0100 Help: Say early on that generator expressions can be nested. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index b5c4457..63e43e1 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -27,8 +27,10 @@ queryable information. Generator expressions have the form ``$<...>``. To avoid confusion, this page deviates from most of the CMake documentation in that it omits angular brackets -``<...>`` around placeholders like ``condition``, ``true_value``, ``string``, -and so on. +``<...>`` around placeholders like ``condition``, ``string``, ``target``, +among others. + +Generator expressions can be nested, as shown in most of the examples below. .. _`Boolean Generator Expressions`: https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ab1d7df7575503c8eabdf6f8892b5944b06d98e5 commit ab1d7df7575503c8eabdf6f8892b5944b06d98e5 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 23:13:21 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:25 2018 +0100 Help: add section on debugging generator expressions. This resolves #18550. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index eb9c9fe..b5c4457 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -440,3 +440,25 @@ Output-Related Expressions Content of ``...`` converted to shell path style. For example, slashes are converted to backslashes in Windows shells and drive letters are converted to posix paths in MSYS shells. The ``...`` must be an absolute path. + +Debugging +========= + +Since generator expressions are evaluated during generation of the buildsystem, +and not during processing of ``CMakeLists.txt`` files, it is not possible to +inspect their result with the :command:`message()` command. + +One possible way to generate debug messages is to add a custom target, + +.. code-block:: cmake + + add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$<...>") + +The shell command ``make genexdebug`` (invoked after execution of ``cmake``) +would then print the result of ``$<...>``. + +Another way is to write debug messages to a file: + +.. code-block:: cmake + + file(GENERATE OUTPUT filename CONTENT "$<...>") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e0f0f80f0286b7181b1203693799f5fcfcd8b4af commit e0f0f80f0286b7181b1203693799f5fcfcd8b4af Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 23:00:12 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Explain conversion rules of $. This resolves #18549. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c5d7a31..eb9c9fe 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -44,8 +44,16 @@ Available boolean expressions are: Logical Operators ----------------- -``$`` - ``1`` if the ``condition`` is true, else ``0`` +``$`` + Converts ``string`` to ``0`` or ``1`` according to the rules of the + :command:`if()` command. Evaluates to ``0`` if any of the following is true: + + * ``string`` is empty, + * ``string`` is a case-insensitive equal of + ``0``, ``FALSE``, ``OFF``, ``N``, ``NO``, ``IGNORE``, or ``NOTFOUND``, or + * ``string`` ends in the suffix ``-NOTFOUND`` (case-sensitive). + + Otherwise evaluates to ``1``. ``$`` where ``conditions`` is a comma-separated list of boolean expressions. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2b2b41f038af97b7bca2213cda0198d2a28f6c2e commit 2b2b41f038af97b7bca2213cda0198d2a28f6c2e Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 20:03:43 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Code example for case-insensitive comparison diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index bf11b05..c5d7a31 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -65,7 +65,14 @@ String Comparisons ``$`` ``1`` if ``string1`` and ``string2`` are equal, else ``0``. - The comparison is case-sensitive. + The comparison is case-sensitive. For a case-insensitive comparison, + combine with a :ref:`string transforming generator expression + `, + + .. code-block:: cmake + + $,"BAR"> # "1" if ${foo} is any of "BAR", "Bar", "bar", ... + ``$`` ``1`` if ``value1`` and ``value2`` are numerically equal, else ``0``. ``$`` @@ -254,8 +261,10 @@ Typically, the ``condition`` is a :ref:`boolean generator expression expands to ``DEBUG_MODE`` when the ``Debug`` configuration is used, and otherwise expands to the empty string. -String Operations ------------------ +.. _`String Transforming Generator Expressions`: + +String Transformations +---------------------- ``$`` Joins the list with the content of ``string``. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e045fb202ddf9100965ac418f4aa22e65256dd8d commit e045fb202ddf9100965ac418f4aa22e65256dd8d Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 19:54:20 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Terminate explanations with a dot. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 27bf7d1..bf11b05 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -58,7 +58,7 @@ Logical Operators Otherwise evaluates to ``0``. ``$`` - ``0`` if ``condition`` is ``1``, else ``1`` + ``0`` if ``condition`` is ``1``, else ``1``. String Comparisons ------------------ @@ -67,7 +67,7 @@ String Comparisons ``1`` if ``string1`` and ``string2`` are equal, else ``0``. The comparison is case-sensitive. ``$`` - ``1`` if ``value1`` and ``value2`` are numerically equal, else ``0`` + ``1`` if ``value1`` and ``value2`` are numerically equal, else ``0``. ``$`` ``1`` if ``string`` is member of the comma-separated ``list``, else ``0``. Uses case-sensitive comparisons. @@ -258,7 +258,7 @@ String Operations ----------------- ``$`` - Joins the list with the content of ``string`` + Joins the list with the content of ``string``. ``$`` Content of ``string`` converted to lower case. ``$`` @@ -308,7 +308,7 @@ Variable Queries ---------------- ``$`` - Configuration name + Configuration name. ``$`` Configuration name. Deprecated since CMake 3.0. Use ``CONFIG`` instead. ``$`` https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3fa0a03b7e4094bef1b66e48ed437e1c0b41c49a commit 3fa0a03b7e4094bef1b66e48ed437e1c0b41c49a Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 19:51:06 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Expand placeholders in string comparisons. And point out that STREQUAL is case sensitive. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index cbeb348..27bf7d1 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -63,12 +63,14 @@ Logical Operators String Comparisons ------------------ -``$`` - ``1`` if ``a`` is STREQUAL ``b``, else ``0`` -``$`` - ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0`` -``$`` - ``1`` if ``a`` is IN_LIST ``b``, else ``0`` +``$`` + ``1`` if ``string1`` and ``string2`` are equal, else ``0``. + The comparison is case-sensitive. +``$`` + ``1`` if ``value1`` and ``value2`` are numerically equal, else ``0`` +``$`` + ``1`` if ``string`` is member of the comma-separated ``list``, else ``0``. + Uses case-sensitive comparisons. ``$`` ``1`` if ``v1`` is a version less than ``v2``, else ``0``. ``$`` https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fb423b3c49d21df851b1d4a91fddfe94d835155b commit fb423b3c49d21df851b1d4a91fddfe94d835155b Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 19:31:22 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: sort conditional expressions below string-valued ones. Makes things yet clearer and simpler. Also correct remnant of "informational expression". diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 4f2036e..cbeb348 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -30,41 +30,14 @@ deviates from most of the CMake documentation in that it omits angular brackets ``<...>`` around placeholders like ``condition``, ``true_value``, ``string``, and so on. -.. _`Conditional Generator Expressions`: - -Conditional Generator Expressions -================================= - -Conditional generator expressions depend on a boolean condition -that must be ``0`` or ``1``. - -``$`` - Evaluates to ``true_value`` if ``condition`` is ``1``. - Otherwise evaluates to the empty string. - -``$`` - Evaluates to ``true_value`` if ``condition`` is ``1``. - Otherwise evaluates to ``false_value``. - -Typically, the ``condition`` is a -:ref:`boolean generator expression`. -For instance, - -.. code-block:: cmake - - $<$:DEBUG_MODE> - -expands to ``DEBUG_MODE`` when the ``Debug`` configuration is used, and -otherwise expands to the empty string. - .. _`Boolean Generator Expressions`: Boolean Generator Expressions ============================= Boolean expressions evaluate to either ``0`` or ``1``. -They are typically used to construct the condition in a -:ref:`conditional generator expression`. +They are typically used to construct the condition in a :ref:`conditional +generator expression`. Available boolean expressions are: @@ -239,7 +212,7 @@ introduce a helper variable to keep the code readable: set(prop "$") # helper variable $<$:-I$> -Available informational expressions are: +The following string-valued generator expressions are available: Escaped Characters ------------------ @@ -253,6 +226,32 @@ String literals to escape the special meaning a character would otherwise have: ``$`` A literal ``;``. Used to prevent list expansion on an argument with ``;``. +.. _`Conditional Generator Expressions`: + +Conditional Expressions +----------------------- + +Conditional generator expressions depend on a boolean condition +that must be ``0`` or ``1``. + +``$`` + Evaluates to ``true_string`` if ``condition`` is ``1``. + Otherwise evaluates to the empty string. + +``$`` + Evaluates to ``true_string`` if ``condition`` is ``1``. + Otherwise evaluates to ``false_string``. + +Typically, the ``condition`` is a :ref:`boolean generator expression +`. For instance, + +.. code-block:: cmake + + $<$:DEBUG_MODE> + +expands to ``DEBUG_MODE`` when the ``Debug`` configuration is used, and +otherwise expands to the empty string. + String Operations ----------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=867c9c9c0dc2782b2d822557c8dc83c451409b48 commit 867c9c9c0dc2782b2d822557c8dc83c451409b48 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 18:51:38 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Add deprecation date of $ diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 929d120..4f2036e 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -309,7 +309,7 @@ Variable Queries ``$`` Configuration name ``$`` - Configuration name. Deprecated. Use ``CONFIG`` instead. + Configuration name. Deprecated since CMake 3.0. Use ``CONFIG`` instead. ``$`` The CMake-id of the platform. See also the :variable:`CMAKE_SYSTEM_NAME` variable. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a85e5e6f4d53dd158392dd74b9632d84fb583722 commit a85e5e6f4d53dd158392dd74b9632d84fb583722 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 18:26:13 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Add note on omitted <..> notation in cmake-generator-expressions(7) diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 187f3b7..929d120 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -25,6 +25,11 @@ conditional include directories, and more. The conditions may be based on the build configuration, target properties, platform information or any other queryable information. +Generator expressions have the form ``$<...>``. To avoid confusion, this page +deviates from most of the CMake documentation in that it omits angular brackets +``<...>`` around placeholders like ``condition``, ``true_value``, ``string``, +and so on. + .. _`Conditional Generator Expressions`: Conditional Generator Expressions https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ff1db47728a37a7775a3b870ff9ffdc3249c3d40 commit ff1db47728a37a7775a3b870ff9ffdc3249c3d40 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 17:08:25 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:24 2018 +0100 Help: Revise documentation of string-valued generator expressions * Consolidate examples * Sort, and insert subsection headers diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 099d398..187f3b7 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -102,6 +102,7 @@ String Comparisons ``$`` ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. + Variable Queries ---------------- @@ -144,6 +145,9 @@ Variable Queries for the 'head' target, an error is reported. See the :manual:`cmake-compile-features(7)` manual for information on compile features and a list of supported compilers. + +.. _`Boolean COMPILE_LANGUAGE Generator Expression`: + ``$`` ``1`` when the language used for compilation unit matches ``language``, otherwise ``0``. This expression may be used to specify compile options, @@ -187,20 +191,22 @@ Variable Queries add_executable(myapp main.cpp) target_link_libraries(myapp myapp_c myapp_cxx) -Informational Generator Expressions +String-Valued Generator Expressions =================================== -These expressions expand to some information. The information may be used -directly, eg: +These expressions expand to some string. +For example, .. code-block:: cmake include_directories(/usr/include/$/) expands to ``/usr/include/GNU/`` or ``/usr/include/Clang/`` etc, depending on -the Id of the compiler. +the compiler identifier. -These expressions may also may be combined with logical expressions: +String-valued expressions may also be combined with other expressions. +Here an example for a string-valued expression within a boolean expressions +within a conditional expression: .. code-block:: cmake @@ -210,12 +216,95 @@ expands to ``OLD_COMPILER`` if the :variable:`CMAKE_CXX_COMPILER_VERSION _COMPILER_VERSION>` is less than 4.2.0. +And here two nested string-valued expressions: + +.. code-block:: cmake + + -I$, -I> + +generates a string of the entries in the :prop_tgt:`INCLUDE_DIRECTORIES` target +property with each entry preceded by ``-I``. + +Expanding on the previous example, if one first wants to check if the +``INCLUDE_DIRECTORIES`` property is non-empty, then it is advisable to +introduce a helper variable to keep the code readable: + +.. code-block:: cmake + + set(prop "$") # helper variable + $<$:-I$> + Available informational expressions are: -``$`` - Configuration name. Deprecated. Use ``CONFIG`` instead. +Escaped Characters +------------------ + +String literals to escape the special meaning a character would otherwise have: + +``$`` + A literal ``>``. Used for example to compare strings that contain a ``>``. +``$`` + A literal ``,``. Used for example to compare strings which contain a ``,``. +``$`` + A literal ``;``. Used to prevent list expansion on an argument with ``;``. + +String Operations +----------------- + +``$`` + Joins the list with the content of ``string`` +``$`` + Content of ``string`` converted to lower case. +``$`` + Content of ``string`` converted to upper case. + +``$`` + Content of ``expr`` evaluated as a generator expression in the current + context. This enables consumption of generator expressions whose + evaluation results itself in generator expressions. +``$`` + Content of ``expr`` evaluated as a generator expression in the context of + ``tgt`` target. This enables consumption of custom target properties that + themselves contain generator expressions. + + Having the capability to evaluate generator expressions is very useful when + you want to manage custom properties supporting generator expressions. + For example: + + .. code-block:: cmake + + add_library(foo ...) + + set_property(TARGET foo PROPERTY + CUSTOM_KEYS $<$:FOO_EXTRA_THINGS> + ) + + add_custom_target(printFooKeys + COMMAND ${CMAKE_COMMAND} -E echo $ + ) + + This naive implementation of the ``printFooKeys`` custom command is wrong + because ``CUSTOM_KEYS`` target property is not evaluated and the content + is passed as is (i.e. ``$<$:FOO_EXTRA_THINGS>``). + + To have the expected result (i.e. ``FOO_EXTRA_THINGS`` if config is + ``Debug``), it is required to evaluate the output of + ``$``: + + .. code-block:: cmake + + add_custom_target(printFooKeys + COMMAND ${CMAKE_COMMAND} -E + echo $> + ) + +Variable Queries +---------------- + ``$`` Configuration name +``$`` + Configuration name. Deprecated. Use ``CONFIG`` instead. ``$`` The CMake-id of the platform. See also the :variable:`CMAKE_SYSTEM_NAME` variable. @@ -231,6 +320,19 @@ Available informational expressions are: ``$`` The version of the CXX compiler used. See also the :variable:`CMAKE__COMPILER_VERSION` variable. +``$`` + The compile language of source files when evaluating compile options. + See :ref:`the related boolean expression + ` + ``$`` + for notes about the portability of this generator expression. + +Target-Dependent Queries +------------------------ + +``$`` + Expands to the ``tgt`` if the given target exists, an empty string + otherwise. ``$`` Full path to main file (.exe, .so.1.2, .a) where ``tgt`` is the name of a target. ``$`` @@ -283,54 +385,14 @@ Available informational expressions are: ``$`` Content of the install prefix when the target is exported via :command:`install(EXPORT)` and empty otherwise. -``$`` - The compile language of source files when evaluating compile options. See - the unary version for notes about portability of this generator - expression. -Output Generator Expressions -============================ +Output-Related Expressions +-------------------------- -These expressions generate output, in some cases depending on an input. These -expressions may be combined with other expressions for information or logical -comparison: - -.. code-block:: cmake - - -I$, -I> - -generates a string of the entries in the :prop_tgt:`INCLUDE_DIRECTORIES` target -property with each entry preceded by ``-I``. Note that a more-complete use -in this situation would require first checking if the INCLUDE_DIRECTORIES -property is non-empty: - -.. code-block:: cmake - - $<$:-I$> - -where ``${prop}`` refers to a helper variable: - -.. code-block:: cmake - - set(prop "$") - -Available output expressions are: - -``$`` - Joins the list with the content of ``...`` -``$`` - A literal ``>``. Used to compare strings which contain a ``>`` for example. -``$`` - A literal ``,``. Used to compare strings which contain a ``,`` for example. -``$`` - A literal ``;``. Used to prevent list expansion on an argument with ``;``. ``$`` Marks ``...`` as being the name of a target. This is required if exporting targets to multiple dependent export sets. The ``...`` must be a literal name of a target- it may not contain generator expressions. -``$`` - Expands to the ``...`` if the given target exists, an empty string - otherwise. ``$`` Content of ``...`` except when evaluated in a link interface while propagating :ref:`Target Usage Requirements`, in which case it is the @@ -345,10 +407,6 @@ Available output expressions are: Content of ``...`` when the property is exported using :command:`export`, or when the target is used by another target in the same buildsystem. Expands to the empty string otherwise. -``$`` - Content of ``...`` converted to lower case. -``$`` - Content of ``...`` converted to upper case. ``$`` Content of ``...`` converted to a C identifier. The conversion follows the same behavior as :command:`string(MAKE_C_IDENTIFIER)`. @@ -359,42 +417,3 @@ Available output expressions are: Content of ``...`` converted to shell path style. For example, slashes are converted to backslashes in Windows shells and drive letters are converted to posix paths in MSYS shells. The ``...`` must be an absolute path. -``$`` - Content of ``...`` evaluated as a generator expression in the current - context. This enables consumption of generator expressions - whose evaluation results itself in generator expressions. -``$`` - Content of ``...`` evaluated as a generator expression in the context of - ``tgt`` target. This enables consumption of custom target properties that - themselves contain generator expressions. - - Having the capability to evaluate generator expressions is very useful when - you want to manage custom properties supporting generator expressions. - For example: - - .. code-block:: cmake - - add_library(foo ...) - - set_property(TARGET foo PROPERTY - CUSTOM_KEYS $<$:FOO_EXTRA_THINGS> - ) - - add_custom_target(printFooKeys - COMMAND ${CMAKE_COMMAND} -E echo $ - ) - - This naive implementation of the ``printFooKeys`` custom command is wrong - because ``CUSTOM_KEYS`` target property is not evaluated and the content - is passed as is (i.e. ``$<$:FOO_EXTRA_THINGS>``). - - To have the expected result (i.e. ``FOO_EXTRA_THINGS`` if config is - ``Debug``), it is required to evaluate the output of - ``$``: - - .. code-block:: cmake - - add_custom_target(printFooKeys - COMMAND ${CMAKE_COMMAND} -E - echo $> - ) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fe8acf7c0540ca39300bab5b014e428e84077c7a commit fe8acf7c0540ca39300bab5b014e428e84077c7a Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 15:48:02 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: 3 subtypes of boolean generator expressions. Main classification by return type, subclassification by dependences diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 1c3d3fc..099d398 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -63,6 +63,9 @@ They are typically used to construct the condition in a Available boolean expressions are: +Logical Operators +----------------- + ``$`` ``1`` if the ``condition`` is true, else ``0`` @@ -79,12 +82,29 @@ Available boolean expressions are: ``$`` ``0`` if ``condition`` is ``1``, else ``1`` +String Comparisons +------------------ + ``$`` ``1`` if ``a`` is STREQUAL ``b``, else ``0`` ``$`` ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0`` ``$`` ``1`` if ``a`` is IN_LIST ``b``, else ``0`` +``$`` + ``1`` if ``v1`` is a version less than ``v2``, else ``0``. +``$`` + ``1`` if ``v1`` is a version greater than ``v2``, else ``0``. +``$`` + ``1`` if ``v1`` is the same version as ``v2``, else ``0``. +``$`` + ``1`` if ``v1`` is a version less than or equal to ``v2``, else ``0``. +``$`` + ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. + +Variable Queries +---------------- + ``$`` ``1`` if ``target`` exists, else ``0``. ``$`` @@ -104,16 +124,6 @@ Available boolean expressions are: ``1`` if the CMake-id of the CXX compiler matches ``compiler_id``, otherwise ``0``. See also the :variable:`CMAKE__COMPILER_ID` variable. -``$`` - ``1`` if ``v1`` is a version less than ``v2``, else ``0``. -``$`` - ``1`` if ``v1`` is a version greater than ``v2``, else ``0``. -``$`` - ``1`` if ``v1`` is the same version as ``v2``, else ``0``. -``$`` - ``1`` if ``v1`` is a version less than or equal to ``v2``, else ``0``. -``$`` - ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. ``$`` ``1`` if the version of the C compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE__COMPILER_VERSION` variable. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9891adf74becfa95463f6928fda9f8ac17c934bd commit 9891adf74becfa95463f6928fda9f8ac17c934bd Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 15:40:58 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: Cross-link conditional and boolean expressions. Rename Logical -> Boolean Generator Expressions. It's the return type that helps us to sort the expression zoo. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 094bfc1..1c3d3fc 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -25,11 +25,13 @@ conditional include directories, and more. The conditions may be based on the build configuration, target properties, platform information or any other queryable information. -Conditional Expressions -======================= +.. _`Conditional Generator Expressions`: -Conditional expressions depend on a boolean condition that must be -``0`` or ``1``. +Conditional Generator Expressions +================================= + +Conditional generator expressions depend on a boolean condition +that must be ``0`` or ``1``. ``$`` Evaluates to ``true_value`` if ``condition`` is ``1``. @@ -39,23 +41,27 @@ Conditional expressions depend on a boolean condition that must be Evaluates to ``true_value`` if ``condition`` is ``1``. Otherwise evaluates to ``false_value``. - -Logical Expressions -=================== - -Logical expressions are used to create conditional output. The basic -expressions are the ``0`` and ``1`` expressions. Because other logical -expressions evaluate to either ``0`` or ``1``, they can be composed to -create conditional output: +Typically, the ``condition`` is a +:ref:`boolean generator expression`. +For instance, .. code-block:: cmake $<$:DEBUG_MODE> expands to ``DEBUG_MODE`` when the ``Debug`` configuration is used, and -otherwise expands to nothing. +otherwise expands to the empty string. + +.. _`Boolean Generator Expressions`: + +Boolean Generator Expressions +============================= + +Boolean expressions evaluate to either ``0`` or ``1``. +They are typically used to construct the condition in a +:ref:`conditional generator expression`. -Available logical expressions are: +Available boolean expressions are: ``$`` ``1`` if the ``condition`` is true, else ``0`` @@ -171,8 +177,8 @@ Available logical expressions are: add_executable(myapp main.cpp) target_link_libraries(myapp myapp_c myapp_cxx) -Informational Expressions -========================= +Informational Generator Expressions +=================================== These expressions expand to some information. The information may be used directly, eg: @@ -272,8 +278,8 @@ Available informational expressions are: the unary version for notes about portability of this generator expression. -Output Expressions -================== +Output Generator Expressions +============================ These expressions generate output, in some cases depending on an input. These expressions may be combined with other expressions for information or logical https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=20b6561e78f5acceecae7c6fc330f7f7de4f2223 commit 20b6561e78f5acceecae7c6fc330f7f7de4f2223 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 15:23:00 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: new section on conditional generator expressions Before, the closely related signatures $ $ were explained in two different sections. The former section was badly explained, with '0' and '1' in place of the formal parameter 'condition'. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 6f17812..094bfc1 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -25,6 +25,21 @@ conditional include directories, and more. The conditions may be based on the build configuration, target properties, platform information or any other queryable information. +Conditional Expressions +======================= + +Conditional expressions depend on a boolean condition that must be +``0`` or ``1``. + +``$`` + Evaluates to ``true_value`` if ``condition`` is ``1``. + Otherwise evaluates to the empty string. + +``$`` + Evaluates to ``true_value`` if ``condition`` is ``1``. + Otherwise evaluates to ``false_value``. + + Logical Expressions =================== @@ -58,10 +73,6 @@ Available logical expressions are: ``$`` ``0`` if ``condition`` is ``1``, else ``1`` -``$`` - ``true_value`` if ``condition`` is ``1``, - ``false_value`` if ``condition`` is ``0`` - ``$`` ``1`` if ``a`` is STREQUAL ``b``, else ``0`` ``$`` @@ -289,10 +300,6 @@ where ``${prop}`` refers to a helper variable: Available output expressions are: -``$<0:...>`` - Empty string (ignores ``...``) -``$<1:...>`` - Content of ``...`` ``$`` Joins the list with the content of ``...`` ``$`` https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=873e59c0c456c2e13e66019c15f3632d06dac0f6 commit 873e59c0c456c2e13e66019c15f3632d06dac0f6 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 15:10:40 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: rm unmotivated "This means that" That generator expressions enable conditional things has not been said before. Amended for nicer source format. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 95de378..6f17812 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -20,10 +20,10 @@ commands to populate those properties, such as :command:`target_link_libraries`, :command:`target_include_directories`, :command:`target_compile_definitions` and others. -This means that they enable conditional linking, conditional -definitions used when compiling, and conditional include directories and -more. The conditions may be based on the build configuration, target -properties, platform information or any other queryable information. +They enable conditional linking, conditional definitions used when compiling, +conditional include directories, and more. The conditions may be based on +the build configuration, target properties, platform information or any other +queryable information. Logical Expressions =================== https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b2a798fe32ce25e5ea19f6487ce9cadf9852ea83 commit b2a798fe32ce25e5ea19f6487ce9cadf9852ea83 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 15:07:42 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: expand "ver", "pol", ... No need to save a few characters on formal parameters. Use this occasion to correct $: the parameter is a platform_id, not a compiler_id. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 24b79d4..95de378 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -68,21 +68,24 @@ Available logical expressions are: ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0`` ``$`` ``1`` if ``a`` is IN_LIST ``b``, else ``0`` -``$`` - ``1`` if ``tgt`` is an existed target name, else ``0``. +``$`` + ``1`` if ``target`` exists, else ``0``. ``$`` ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison. The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_` is also considered by this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED` target. -``$`` - ``1`` if the CMake-id of the platform matches ``comp``, otherwise ``0``. +``$`` + ``1`` if the CMake-id of the platform matches ``platform_id`` + otherwise ``0``. See also the :variable:`CMAKE_SYSTEM_NAME` variable. -``$`` - ``1`` if the CMake-id of the C compiler matches ``comp``, otherwise ``0``. +``$`` + ``1`` if the CMake-id of the C compiler matches ``compiler_id``, + otherwise ``0``. See also the :variable:`CMAKE__COMPILER_ID` variable. -``$`` - ``1`` if the CMake-id of the CXX compiler matches ``comp``, otherwise ``0``. +``$`` + ``1`` if the CMake-id of the CXX compiler matches ``compiler_id``, + otherwise ``0``. See also the :variable:`CMAKE__COMPILER_ID` variable. ``$`` ``1`` if ``v1`` is a version less than ``v2``, else ``0``. @@ -94,27 +97,28 @@ Available logical expressions are: ``1`` if ``v1`` is a version less than or equal to ``v2``, else ``0``. ``$`` ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. -``$`` - ``1`` if the version of the C compiler matches ``ver``, otherwise ``0``. +``$`` + ``1`` if the version of the C compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE__COMPILER_VERSION` variable. -``$`` - ``1`` if the version of the CXX compiler matches ``ver``, otherwise ``0``. +``$`` + ``1`` if the version of the CXX compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE__COMPILER_VERSION` variable. -``$`` - ``1`` if the policy ``pol`` was NEW when the 'head' target was created, - else ``0``. If the policy was not set, the warning message for the policy +``$`` + ``1`` if the ``policy`` was NEW when the 'head' target was created, + else ``0``. If the ``policy`` was not set, the warning message for the policy will be emitted. This generator expression only works for a subset of policies. -``$`` - ``1`` if all of the ``feature`` features are available for the 'head' +``$`` + where ``features`` is a comma-spearated list. + Evaluates to ``1`` if all of the ``features`` are available for the 'head' target, and ``0`` otherwise. If this expression is used while evaluating the link implementation of a target and if any dependency transitively increases the required :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD` for the 'head' target, an error is reported. See the :manual:`cmake-compile-features(7)` manual for information on compile features and a list of supported compilers. -``$`` - ``1`` when the language used for compilation unit matches ``lang``, +``$`` + ``1`` when the language used for compilation unit matches ``language``, otherwise ``0``. This expression may be used to specify compile options, compile definitions, and include directories for source files of a particular language in a target. For example: https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=db749f404c29bc91a06f2ea2fb23d8a30c526a9a commit db749f404c29bc91a06f2ea2fb23d8a30c526a9a Author: Joachim Wuttke (h) AuthorDate: Sun Nov 4 14:55:51 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 6 12:55:23 2018 +0100 Help: expand "..." and "?" in logical generator expressions Expand "..." and "?", which could be mistaken as metacharacters (and in the explanations of AND and OR actually were meant as metacharacters). diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index bddf827..24b79d4 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -42,19 +42,26 @@ otherwise expands to nothing. Available logical expressions are: -``$`` - ``1`` if the ``...`` is true, else ``0`` -``$`` - ``1`` if all ``?`` are ``1``, else ``0`` - - The ``?`` must always be either ``0`` or ``1`` in boolean expressions. - -``$`` - ``0`` if all ``?`` are ``0``, else ``1`` -``$`` - ``0`` if ``?`` is ``1``, else ``1`` -``$`` - ``true-value...`` if ``?`` is ``1``, ``false-value...`` if ``?`` is ``0`` +``$`` + ``1`` if the ``condition`` is true, else ``0`` + +``$`` + where ``conditions`` is a comma-separated list of boolean expressions. + Evaluates to ``1`` if all conditions are ``1``. + Otherwise evaluates to ``0``. + +``$`` + where ``conditions`` is a comma-separated list of boolean expressions. + Evaluates to ``1`` if at least one of the conditions is ``1``. + Otherwise evaluates to ``0``. + +``$`` + ``0`` if ``condition`` is ``1``, else ``1`` + +``$`` + ``true_value`` if ``condition`` is ``1``, + ``false_value`` if ``condition`` is ``0`` + ``$`` ``1`` if ``a`` is STREQUAL ``b``, else ``0`` ``$`` https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=53a5aec89998a58dff53946b47426ea692c5ad8d commit 53a5aec89998a58dff53946b47426ea692c5ad8d Author: R2RT AuthorDate: Sun Nov 4 23:05:35 2018 +0100 Commit: Brad King CommitDate: Mon Nov 5 08:31:09 2018 -0500 CMP0053: Fix double warning on uninitialized variables in -P mode When `CMP0053` is not set to OLD or NEW then we compute both variants in case we need to warn about a behavior change. Do not allow both code paths to produce an uninitialized variable warning. Fixes: #18552 diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 83139ba..0d42fb0 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2766,7 +2766,7 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( } else { varresult = value; } - } else if (!removeEmpty) { + } else if (!removeEmpty && !this->SuppressSideEffects) { // check to see if we need to print a warning // if strict mode is on and the variable has // not been "cleared"/initialized with a set(foo ) call diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index b47abfb..ef48852 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -348,6 +348,10 @@ set(RunCMake_TEST_OPTIONS --trace-expand --warn-uninitialized) run_cmake(trace-expand-warn-uninitialized) unset(RunCMake_TEST_OPTIONS) +set(RunCMake_TEST_OPTIONS --warn-uninitialized) +run_cmake(warn-uninitialized) +unset(RunCMake_TEST_OPTIONS) + set(RunCMake_TEST_OPTIONS --trace-source=trace-only-this-file.cmake) run_cmake(trace-source) unset(RunCMake_TEST_OPTIONS) diff --git a/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt b/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt new file mode 100644 index 0000000..a13402a --- /dev/null +++ b/Tests/RunCMake/CommandLine/warn-uninitialized-stderr.txt @@ -0,0 +1,5 @@ +^CMake Warning \(dev\) at warn-uninitialized.cmake:1 \(set\): + uninitialized variable 'WARN_FROM_NORMAL_CMAKE_FILE' +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/CommandLine/warn-uninitialized.cmake b/Tests/RunCMake/CommandLine/warn-uninitialized.cmake new file mode 100644 index 0000000..f1a75c9 --- /dev/null +++ b/Tests/RunCMake/CommandLine/warn-uninitialized.cmake @@ -0,0 +1 @@ +set(FOO "${WARN_FROM_NORMAL_CMAKE_FILE}") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f92f93467ecc22419c981f8f5283c81fa9d8eb01 commit f92f93467ecc22419c981f8f5283c81fa9d8eb01 Author: R2RT AuthorDate: Sun Nov 4 22:53:44 2018 +0100 Commit: Brad King CommitDate: Mon Nov 5 08:29:10 2018 -0500 cmMakefile: Rename SuppressWatches to SuppressSideEffects diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 0a69d09..83139ba 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -67,7 +67,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); - this->SuppressWatches = false; + this->SuppressSideEffects = false; // Setup the default include complaint regular expression (match nothing). this->ComplainFileRegularExpression = "^$"; @@ -2421,7 +2421,7 @@ const std::string* cmMakefile::GetDef(const std::string& name) const } #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); - if (vv && !this->SuppressWatches) { + if (vv && !this->SuppressSideEffects) { bool const watch_function_executed = vv->VariableAccessed(name, def ? cmVariableWatch::VARIABLE_READ_ACCESS @@ -2508,11 +2508,11 @@ const std::string& cmMakefile::ExpandVariablesInString( compareResults = true; // Suppress variable watches to avoid calling hooks twice. Suppress new // dereferences since the OLD behavior is still what is actually used. - this->SuppressWatches = true; + this->SuppressSideEffects = true; newError = ExpandVariablesInStringNew( newErrorstr, newResult, escapeQuotes, noEscapes, atOnly, filename, line, removeEmpty, replaceAt); - this->SuppressWatches = false; + this->SuppressSideEffects = false; CM_FALLTHROUGH; } case cmPolicies::OLD: diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index b30f281..d8176d9 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1025,7 +1025,7 @@ private: bool CheckCMP0000; std::set WarnedCMP0074; bool IsSourceFileTryCompile; - mutable bool SuppressWatches; + mutable bool SuppressSideEffects; }; #endif ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-generator-expressions.7.rst | 406 +++++++++++++-------- Help/manual/cmake-modules.7.rst | 1 + Help/module/FindSQLite3.rst | 1 + Help/release/dev/FindSQLite3-module.rst | 4 + Modules/FindSQLite3.cmake | 66 ++++ Source/cmAddSubDirectoryCommand.cxx | 6 +- Source/cmArchiveWrite.cxx | 2 +- Source/cmCTest.cxx | 4 +- Source/cmCacheManager.cxx | 3 +- Source/cmExtraEclipseCDT4Generator.cxx | 7 +- Source/cmExtraKateGenerator.cxx | 3 +- Source/cmFileCommand.cxx | 2 +- Source/cmFindBase.cxx | 4 +- Source/cmFindCommon.cxx | 4 +- Source/cmFindPackageCommand.cxx | 10 +- Source/cmGeneratorTarget.cxx | 5 +- Source/cmGetFilenameComponentCommand.cxx | 10 +- Source/cmGlobalGenerator.cxx | 2 +- Source/cmGlobalNinjaGenerator.cxx | 2 +- Source/cmGlobalXCodeGenerator.cxx | 2 +- Source/cmListCommand.cxx | 8 +- Source/cmLocalGenerator.cxx | 8 +- Source/cmLocalVisualStudio7Generator.cxx | 2 +- Source/cmMakefile.cxx | 10 +- Source/cmMakefile.h | 2 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmOrderDirectories.cxx | 2 +- Source/cmOutputConverter.cxx | 6 +- Source/cmOutputRequiredFilesCommand.cxx | 6 +- Source/cmRST.cxx | 3 +- Source/cmRulePlaceholderExpander.cxx | 4 +- Source/cmSetCommand.cxx | 8 +- Source/cmState.cxx | 8 +- Source/cmStringCommand.cxx | 7 +- Source/cmSystemTools.cxx | 4 +- Source/cmTarget.cxx | 2 +- Source/cmVisualStudioSlnParser.cxx | 6 +- Source/cmake.cxx | 2 +- Source/cmcldeps.cxx | 2 +- Source/cmcmd.cxx | 24 +- Tests/CMakeLists.txt | 4 + Tests/{FindCURL => FindSQLite3}/CMakeLists.txt | 8 +- Tests/FindSQLite3/Test/CMakeLists.txt | 16 + Tests/FindSQLite3/Test/main.c | 10 + Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 4 + .../warn-uninitialized-stderr.txt} | 6 +- .../RunCMake/CommandLine/warn-uninitialized.cmake | 1 + 47 files changed, 455 insertions(+), 254 deletions(-) create mode 100644 Help/module/FindSQLite3.rst create mode 100644 Help/release/dev/FindSQLite3-module.rst create mode 100644 Modules/FindSQLite3.cmake copy Tests/{FindCURL => FindSQLite3}/CMakeLists.txt (53%) create mode 100644 Tests/FindSQLite3/Test/CMakeLists.txt create mode 100644 Tests/FindSQLite3/Test/main.c copy Tests/RunCMake/{include/EmptyString-stderr.txt => CommandLine/warn-uninitialized-stderr.txt} (51%) create mode 100644 Tests/RunCMake/CommandLine/warn-uninitialized.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 07:53:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 07:53:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-396-g48de916 Message-ID: <20181107125304.19F63127455@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 48de9169d0624b323462c084b68cb1fdb693d91b (commit) via a67d1e824c162a7f84a1d2520199c7e5d10080fb (commit) via 3bad96c9888932ec2b792f2febfee6cc58bf8bbd (commit) via 272c4c3dee28a7b1c0a690cac3cb310165324794 (commit) via db0445f0c860cc561baf3b38f296b7f338385d63 (commit) from 7e6b78759904dcf31d780a6e2f14f3821f4f23df (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48de9169d0624b323462c084b68cb1fdb693d91b commit 48de9169d0624b323462c084b68cb1fdb693d91b Merge: a67d1e8 3bad96c Author: Brad King AuthorDate: Wed Nov 7 07:49:38 2018 -0500 Commit: Brad King CommitDate: Wed Nov 7 07:49:38 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a67d1e824c162a7f84a1d2520199c7e5d10080fb commit a67d1e824c162a7f84a1d2520199c7e5d10080fb Merge: 7e6b787 272c4c3 Author: Brad King AuthorDate: Wed Nov 7 12:46:33 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 7 07:46:40 2018 -0500 Merge topic 'FindOpenMP-log-errors' 272c4c3dee FindOpenMP: Log error output db0445f0c8 FindOpenMP: Fix warnings with -Wstrict-prototypes Acked-by: Kitware Robot Reviewed-by: Christian Pfeiffer Merge-request: !2574 ----------------------------------------------------------------------- Summary of changes: Modules/FindOpenMP.cmake | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 07:53:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 07:53:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-50-g3bad96c Message-ID: <20181107125304.3C244127457@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 3bad96c9888932ec2b792f2febfee6cc58bf8bbd (commit) via 272c4c3dee28a7b1c0a690cac3cb310165324794 (commit) via db0445f0c860cc561baf3b38f296b7f338385d63 (commit) from 263d28b2566facd87fe72dd40fc869fc09ca4172 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindOpenMP.cmake | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 09:53:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 09:53:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc2-398-g71db326 Message-ID: <20181107145304.711281273A2@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 71db32660eed1f70c06b624e661f8f5c2b938907 (commit) via 8d70ed5a10362209d265a15d993f319235aea7e5 (commit) from 48de9169d0624b323462c084b68cb1fdb693d91b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=71db32660eed1f70c06b624e661f8f5c2b938907 commit 71db32660eed1f70c06b624e661f8f5c2b938907 Merge: 48de916 8d70ed5 Author: Brad King AuthorDate: Wed Nov 7 09:48:30 2018 -0500 Commit: Brad King CommitDate: Wed Nov 7 09:48:30 2018 -0500 Merge branch 'release-3.13' ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 09:53:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 09:53:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc2-51-g8d70ed5 Message-ID: <20181107145304.8B6EC1273A3@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 8d70ed5a10362209d265a15d993f319235aea7e5 (commit) from 3bad96c9888932ec2b792f2febfee6cc58bf8bbd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 7 10:03:02 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 7 Nov 2018 10:03:02 -0500 (EST) Subject: [Cmake-commits] CMake annotated tag, v3.13.0-rc3, created. v3.13.0-rc3 Message-ID: <20181107150302.633CE127550@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The annotated tag, v3.13.0-rc3 has been created at 3b466627c5d387c21b003d641c14685c7a6c2335 (tag) tagging 8d70ed5a10362209d265a15d993f319235aea7e5 (commit) replaces v3.13.0-rc2 tagged by Brad King on Wed Nov 7 09:48:21 2018 -0500 - Log ----------------------------------------------------------------- CMake 3.13.0-rc3 -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEExsJlMku+vcNQtRPQLSzvEDSSFoQFAlvi+zUWHGJyYWQua2lu Z0BraXR3YXJlLmNvbQAKCRAtLO8QNJIWhLRwEACzdUTCCWxSzWPOGEEI1va6QB8S kp8eWut+3BgIJLnod8zwd3ui0GksxVBMRvgJ1kDX74vMQKUV/YE5JzztDUttQgHV j+qrUzI/XM/WEDJFPfhpT2wmwfaDpXmzWfWCFNqmzobTxNgK98n06DqGTPp50oGO nHq57FOEYevSEkc39HK3jlBY46gEad8Yja/FMgC/mwlmeYrpSCgUVWt4BwDsV8ad aGd/ZZEgKzFsJ+BgONxznYO1q5JsmoQ5MN+hhCTxv+k26wSZlJQsOOoPag/chPqs +Qhk+n6QnMnLC8Y5TbMr34JsazdF4iSMraeFk0jkMmg+h4PBuxiq3bT/YrJzwwBj sfsidtLdcpyxMgtYYeOZitO8MqxHHmodySTA+wXMrMgV3nJykagAAqDp4VpF4WR0 MDuOLYE5b4aXkt49JTfsp4L0fnQiFWu964dBbPB5gcHuIEpbY5iEpiYIE9J6r3yM W22t/pNp79Dv1Y4Rb0cMulujqsRxUrH544XWKtj/RewObRm0cRapMzd3oXt0h4Zn r4AZRSm/CmQB7HDp8VjhdzNk8Ejv+dmA7o2F4k3mTlPNmF9877RUtv7COMExCJEG bDvuJrQUJjxgb0qOK+zo+Wn0Y01fM4KOXPAc0Yxz3SJ6z309Te5eKvL0XmmU+tMI G9igI8zMvASvaHYNCA== =af+B -----END PGP SIGNATURE----- Brad King (33): FindMPI: Pass -pthread to CUDA compiler through -Xcompiler Merge branch 'FindMPI-pthread-cuda' into release-3.13 Merge branch 'doc-updates' into release-3.13 set_directory_properties: Restore in script mode Merge branch 'set_directory_properties-script-mode' into release-3.13 Merge branch 'UseSWIG-multi-input' into release-3.13 Merge branch 'cuda-filter-device-link-libs' into release-3.13 Merge branch 'qccDepfile' into release-3.13 Flang: Fix command-line used to preprocess sources Merge branch 'flang-preprocess-source' into release-3.13 Merge branch 'FindBoost-stacktrace' into release-3.13 Merge branch 'UseSWIG-typos' into release-3.13 CSharp: Fix regression in VS project type selection for custom target Merge branch 'FindPostgreSQL-11' into release-3.13 Merge branch 'fix-custom-target-with-csharp' into release-3.13 curl: Update script to get curl 7.62.0 Merge branch 'upstream-curl' into update-curl curl: Update build within CMake to account for 7.62 changes FindProtobuf: Add missing link dependencies on threads Merge branch 'FindProtobuf-threads' into release-3.13 curl: Modernize tiny test code used for build inside CMake Merge branch 'server-file-monitor-check' into release-3.13 curl: backport upstream fix to 7.62.0 regression add_custom_{command,target}: Fix WORKING_DIRECTORY leading genex Merge branch 'update-curl' into release-3.13 Merge branch 'custom-command-work-dir-genex' into release-3.13 Merge branch 'blaslapack95' into release-3.13 FindBoost: Add explicit Boost_ARCHITECTURE option Merge branch 'rename-cpack-ext-generator' into release-3.13 Merge branch 'backport-FindBoost-explicit-arch-tag' into release-3.13 Merge branch 'cpack-doc-gen-names' into release-3.13 Merge branch 'FindOpenMP-log-errors' into release-3.13 CMake 3.13.0-rc3 Craig Scott (4): Help: Fix generators link in cpack(1) manual Merge branch 'cpack-gen-docs-link' into release-3.13 CPack: Rename Ext generator to External Help: Use correct CPack generator names Curl Upstream (1): curl 2018-10-30 (19667715) Ivan Pozdeev (2): FindOpenMP: Fix warnings with -Wstrict-prototypes FindOpenMP: Log error output Jakub Benda (2): FindBLAS: Correct symbol searched in BLAS95 wrapper FindLAPACK: Correct library name and symbol searched in LAPACK95 wrapper Maikel van den Hurk (1): QNX: Update qcc depfile flags to be compliant with ccache Marc Chevrier (2): Help: clarify "LINKER:" prefix usage UseSWIG: multiple input files must be supported in version 2 Martin Quinson (1): FindBoost: Add support for stacktrace components Robert Maynard (1): CUDA: Filter out non-static libraries during device linking Sylvain Joubert (3): UseSWIG: Typo, add missing letter UseSWIG: Add target language and input file in command description FindPostgreSQL: Search for version 11 Vladimir Penev (1): server: Fix assertion failure on directory paths in file monitor ----------------------------------------------------------------------- hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 8 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 8 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-348-g4193430 Message-ID: <20181108050306.0BA4E127780@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 4193430628757eb664f65bb1810ce5077f68e2b3 (commit) from 71db32660eed1f70c06b624e661f8f5c2b938907 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4193430628757eb664f65bb1810ce5077f68e2b3 commit 4193430628757eb664f65bb1810ce5077f68e2b3 Author: Kitware Robot AuthorDate: Thu Nov 8 00:01:08 2018 -0500 Commit: Kitware Robot CommitDate: Thu Nov 8 00:01:08 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ad29c57..5f7dd8a 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 13) -set(CMake_VERSION_PATCH 20181107) +set(CMake_VERSION_PATCH 20181108) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 8 07:33:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 8 Nov 2018 07:33:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-352-ga4add4e Message-ID: <20181108123306.AFEB51288AE@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via a4add4eca2a19b52c44b6cbf074f99788e63d04e (commit) via a848abe24cd9cf05b9ffc9141d3f4a3ea633c056 (commit) via f5c46dd84ec48cfd1bfe32ed0093a21321e89845 (commit) via 1c4c4be509ab548d9e848a8850c30e3dbbb7f8bc (commit) from 4193430628757eb664f65bb1810ce5077f68e2b3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a4add4eca2a19b52c44b6cbf074f99788e63d04e commit a4add4eca2a19b52c44b6cbf074f99788e63d04e Merge: a848abe f5c46dd Author: Brad King AuthorDate: Thu Nov 8 12:31:14 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 8 07:31:30 2018 -0500 Merge topic 'pkgconfig-mark-advanced' f5c46dd84e PkgConfig: Be less verbose by mark(ing)_as_advanced the find_library result Acked-by: Kitware Robot Acked-by: Rolf Eike Beer Merge-request: !2576 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a848abe24cd9cf05b9ffc9141d3f4a3ea633c056 commit a848abe24cd9cf05b9ffc9141d3f4a3ea633c056 Merge: 4193430 1c4c4be Author: Brad King AuthorDate: Thu Nov 8 12:30:41 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 8 07:30:51 2018 -0500 Merge topic 'find-jpeg-turbo-multiarch-version' 1c4c4be509 FindJPEG: handle multiarch installs of libjpeg-turbo Acked-by: Kitware Robot Merge-request: !2572 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f5c46dd84ec48cfd1bfe32ed0093a21321e89845 commit f5c46dd84ec48cfd1bfe32ed0093a21321e89845 Author: Sylvain Joubert AuthorDate: Wed Nov 7 11:07:32 2018 +0100 Commit: Sylvain Joubert CommitDate: Wed Nov 7 14:08:02 2018 +0100 PkgConfig: Be less verbose by mark(ing)_as_advanced the find_library result diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index a45aef2..e192426 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -231,6 +231,7 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path) find_library(pkgcfg_lib_${_prefix}_${_pkg_search} NAMES ${_pkg_search} ${_find_opts}) + mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_search}) list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}") endforeach() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1c4c4be509ab548d9e848a8850c30e3dbbb7f8bc commit 1c4c4be509ab548d9e848a8850c30e3dbbb7f8bc Author: Ben Boeckel AuthorDate: Tue Nov 6 13:20:36 2018 -0500 Commit: Ben Boeckel CommitDate: Tue Nov 6 16:45:52 2018 -0500 FindJPEG: handle multiarch installs of libjpeg-turbo Fedora installs a `jconfig-32.h` and `jconfig-64.h` which were not searched. Instead, glob up all `jconfig` headers and bail once we've found a version number. diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake index 0aa387a..f50f79e 100644 --- a/Modules/FindJPEG.cmake +++ b/Modules/FindJPEG.cmake @@ -67,23 +67,33 @@ endif() unset(jpeg_names) unset(jpeg_names_debug) -if(JPEG_INCLUDE_DIR AND EXISTS "${JPEG_INCLUDE_DIR}/jpeglib.h") - file(STRINGS "${JPEG_INCLUDE_DIR}/jpeglib.h" - jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*") - - if (NOT jpeg_lib_version) - # libjpeg-turbo sticks JPEG_LIB_VERSION in jconfig.h - find_path(jconfig_dir jconfig.h) - if (jconfig_dir) - file(STRINGS "${jconfig_dir}/jconfig.h" - jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*") - endif() - unset(jconfig_dir) - endif() - - string(REGEX REPLACE "^#define[\t ]+JPEG_LIB_VERSION[\t ]+([0-9]+).*" - "\\1" JPEG_VERSION "${jpeg_lib_version}") +if(JPEG_INCLUDE_DIR) + file(GLOB _JPEG_CONFIG_HEADERS_FEDORA "${JPEG_INCLUDE_DIR}/jconfig*.h") + file(GLOB _JPEG_CONFIG_HEADERS_DEBIAN "${JPEG_INCLUDE_DIR}/*/jconfig.h") + set(_JPEG_CONFIG_HEADERS + "${JPEG_INCLUDE_DIR}/jpeglib.h" + ${_JPEG_CONFIG_HEADERS_FEDORA} + ${_JPEG_CONFIG_HEADERS_DEBIAN}) + foreach (_JPEG_CONFIG_HEADER IN LISTS _JPEG_CONFIG_HEADERS) + if (NOT EXISTS "${_JPEG_CONFIG_HEADER}") + continue () + endif () + file(STRINGS "${_JPEG_CONFIG_HEADER}" + jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*") + + if (NOT jpeg_lib_version) + continue () + endif () + + string(REGEX REPLACE "^#define[\t ]+JPEG_LIB_VERSION[\t ]+([0-9]+).*" + "\\1" JPEG_VERSION "${jpeg_lib_version}") + break () + endforeach () unset(jpeg_lib_version) + unset(_JPEG_CONFIG_HEADER) + unset(_JPEG_CONFIG_HEADERS) + unset(_JPEG_CONFIG_HEADERS_FEDORA) + unset(_JPEG_CONFIG_HEADERS_DEBIAN) endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) diff --git a/Tests/FindJPEG/Test/CMakeLists.txt b/Tests/FindJPEG/Test/CMakeLists.txt index a744f85..912c7a1 100644 --- a/Tests/FindJPEG/Test/CMakeLists.txt +++ b/Tests/FindJPEG/Test/CMakeLists.txt @@ -4,6 +4,8 @@ include(CTest) find_package(JPEG) +add_definitions(-DCMAKE_EXPECTED_JPEG_VERSION=${JPEG_VERSION}) + add_executable(test_jpeg_tgt main.c) target_link_libraries(test_jpeg_tgt JPEG::JPEG) add_test(NAME test_jpeg_tgt COMMAND test_jpeg_tgt) diff --git a/Tests/FindJPEG/Test/main.c b/Tests/FindJPEG/Test/main.c index c6e48f0..0e23eff 100644 --- a/Tests/FindJPEG/Test/main.c +++ b/Tests/FindJPEG/Test/main.c @@ -12,5 +12,5 @@ int main() cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); - return 0; + return (JPEG_LIB_VERSION != CMAKE_EXPECTED_JPEG_VERSION); } ----------------------------------------------------------------------- Summary of changes: Modules/FindJPEG.cmake | 42 +++++++++++++++++++++++--------------- Modules/FindPkgConfig.cmake | 1 + Tests/FindJPEG/Test/CMakeLists.txt | 2 ++ Tests/FindJPEG/Test/main.c | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 8 07:43:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 8 Nov 2018 07:43:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-355-g17e98e0 Message-ID: <20181108124305.3EF4D1276ED@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 17e98e00c449ebdceac980c0ce65c800030605db (commit) via fdcd559a8ea7748e662c40a0a4a34905611bf238 (commit) via 9fc20a4f3e1865e409d960c87e2e4a366775b72b (commit) from a4add4eca2a19b52c44b6cbf074f99788e63d04e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=17e98e00c449ebdceac980c0ce65c800030605db commit 17e98e00c449ebdceac980c0ce65c800030605db Merge: a4add4e fdcd559 Author: Brad King AuthorDate: Thu Nov 8 12:33:05 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 8 07:33:18 2018 -0500 Merge topic 'install-defaults' fdcd559a8e Help: Add documentation and release notes for install 9fc20a4f3e install: Add sane set of defaults for DESTINATION and file type parameters Acked-by: Kitware Robot Acked-by: Alex Turbov Acked-by: Ruslan Baratov Merge-request: !2558 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fdcd559a8ea7748e662c40a0a4a34905611bf238 commit fdcd559a8ea7748e662c40a0a4a34905611bf238 Author: Kyle Edwards AuthorDate: Sat Nov 3 14:39:42 2018 -0400 Commit: Kyle Edwards CommitDate: Wed Nov 7 15:47:21 2018 -0500 Help: Add documentation and release notes for install This change adds documentation for the new DESTINATION behavior of the install() command. diff --git a/Help/command/install.rst b/Help/command/install.rst index 4966df4..55c8485 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -9,8 +9,8 @@ Synopsis .. parsed-literal:: install(`TARGETS`_ ... [...]) - install({`FILES`_ | `PROGRAMS`_} ... DESTINATION [...]) - install(`DIRECTORY`_ ... DESTINATION [...]) + install({`FILES`_ | `PROGRAMS`_} ... [DESTINATION ] [...]) + install(`DIRECTORY`_ ... [DESTINATION ] [...]) install(`SCRIPT`_ [...]) install(`CODE`_ [...]) install(`EXPORT`_ DESTINATION [...]) @@ -172,6 +172,29 @@ installation properties apply to all target types. If only one is given then only targets of that type will be installed (which can be used to install just a DLL or just an import library.) +For some target types, the ``DESTINATION`` argument is optional. If no +``DESTINATION`` argument is specified for these target types, the destination +will default to either the appropriate variable from :module:`GNUInstallDirs` +(if it is defined) or a built-in default (if the variable is not defined.) These +defaults are outlined below: + +================== =============================== ====================== + Target Type GNUInstallDirs Variable Built-In Default +================== =============================== ====================== +``RUNTIME`` ``${CMAKE_INSTALL_BINDIR}`` ``bin`` +``LIBRARY`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib`` +``ARCHIVE`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib`` +``PRIVATE_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include`` +``PUBLIC_HEADER`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include`` +================== =============================== ====================== + +To make your package compliant with distribution filesystem layout policies, it +is not recommended that you specify a ``DESTINATION`` for a target unless it +must be installed in a nonstandard location. That way, package maintainers can +control the install destination by setting the appropriate cache variables. In +any case, it is recommended that you use the :module:`GNUInstallDirs` variables +in your ``DESTINATION`` arguments whenever possible. + In addition to the common options listed above, each target can accept the following additional arguments: @@ -307,7 +330,7 @@ Installing Files .. code-block:: cmake - install( files... DESTINATION + install( files... [DESTINATION | TYPE ] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT ] @@ -331,6 +354,47 @@ The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use However, if any item begins in a generator expression it must evaluate to a full path. +Instead of specifying ``DESTINATION``, you may specify a generic file type +via the ``TYPE`` argument as listed below. If a type is selected and no +destination is specified, the destination will default to either the +appropriate variable from :module:`GNUInstallDirs` (if it is defined) or a +built-in default (if the variable is not defined.) These defaults are outlined +below: + +======================= ================================== ========================= + ``TYPE`` Argument GNUInstallDirs Variable Built-In Default +======================= ================================== ========================= +``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin`` +``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin`` +``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib`` +``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include`` +``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc`` +``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com`` +``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var`` +``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``/run`` +``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ```` +``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``/info`` +``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``/locale`` +``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``/man`` +``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``/doc`` +======================= ================================== ========================= + +It is an error to use ``TYPE`` and ``DESTINATION`` arguments together. + +Note that some of the types' built-in defaults use the ``DATAROOT`` directory as +a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with +``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in +default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use +``DATA`` instead. + +To make your package compliant with distribution filesystem layout policies, it +is recommended that you specify one of the above generic file types, rather than +a ``DESTINATION`` argument, unless the files must be installed in a nonstandard +location. That way, package maintainers can control the install destination by +setting the appropriate cache variables. In any case, it is recommended that you +use the :module:`GNUInstallDirs` variables in your ``DESTINATION`` arguments +whenever possible. + The install destination given to the files install ``DESTINATION`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. @@ -342,7 +406,7 @@ Installing Directories .. code-block:: cmake - install(DIRECTORY dirs... DESTINATION + install(DIRECTORY dirs... [DESTINATION | TYPE ] [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER] @@ -413,6 +477,47 @@ will install the ``icons`` directory to ``share/myproj/icons`` and the file permissions, the scripts will be given specific permissions, and any ``CVS`` directories will be excluded. +Instead of specifying ``DESTINATION``, you may specify a generic file type +via the ``TYPE`` argument as listed below. If a type is selected and no +destination is specified, the destination will default to either the +appropriate variable from :module:`GNUInstallDirs` (if it is defined) or a +built-in default (if the variable is not defined.) These defaults are outlined +below: + +======================= ================================== ========================= + ``TYPE`` Argument GNUInstallDirs Variable Built-In Default +======================= ================================== ========================= +``BIN`` ``${CMAKE_INSTALL_BINDIR}`` ``bin`` +``SBIN`` ``${CMAKE_INSTALL_SBINDIR}`` ``sbin`` +``LIB`` ``${CMAKE_INSTALL_LIBDIR}`` ``lib`` +``INCLUDE`` ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include`` +``SYSCONF`` ``${CMAKE_INSTALL_SYSCONFDIR}`` ``etc`` +``SHAREDSTATE`` ``${CMAKE_INSTALL_SHARESTATEDIR}`` ``com`` +``LOCALSTATE`` ``${CMAKE_INSTALL_LOCALSTATEDIR}`` ``var`` +``RUNSTATE`` ``${CMAKE_INSTALL_RUNSTATEDIR}`` ``/run`` +``DATA`` ``${CMAKE_INSTALL_DATADIR}`` ```` +``INFO`` ``${CMAKE_INSTALL_INFODIR}`` ``/info`` +``LOCALE`` ``${CMAKE_INSTALL_LOCALEDIR}`` ``/locale`` +``MAN`` ``${CMAKE_INSTALL_MANDIR}`` ``/man`` +``DOC`` ``${CMAKE_INSTALL_DOCDIR}`` ``/doc`` +======================= ================================== ========================= + +It is an error to use ``TYPE`` and ``DESTINATION`` arguments together. + +Note that some of the types' built-in defaults use the ``DATAROOT`` directory as +a prefix. The ``DATAROOT`` prefix is calculated similarly to the types, with +``CMAKE_INSTALL_DATAROOTDIR`` as the variable and ``share`` as the built-in +default. You cannot use ``DATAROOT`` as a ``TYPE`` parameter; please use +``DATA`` instead. + +To make your package compliant with distribution filesystem layout policies, it +is recommended that you specify one of the above generic file types, rather than +a ``DESTINATION`` argument, unless the files must be installed in a nonstandard +location. That way, package maintainers can control the install destination by +setting the appropriate cache variables. In any case, it is recommended that you +use the :module:`GNUInstallDirs` variables in your ``DESTINATION`` arguments +whenever possible. + The list of ``dirs...`` given to ``DIRECTORY`` and the install destination given to the directory install ``DESTINATION`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` diff --git a/Help/release/dev/install-defaults.rst b/Help/release/dev/install-defaults.rst new file mode 100644 index 0000000..4f31b7e --- /dev/null +++ b/Help/release/dev/install-defaults.rst @@ -0,0 +1,12 @@ +install-defaults +---------------- + +* The ``TARGETS`` variant of the :command:`install` command learned how to + install to an appropriate default directory for a given target type, based + on variables from the :module:`GNUInstallDirs` module and built-in defaults, + in lieu of a ``DESTINATION`` argument. +* The ``FILES`` and ``DIRECTORY`` variants of the :command:`install` command + learned a new set of parameters for installing files as a file type, setting + the destination based on the appropriate variables from + :module:`GNUInstallDirs` and built-in defaults, in lieu of a ``DESTINATION`` + argument. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9fc20a4f3e1865e409d960c87e2e4a366775b72b commit 9fc20a4f3e1865e409d960c87e2e4a366775b72b Author: Kyle Edwards AuthorDate: Fri Nov 2 12:42:41 2018 -0400 Commit: Kyle Edwards CommitDate: Wed Nov 7 14:08:48 2018 -0500 install: Add sane set of defaults for DESTINATION and file type parameters If the user does not specify a DESTINATION for a target type, the install() command checks to see if the appropriate variable from GNUInstallDirs is set. If it is not, then it uses an appropriate hard-coded guess. In addition, for FILES and DIRECTORY, the user can specify a file type instead of a DESTINATION, and the command will use the appropriate variable from GNUInstallDirs, or a hard-coded guess if it is not set. diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index fbc5278..7c8458a 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -3,6 +3,7 @@ #include "cmInstallCommand.h" #include "cmsys/Glob.hxx" +#include #include #include #include @@ -33,8 +34,8 @@ class cmExecutionStatus; static cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, - cmListFileBacktrace const& backtrace, bool forceOpt = false, - bool namelink = false) + cmListFileBacktrace const& backtrace, const std::string& destination, + bool forceOpt = false, bool namelink = false) { cmInstallGenerator::MessageLevel message = cmInstallGenerator::SelectMessageLevel(target.GetMakefile()); @@ -42,25 +43,49 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( const char* component = namelink ? args.GetNamelinkComponent().c_str() : args.GetComponent().c_str(); return new cmInstallTargetGenerator( - target.GetName(), args.GetDestination().c_str(), impLib, + target.GetName(), destination.c_str(), impLib, args.GetPermissions().c_str(), args.GetConfigurations(), component, message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt, backtrace); } +static cmInstallTargetGenerator* CreateInstallTargetGenerator( + cmTarget& target, const cmInstallCommandArguments& args, bool impLib, + cmListFileBacktrace const& backtrace, bool forceOpt = false, + bool namelink = false) +{ + return CreateInstallTargetGenerator(target, args, impLib, backtrace, + args.GetDestination(), forceOpt, + namelink); +} + static cmInstallFilesGenerator* CreateInstallFilesGenerator( cmMakefile* mf, const std::vector& absFiles, - const cmInstallCommandArguments& args, bool programs) + const cmInstallCommandArguments& args, bool programs, + const std::string& destination) { cmInstallGenerator::MessageLevel message = cmInstallGenerator::SelectMessageLevel(mf); return new cmInstallFilesGenerator( - absFiles, args.GetDestination().c_str(), programs, - args.GetPermissions().c_str(), args.GetConfigurations(), - args.GetComponent().c_str(), message, args.GetExcludeFromAll(), - args.GetRename().c_str(), args.GetOptional()); + absFiles, destination.c_str(), programs, args.GetPermissions().c_str(), + args.GetConfigurations(), args.GetComponent().c_str(), message, + args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional()); } +static cmInstallFilesGenerator* CreateInstallFilesGenerator( + cmMakefile* mf, const std::vector& absFiles, + const cmInstallCommandArguments& args, bool programs) +{ + return CreateInstallFilesGenerator(mf, absFiles, args, programs, + args.GetDestination()); +} + +static const std::set allowedTypes{ + "BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF", + "SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO", + "LOCALE", "MAN", "DOC", +}; + // cmInstallCommand bool cmInstallCommand::InitialPass(std::vector const& args, cmExecutionStatus&) @@ -335,6 +360,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) "At most one of these two options may be specified."); return false; } + if (!genericArgs.GetType().empty() || !archiveArgs.GetType().empty() || + !libraryArgs.GetType().empty() || !runtimeArgs.GetType().empty() || + !objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() || + !bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() || + !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) { + std::ostringstream e; + e << "TARGETS given TYPE option. The TYPE option may only be specified in " + " install(FILES) and install(DIRECTORIES)."; + this->SetError(e.str()); + return false; + } // Select the mode for installing symlinks to versioned shared libraries. cmInstallTargetGenerator::NamelinkModeType namelinkMode = @@ -447,8 +483,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) target, runtimeArgs, false, this->Makefile->GetBacktrace()); } if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) { - this->SetError("Library TARGETS given no DESTINATION!"); - return false; + archiveGenerator = CreateInstallTargetGenerator( + target, archiveArgs, true, this->Makefile->GetBacktrace(), + this->GetArchiveDestination(nullptr)); + runtimeGenerator = CreateInstallTargetGenerator( + target, runtimeArgs, false, this->Makefile->GetBacktrace(), + this->GetRuntimeDestination(nullptr)); } } else { // This is a non-DLL platform. @@ -474,30 +514,22 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } } else { // The shared library uses the LIBRARY properties. - if (!libraryArgs.GetDestination().empty()) { - if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) { - libraryGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace()); - libraryGenerator->SetNamelinkMode( - cmInstallTargetGenerator::NamelinkModeSkip); - } - if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) { - namelinkGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace(), - false, true); - namelinkGenerator->SetNamelinkMode( - cmInstallTargetGenerator::NamelinkModeOnly); - } - namelinkOnly = - (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); - } else { - std::ostringstream e; - e << "TARGETS given no LIBRARY DESTINATION for shared library " - "target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); - return false; + if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) { + libraryGenerator = CreateInstallTargetGenerator( + target, libraryArgs, false, this->Makefile->GetBacktrace(), + this->GetLibraryDestination(&libraryArgs)); + libraryGenerator->SetNamelinkMode( + cmInstallTargetGenerator::NamelinkModeSkip); + } + if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) { + namelinkGenerator = CreateInstallTargetGenerator( + target, libraryArgs, false, this->Makefile->GetBacktrace(), + this->GetLibraryDestination(&libraryArgs), false, true); + namelinkGenerator->SetNamelinkMode( + cmInstallTargetGenerator::NamelinkModeOnly); } + namelinkOnly = + (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); } } } break; @@ -524,17 +556,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } } else { // Static libraries use ARCHIVE properties. - if (!archiveArgs.GetDestination().empty()) { - archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, false, this->Makefile->GetBacktrace()); - } else { - std::ostringstream e; - e << "TARGETS given no ARCHIVE DESTINATION for static library " - "target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); - return false; - } + archiveGenerator = CreateInstallTargetGenerator( + target, archiveArgs, false, this->Makefile->GetBacktrace(), + this->GetArchiveDestination(&archiveArgs)); } } break; case cmStateEnums::MODULE_LIBRARY: { @@ -602,17 +626,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } } else { // Executables use the RUNTIME properties. - if (!runtimeArgs.GetDestination().empty()) { - runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace()); - } else { - std::ostringstream e; - e << "TARGETS given no RUNTIME DESTINATION for executable " - "target \"" - << target.GetName() << "\"."; - this->SetError(e.str()); - return false; - } + runtimeGenerator = CreateInstallTargetGenerator( + target, runtimeArgs, false, this->Makefile->GetBacktrace(), + this->GetRuntimeDestination(&runtimeArgs)); } // On DLL platforms an executable may also have an import @@ -659,15 +675,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } // Create the files install generator. - if (!privateHeaderArgs.GetDestination().empty()) { - privateHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, privateHeaderArgs, false); - } else { - std::ostringstream e; - e << "INSTALL TARGETS - target " << target.GetName() << " has " - << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION."; - cmSystemTools::Message(e.str().c_str(), "Warning"); - } + privateHeaderGenerator = CreateInstallFilesGenerator( + this->Makefile, absFiles, privateHeaderArgs, false, + this->GetIncludeDestination(&privateHeaderArgs)); } files = target.GetProperty("PUBLIC_HEADER"); @@ -680,15 +690,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } // Create the files install generator. - if (!publicHeaderArgs.GetDestination().empty()) { - publicHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, publicHeaderArgs, false); - } else { - std::ostringstream e; - e << "INSTALL TARGETS - target " << target.GetName() << " has " - << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION."; - cmSystemTools::Message(e.str().c_str(), "Warning"); - } + publicHeaderGenerator = CreateInstallFilesGenerator( + this->Makefile, absFiles, publicHeaderArgs, false, + this->GetIncludeDestination(&publicHeaderArgs)); } files = target.GetProperty("RESOURCE"); @@ -824,6 +828,14 @@ bool cmInstallCommand::HandleFilesMode(std::vector const& args) return false; } + std::string type = ica.GetType(); + if (!type.empty() && allowedTypes.count(type) == 0) { + std::ostringstream e; + e << args[0] << " given non-type \"" << type << "\" with TYPE argument."; + this->SetError(e.str()); + return false; + } + const std::vector& filesVector = files.GetVector(); // Check if there is something to do. @@ -886,7 +898,17 @@ bool cmInstallCommand::HandleFilesMode(std::vector const& args) return false; } - if (ica.GetDestination().empty()) { + if (!type.empty() && !ica.GetDestination().empty()) { + std::ostringstream e; + e << args[0] + << " given both TYPE and DESTINATION arguments. You may only specify " + "one."; + this->SetError(e.str()); + return false; + } + + std::string destination = this->GetDestinationForType(&ica, type); + if (destination.empty()) { // A destination is required. std::ostringstream e; e << args[0] << " given no DESTINATION!"; @@ -895,8 +917,8 @@ bool cmInstallCommand::HandleFilesMode(std::vector const& args) } // Create the files install generator. - this->Makefile->AddInstallGenerator( - CreateInstallFilesGenerator(this->Makefile, absFiles, ica, programs)); + this->Makefile->AddInstallGenerator(CreateInstallFilesGenerator( + this->Makefile, absFiles, ica, programs, destination)); // Tell the global generator about any installation component names // specified. @@ -920,7 +942,8 @@ bool cmInstallCommand::HandleDirectoryMode( DoingPermsDir, DoingPermsMatch, DoingConfigurations, - DoingComponent + DoingComponent, + DoingType }; Doing doing = DoingDirs; bool in_match_mode = false; @@ -934,6 +957,7 @@ bool cmInstallCommand::HandleDirectoryMode( std::vector configurations; std::string component = this->DefaultComponentName; std::string literal_args; + std::string type; for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "DESTINATION") { if (in_match_mode) { @@ -946,6 +970,17 @@ bool cmInstallCommand::HandleDirectoryMode( // Switch to setting the destination property. doing = DoingDestination; + } else if (args[i] == "TYPE") { + if (in_match_mode) { + std::ostringstream e; + e << args[0] << " does not allow \"" << args[i] + << "\" after PATTERN or REGEX."; + this->SetError(e.str()); + return false; + } + + // Switch to setting the type. + doing = DoingType; } else if (args[i] == "OPTIONAL") { if (in_match_mode) { std::ostringstream e; @@ -1106,6 +1141,17 @@ bool cmInstallCommand::HandleDirectoryMode( } else if (doing == DoingDestination) { destination = args[i].c_str(); doing = DoingNone; + } else if (doing == DoingType) { + if (allowedTypes.count(args[i]) == 0) { + std::ostringstream e; + e << args[0] << " given non-type \"" << args[i] + << "\" with TYPE argument."; + this->SetError(e.str()); + return false; + } + + type = args[i]; + doing = DoingNone; } else if (doing == DoingPattern) { // Convert the pattern to a regular expression. Require a // leading slash and trailing end-of-string in the matched @@ -1179,10 +1225,22 @@ bool cmInstallCommand::HandleDirectoryMode( if (dirs.empty()) { return true; } + std::string destinationStr; if (!destination) { - // A destination is required. + if (type.empty()) { + // A destination is required. + std::ostringstream e; + e << args[0] << " given no DESTINATION!"; + this->SetError(e.str()); + return false; + } + destinationStr = this->GetDestinationForType(nullptr, type); + destination = destinationStr.c_str(); + } else if (!type.empty()) { std::ostringstream e; - e << args[0] << " given no DESTINATION!"; + e << args[0] + << " given both TYPE and DESTINATION arguments. You may only specify " + "one."; this->SetError(e.str()); return false; } @@ -1456,3 +1514,163 @@ bool cmInstallCommand::CheckCMP0006(bool& failure) } return false; } + +std::string cmInstallCommand::GetDestination( + const cmInstallCommandArguments* args, const std::string& varName, + const std::string& guess) +{ + if (args && !args->GetDestination().empty()) { + return args->GetDestination(); + } + std::string val = this->Makefile->GetSafeDefinition(varName); + if (!val.empty()) { + return val; + } + return guess; +} + +std::string cmInstallCommand::GetRuntimeDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_BINDIR", "bin"); +} + +std::string cmInstallCommand::GetSbinDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_SBINDIR", "sbin"); +} + +std::string cmInstallCommand::GetArchiveDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); +} + +std::string cmInstallCommand::GetLibraryDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); +} + +std::string cmInstallCommand::GetIncludeDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_INCLUDEDIR", "include"); +} + +std::string cmInstallCommand::GetSysconfDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_SYSCONFDIR", "etc"); +} + +std::string cmInstallCommand::GetSharedStateDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_SHAREDSTATEDIR", "com"); +} + +std::string cmInstallCommand::GetLocalStateDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_LOCALSTATEDIR", "var"); +} + +std::string cmInstallCommand::GetRunStateDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_RUNSTATEDIR", + this->GetLocalStateDestination(nullptr) + + "/run"); +} + +std::string cmInstallCommand::GetDataRootDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_DATAROOTDIR", "share"); +} + +std::string cmInstallCommand::GetDataDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_DATADIR", + this->GetDataRootDestination(nullptr)); +} + +std::string cmInstallCommand::GetInfoDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_INFODIR", + this->GetDataRootDestination(nullptr) + "/info"); +} + +std::string cmInstallCommand::GetLocaleDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_LOCALEDIR", + this->GetDataRootDestination(nullptr) + + "/locale"); +} + +std::string cmInstallCommand::GetManDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_MANDIR", + this->GetDataRootDestination(nullptr) + "/man"); +} + +std::string cmInstallCommand::GetDocDestination( + const cmInstallCommandArguments* args) +{ + return this->GetDestination(args, "CMAKE_INSTALL_DOCDIR", + this->GetDataRootDestination(nullptr) + "/doc"); +} + +std::string cmInstallCommand::GetDestinationForType( + const cmInstallCommandArguments* args, const std::string& type) +{ + if (args && !args->GetDestination().empty()) { + return args->GetDestination(); + } + if (type == "BIN") { + return this->GetRuntimeDestination(nullptr); + } + if (type == "SBIN") { + return this->GetSbinDestination(nullptr); + } + if (type == "SYSCONF") { + return this->GetSysconfDestination(nullptr); + } + if (type == "SHAREDSTATE") { + return this->GetSharedStateDestination(nullptr); + } + if (type == "LOCALSTATE") { + return this->GetLocalStateDestination(nullptr); + } + if (type == "RUNSTATE") { + return this->GetRunStateDestination(nullptr); + } + if (type == "LIB") { + return this->GetLibraryDestination(nullptr); + } + if (type == "INCLUDE") { + return this->GetIncludeDestination(nullptr); + } + if (type == "DATA") { + return this->GetDataDestination(nullptr); + } + if (type == "INFO") { + return this->GetInfoDestination(nullptr); + } + if (type == "LOCALE") { + return this->GetLocaleDestination(nullptr); + } + if (type == "MAN") { + return this->GetManDestination(nullptr); + } + if (type == "DOC") { + return this->GetDocDestination(nullptr); + } + return ""; +} diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 8bd0159..202c438 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -11,6 +11,7 @@ #include "cmCommand.h" class cmExecutionStatus; +class cmInstallCommandArguments; /** \class cmInstallCommand * \brief Specifies where to install some files @@ -45,6 +46,27 @@ private: std::vector& absFiles); bool CheckCMP0006(bool& failure); + std::string GetDestination(const cmInstallCommandArguments* args, + const std::string& varName, + const std::string& guess); + std::string GetRuntimeDestination(const cmInstallCommandArguments* args); + std::string GetSbinDestination(const cmInstallCommandArguments* args); + std::string GetArchiveDestination(const cmInstallCommandArguments* args); + std::string GetLibraryDestination(const cmInstallCommandArguments* args); + std::string GetIncludeDestination(const cmInstallCommandArguments* args); + std::string GetSysconfDestination(const cmInstallCommandArguments* args); + std::string GetSharedStateDestination(const cmInstallCommandArguments* args); + std::string GetLocalStateDestination(const cmInstallCommandArguments* args); + std::string GetRunStateDestination(const cmInstallCommandArguments* args); + std::string GetDataRootDestination(const cmInstallCommandArguments* args); + std::string GetDataDestination(const cmInstallCommandArguments* args); + std::string GetInfoDestination(const cmInstallCommandArguments* args); + std::string GetLocaleDestination(const cmInstallCommandArguments* args); + std::string GetManDestination(const cmInstallCommandArguments* args); + std::string GetDocDestination(const cmInstallCommandArguments* args); + std::string GetDestinationForType(const cmInstallCommandArguments* args, + const std::string& type); + std::string DefaultComponentName; }; diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx index 2d6dc12..63bdb00 100644 --- a/Source/cmInstallCommandArguments.cxx +++ b/Source/cmInstallCommandArguments.cxx @@ -29,6 +29,7 @@ cmInstallCommandArguments::cmInstallCommandArguments( , Optional(&Parser, "OPTIONAL", &ArgumentGroup) , NamelinkOnly(&Parser, "NAMELINK_ONLY", &ArgumentGroup) , NamelinkSkip(&Parser, "NAMELINK_SKIP", &ArgumentGroup) + , Type(&Parser, "TYPE", &ArgumentGroup) , GenericArguments(nullptr) , DefaultComponentName(defaultComponent) { @@ -145,6 +146,11 @@ bool cmInstallCommandArguments::HasNamelinkComponent() const return false; } +const std::string& cmInstallCommandArguments::GetType() const +{ + return this->Type.GetString(); +} + const std::vector& cmInstallCommandArguments::GetConfigurations() const { diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h index ee6e865..425e58a 100644 --- a/Source/cmInstallCommandArguments.h +++ b/Source/cmInstallCommandArguments.h @@ -35,6 +35,7 @@ public: bool GetNamelinkOnly() const; bool GetNamelinkSkip() const; bool HasNamelinkComponent() const; + const std::string& GetType() const; // once HandleDirectoryMode() is also switched to using // cmInstallCommandArguments then these two functions can become non-static @@ -55,6 +56,7 @@ private: cmCAEnabler Optional; cmCAEnabler NamelinkOnly; cmCAEnabler NamelinkSkip; + cmCAString Type; std::string DestinationString; std::string PermissionsString; diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt new file mode 100644 index 0000000..c847c43 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at DIRECTORY-DESTINATION-TYPE\.cmake:[0-9]+ \(install\): + install DIRECTORY given both TYPE and DESTINATION arguments\. You may only + specify one\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake new file mode 100644 index 0000000..4404d6b --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake @@ -0,0 +1 @@ +install(DIRECTORY dir TYPE BIN DESTINATION mybin) diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake new file mode 100644 index 0000000..fb393e3 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake @@ -0,0 +1,42 @@ +set(_check_files + [[mybin]] + [[mybin/dir]] + [[mybin/dir/empty\.txt]] + [[mycom]] + [[mycom/dir]] + [[mycom/dir/empty\.txt]] + [[mydoc]] + [[mydoc/dir]] + [[mydoc/dir/empty\.txt]] + [[myetc]] + [[myetc/dir]] + [[myetc/dir/empty\.txt]] + [[myinclude]] + [[myinclude/dir]] + [[myinclude/dir/empty\.txt]] + [[myinfo]] + [[myinfo/dir]] + [[myinfo/dir/empty\.txt]] + [[mylib]] + [[mylib/dir]] + [[mylib/dir/empty\.txt]] + [[mylocale]] + [[mylocale/dir]] + [[mylocale/dir/empty\.txt]] + [[myman]] + [[myman/dir]] + [[myman/dir/empty\.txt]] + [[myrun]] + [[myrun/dir]] + [[myrun/dir/empty\.txt]] + [[mysbin]] + [[mysbin/dir]] + [[mysbin/dir/empty\.txt]] + [[myshare]] + [[myshare/dir]] + [[myshare/dir/empty\.txt]] + [[myvar]] + [[myvar/dir]] + [[myvar/dir/empty\.txt]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake new file mode 100644 index 0000000..53e95f8 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake @@ -0,0 +1,13 @@ +install(DIRECTORY dir TYPE BIN) +install(DIRECTORY dir TYPE SBIN) +install(DIRECTORY dir TYPE LIB) +install(DIRECTORY dir TYPE INCLUDE) +install(DIRECTORY dir TYPE SYSCONF) +install(DIRECTORY dir TYPE SHAREDSTATE) +install(DIRECTORY dir TYPE LOCALSTATE) +install(DIRECTORY dir TYPE RUNSTATE) +install(DIRECTORY dir TYPE DATA) +install(DIRECTORY dir TYPE INFO) +install(DIRECTORY dir TYPE LOCALE) +install(DIRECTORY dir TYPE MAN) +install(DIRECTORY dir TYPE DOC) diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake new file mode 100644 index 0000000..03f7bd6 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake @@ -0,0 +1,24 @@ +set(_check_files + [[myshare]] + [[myshare/dir]] + [[myshare/dir/empty\.txt]] + [[myshare/doc]] + [[myshare/doc/dir]] + [[myshare/doc/dir/empty\.txt]] + [[myshare/info]] + [[myshare/info/dir]] + [[myshare/info/dir/empty\.txt]] + [[myshare/locale]] + [[myshare/locale/dir]] + [[myshare/locale/dir/empty\.txt]] + [[myshare/man]] + [[myshare/man/dir]] + [[myshare/man/dir/empty.txt]] + [[myvar]] + [[myvar/dir]] + [[myvar/dir/empty\.txt]] + [[myvar/run]] + [[myvar/run/dir]] + [[myvar/run/dir/empty\.txt]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake new file mode 100644 index 0000000..e797abb --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake @@ -0,0 +1,7 @@ +install(DIRECTORY dir TYPE LOCALSTATE) +install(DIRECTORY dir TYPE RUNSTATE) +install(DIRECTORY dir TYPE DATA) +install(DIRECTORY dir TYPE INFO) +install(DIRECTORY dir TYPE LOCALE) +install(DIRECTORY dir TYPE MAN) +install(DIRECTORY dir TYPE DOC) diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake new file mode 100644 index 0000000..03fa3c8 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake @@ -0,0 +1,42 @@ +set(_check_files + [[bin]] + [[bin/dir]] + [[bin/dir/empty\.txt]] + [[com]] + [[com/dir]] + [[com/dir/empty\.txt]] + [[etc]] + [[etc/dir]] + [[etc/dir/empty\.txt]] + [[include]] + [[include/dir]] + [[include/dir/empty\.txt]] + [[lib]] + [[lib/dir]] + [[lib/dir/empty\.txt]] + [[sbin]] + [[sbin/dir]] + [[sbin/dir/empty\.txt]] + [[share]] + [[share/dir]] + [[share/dir/empty\.txt]] + [[share/doc]] + [[share/doc/dir]] + [[share/doc/dir/empty\.txt]] + [[share/info]] + [[share/info/dir]] + [[share/info/dir/empty\.txt]] + [[share/locale]] + [[share/locale/dir]] + [[share/locale/dir/empty\.txt]] + [[share/man]] + [[share/man/dir]] + [[share/man/dir/empty\.txt]] + [[var]] + [[var/dir]] + [[var/dir/empty\.txt]] + [[var/run]] + [[var/run/dir]] + [[var/run/dir/empty\.txt]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE.cmake new file mode 100644 index 0000000..53e95f8 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-TYPE.cmake @@ -0,0 +1,13 @@ +install(DIRECTORY dir TYPE BIN) +install(DIRECTORY dir TYPE SBIN) +install(DIRECTORY dir TYPE LIB) +install(DIRECTORY dir TYPE INCLUDE) +install(DIRECTORY dir TYPE SYSCONF) +install(DIRECTORY dir TYPE SHAREDSTATE) +install(DIRECTORY dir TYPE LOCALSTATE) +install(DIRECTORY dir TYPE RUNSTATE) +install(DIRECTORY dir TYPE DATA) +install(DIRECTORY dir TYPE INFO) +install(DIRECTORY dir TYPE LOCALE) +install(DIRECTORY dir TYPE MAN) +install(DIRECTORY dir TYPE DOC) diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt new file mode 100644 index 0000000..ce8fc23 --- /dev/null +++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at FILES-DESTINATION-TYPE\.cmake:[0-9]+ \(install\): + install FILES given both TYPE and DESTINATION arguments\. You may only + specify one\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake b/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake new file mode 100644 index 0000000..576c98f --- /dev/null +++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake @@ -0,0 +1 @@ +install(FILES main.c TYPE BIN DESTINATION mybin) diff --git a/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake new file mode 100644 index 0000000..dfb90cf --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake @@ -0,0 +1,29 @@ +set(_check_files + [[mybin]] + [[mybin/main\.c]] + [[mycom]] + [[mycom/main\.c]] + [[mydoc]] + [[mydoc/main\.c]] + [[myetc]] + [[myetc/main\.c]] + [[myinclude]] + [[myinclude/main\.c]] + [[myinfo]] + [[myinfo/main\.c]] + [[mylib]] + [[mylib/main\.c]] + [[mylocale]] + [[mylocale/main\.c]] + [[myman]] + [[myman/main\.c]] + [[myrun]] + [[myrun/main\.c]] + [[mysbin]] + [[mysbin/main\.c]] + [[myshare]] + [[myshare/main\.c]] + [[myvar]] + [[myvar/main\.c]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/FILES-TYPE-Cache.cmake b/Tests/RunCMake/install/FILES-TYPE-Cache.cmake new file mode 100644 index 0000000..2e2bfc7 --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE-Cache.cmake @@ -0,0 +1,13 @@ +install(FILES main.c TYPE BIN) +install(FILES main.c TYPE SBIN) +install(FILES main.c TYPE LIB) +install(FILES main.c TYPE INCLUDE) +install(FILES main.c TYPE SYSCONF) +install(FILES main.c TYPE SHAREDSTATE) +install(FILES main.c TYPE LOCALSTATE) +install(FILES main.c TYPE RUNSTATE) +install(FILES main.c TYPE DATA) +install(FILES main.c TYPE INFO) +install(FILES main.c TYPE LOCALE) +install(FILES main.c TYPE MAN) +install(FILES main.c TYPE DOC) diff --git a/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake new file mode 100644 index 0000000..e58c80a --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake @@ -0,0 +1,17 @@ +set(_check_files + [[myshare]] + [[myshare/doc]] + [[myshare/doc/main\.c]] + [[myshare/info]] + [[myshare/info/main\.c]] + [[myshare/locale]] + [[myshare/locale/main\.c]] + [[myshare/main\.c]] + [[myshare/man]] + [[myshare/man/main\.c]] + [[myvar]] + [[myvar/main\.c]] + [[myvar/run]] + [[myvar/run/main\.c]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake b/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake new file mode 100644 index 0000000..d7d5aaa --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake @@ -0,0 +1,7 @@ +install(FILES main.c TYPE LOCALSTATE) +install(FILES main.c TYPE RUNSTATE) +install(FILES main.c TYPE DATA) +install(FILES main.c TYPE INFO) +install(FILES main.c TYPE LOCALE) +install(FILES main.c TYPE MAN) +install(FILES main.c TYPE DOC) diff --git a/Tests/RunCMake/install/FILES-TYPE-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-all-check.cmake new file mode 100644 index 0000000..c4ec661 --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE-all-check.cmake @@ -0,0 +1,29 @@ +set(_check_files + [[bin]] + [[bin/main\.c]] + [[com]] + [[com/main\.c]] + [[etc]] + [[etc/main\.c]] + [[include]] + [[include/main\.c]] + [[lib]] + [[lib/main\.c]] + [[sbin]] + [[sbin/main\.c]] + [[share]] + [[share/doc]] + [[share/doc/main\.c]] + [[share/info]] + [[share/info/main\.c]] + [[share/locale]] + [[share/locale/main\.c]] + [[share/main\.c]] + [[share/man]] + [[share/man/main\.c]] + [[var]] + [[var/main\.c]] + [[var/run]] + [[var/run/main\.c]] + ) +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/FILES-TYPE.cmake b/Tests/RunCMake/install/FILES-TYPE.cmake new file mode 100644 index 0000000..2e2bfc7 --- /dev/null +++ b/Tests/RunCMake/install/FILES-TYPE.cmake @@ -0,0 +1,13 @@ +install(FILES main.c TYPE BIN) +install(FILES main.c TYPE SBIN) +install(FILES main.c TYPE LIB) +install(FILES main.c TYPE INCLUDE) +install(FILES main.c TYPE SYSCONF) +install(FILES main.c TYPE SHAREDSTATE) +install(FILES main.c TYPE LOCALSTATE) +install(FILES main.c TYPE RUNSTATE) +install(FILES main.c TYPE DATA) +install(FILES main.c TYPE INFO) +install(FILES main.c TYPE LOCALE) +install(FILES main.c TYPE MAN) +install(FILES main.c TYPE DOC) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index ec022ca..f7e1dee 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -65,6 +65,12 @@ run_cmake(CMP0062-NEW) run_cmake(CMP0062-WARN) run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all) run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc) +run_cmake(FILES-DESTINATION-TYPE) +run_cmake(DIRECTORY-DESTINATION-TYPE) + +if(APPLE) + run_cmake(TARGETS-Apple-Defaults) +endif() if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]") run_install_test(FILES-TARGET_OBJECTS) @@ -74,6 +80,46 @@ run_install_test(TARGETS-InstallFromSubDir) run_install_test(TARGETS-OPTIONAL) run_install_test(FILES-OPTIONAL) run_install_test(DIRECTORY-OPTIONAL) +run_install_test(TARGETS-Defaults) + +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_BINDIR:PATH=mybin" + "-DCMAKE_INSTALL_LIBDIR:PATH=mylib" + "-DCMAKE_INSTALL_INCLUDEDIR:PATH=myinclude" + ) +run_install_test(TARGETS-Defaults-Cache) +unset(RunCMake_TEST_OPTIONS) + +run_install_test(FILES-TYPE) +run_install_test(DIRECTORY-TYPE) + +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_BINDIR:PATH=mybin" + "-DCMAKE_INSTALL_SBINDIR:PATH=mysbin" + "-DCMAKE_INSTALL_LIBEXECDIR:PATH=mylibexec" + "-DCMAKE_INSTALL_LIBDIR:PATH=mylib" + "-DCMAKE_INSTALL_INCLUDEDIR:PATH=myinclude" + "-DCMAKE_INSTALL_SYSCONFDIR:PATH=myetc" + "-DCMAKE_INSTALL_SHAREDSTATEDIR:PATH=mycom" + "-DCMAKE_INSTALL_LOCALSTATEDIR:PATH=myvar" + "-DCMAKE_INSTALL_RUNSTATEDIR:PATH=myrun" + "-DCMAKE_INSTALL_DATADIR:PATH=myshare" + "-DCMAKE_INSTALL_INFODIR:PATH=myinfo" + "-DCMAKE_INSTALL_LOCALEDIR:PATH=mylocale" + "-DCMAKE_INSTALL_MANDIR:PATH=myman" + "-DCMAKE_INSTALL_DOCDIR:PATH=mydoc" + ) +run_install_test(FILES-TYPE-Cache) +run_install_test(DIRECTORY-TYPE-Cache) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_LOCALSTATEDIR:PATH=myvar" + "-DCMAKE_INSTALL_DATAROOTDIR:PATH=myshare" + ) +run_install_test(FILES-TYPE-CacheDependent) +run_install_test(DIRECTORY-TYPE-CacheDependent) +unset(RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug") run_install_test(TARGETS-OUTPUT_NAME) diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt b/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt b/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt new file mode 100644 index 0000000..645882f --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt @@ -0,0 +1,12 @@ +^CMake Error at TARGETS-Apple-Defaults\.cmake:[0-9]+ \(install\): + install TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable + target "exe"\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) + + +CMake Error at TARGETS-Apple-Defaults\.cmake:[0-9]+ \(install\): + install TARGETS given no FRAMEWORK DESTINATION for shared library FRAMEWORK + target "lib1"\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake new file mode 100644 index 0000000..b60c318 --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake @@ -0,0 +1,8 @@ +enable_language(C) + +add_executable(exe MACOSX_BUNDLE main.c) +add_library(lib1 SHARED obj1.c) +set_property(TARGET lib1 PROPERTY FRAMEWORK ON) + +install(TARGETS exe) +install(TARGETS lib1) diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake new file mode 100644 index 0000000..6fc735c --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake @@ -0,0 +1,49 @@ +if(WIN32) + set(_check_files + [[lib3]] + [[lib3/(lib)?lib3\.(dll\.a|lib)]] + [[lib4]] + [[lib4/(lib)?lib4\.dll]] + [[mybin]] + [[mybin/exe\.exe]] + [[mybin/(lib)?lib1\.dll]] + [[myinclude]] + [[myinclude/obj4\.h]] + [[myinclude/obj5\.h]] + [[mylib]] + [[mylib/(lib)?lib1\.(dll\.a|lib)]] + [[mylib/(lib)?lib2\.(a|lib)]] + ) +elseif(CYGWIN) + set(_check_files + [[lib3]] + [[lib3/liblib3\.dll\.a]] + [[lib4]] + [[lib4/cyglib4\.dll]] + [[mybin]] + [[mybin/exe\.exe]] + [[mybin/cyglib1\.dll]] + [[myinclude]] + [[myinclude/obj4\.h]] + [[myinclude/obj5\.h]] + [[mylib]] + [[mylib/liblib1\.dll\.a]] + [[mylib/liblib2\.a]] + ) +else() + set(_check_files + [[lib3]] + [[lib3/liblib3\.(dylib|so)]] + [[lib4]] + [[lib4/liblib4\.(dylib|so)]] + [[mybin]] + [[mybin/exe]] + [[myinclude]] + [[myinclude/obj4\.h]] + [[myinclude/obj5\.h]] + [[mylib]] + [[mylib/liblib1\.(dylib|so)]] + [[mylib/liblib2\.a]] + ) +endif() +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake new file mode 100644 index 0000000..bfd8c2c --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake @@ -0,0 +1,19 @@ +enable_language(C) + +add_executable(exe main.c) +add_library(lib1 SHARED obj1.c) +add_library(lib2 STATIC obj3.c) +add_library(lib3 SHARED obj4.c) +set_property(TARGET lib3 PROPERTY PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj4.h) +add_library(lib4 SHARED obj5.c) +set_property(TARGET lib4 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj5.h) + +install(TARGETS exe lib1 lib2) +install(TARGETS lib3 + LIBRARY DESTINATION lib3 + ARCHIVE DESTINATION lib3 + ) +install(TARGETS lib4 + LIBRARY DESTINATION lib4 + RUNTIME DESTINATION lib4 + ) diff --git a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake new file mode 100644 index 0000000..59209e6 --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake @@ -0,0 +1,49 @@ +if(WIN32) + set(_check_files + [[bin]] + [[bin/exe\.exe]] + [[bin/(lib)?lib1\.dll]] + [[include]] + [[include/obj4\.h]] + [[include/obj5\.h]] + [[lib]] + [[lib/(lib)?lib1\.(dll\.a|lib)]] + [[lib/(lib)?lib2\.(a|lib)]] + [[lib3]] + [[lib3/(lib)?lib3\.(dll\.a|lib)]] + [[lib4]] + [[lib4/(lib)?lib4\.dll]] + ) +elseif(CYGWIN) + set(_check_files + [[bin]] + [[bin/exe\.exe]] + [[bin/cyglib1\.dll]] + [[include]] + [[include/obj4\.h]] + [[include/obj5\.h]] + [[lib]] + [[lib/liblib1\.dll\.a]] + [[lib/liblib2\.a]] + [[lib3]] + [[lib3/liblib3\.dll\.a]] + [[lib4]] + [[lib4/cyglib4\.dll]] + ) +else() + set(_check_files + [[bin]] + [[bin/exe]] + [[include]] + [[include/obj4\.h]] + [[include/obj5\.h]] + [[lib]] + [[lib/liblib1\.(dylib|so)]] + [[lib/liblib2\.a]] + [[lib3]] + [[lib3/liblib3\.(dylib|so)]] + [[lib4]] + [[lib4/liblib4\.(dylib|so)]] + ) +endif() +check_installed("^${_check_files}$") diff --git a/Tests/RunCMake/install/TARGETS-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Defaults.cmake new file mode 100644 index 0000000..bfd8c2c --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-Defaults.cmake @@ -0,0 +1,19 @@ +enable_language(C) + +add_executable(exe main.c) +add_library(lib1 SHARED obj1.c) +add_library(lib2 STATIC obj3.c) +add_library(lib3 SHARED obj4.c) +set_property(TARGET lib3 PROPERTY PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj4.h) +add_library(lib4 SHARED obj5.c) +set_property(TARGET lib4 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj5.h) + +install(TARGETS exe lib1 lib2) +install(TARGETS lib3 + LIBRARY DESTINATION lib3 + ARCHIVE DESTINATION lib3 + ) +install(TARGETS lib4 + LIBRARY DESTINATION lib4 + RUNTIME DESTINATION lib4 + ) diff --git a/Tests/RunCMake/install/obj3.c b/Tests/RunCMake/install/obj3.c new file mode 100644 index 0000000..991fed3 --- /dev/null +++ b/Tests/RunCMake/install/obj3.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int obj3(void) +{ + return 0; +} diff --git a/Tests/RunCMake/install/obj3.h b/Tests/RunCMake/install/obj3.h new file mode 100644 index 0000000..9e8bb76 --- /dev/null +++ b/Tests/RunCMake/install/obj3.h @@ -0,0 +1,6 @@ +#ifndef OBJ3_H +#define OBJ3_H + +int obj3(void); + +#endif /* OBJ3_H */ diff --git a/Tests/RunCMake/install/obj4.c b/Tests/RunCMake/install/obj4.c new file mode 100644 index 0000000..edd6172 --- /dev/null +++ b/Tests/RunCMake/install/obj4.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int obj4(void) +{ + return 0; +} diff --git a/Tests/RunCMake/install/obj4.h b/Tests/RunCMake/install/obj4.h new file mode 100644 index 0000000..6195aa7 --- /dev/null +++ b/Tests/RunCMake/install/obj4.h @@ -0,0 +1,6 @@ +#ifndef OBJ4_H +#define OBJ4_H + +int obj4(void); + +#endif /* OBJ4_H */ diff --git a/Tests/RunCMake/install/obj5.c b/Tests/RunCMake/install/obj5.c new file mode 100644 index 0000000..df3e997 --- /dev/null +++ b/Tests/RunCMake/install/obj5.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int obj5(void) +{ + return 0; +} diff --git a/Tests/RunCMake/install/obj5.h b/Tests/RunCMake/install/obj5.h new file mode 100644 index 0000000..a16a1b0 --- /dev/null +++ b/Tests/RunCMake/install/obj5.h @@ -0,0 +1,6 @@ +#ifndef OBJ5_H +#define OBJ5_H + +int obj5(void); + +#endif /* OBJ5_H */ ----------------------------------------------------------------------- Summary of changes: Help/command/install.rst | 113 ++++++- Help/release/dev/install-defaults.rst | 12 + Source/cmInstallCommand.cxx | 376 ++++++++++++++++----- Source/cmInstallCommand.h | 22 ++ Source/cmInstallCommandArguments.cxx | 6 + Source/cmInstallCommandArguments.h | 2 + .../DIRECTORY-DESTINATION-TYPE-result.txt} | 0 .../install/DIRECTORY-DESTINATION-TYPE-stderr.txt | 5 + .../install/DIRECTORY-DESTINATION-TYPE.cmake | 1 + .../install/DIRECTORY-TYPE-Cache-all-check.cmake | 42 +++ Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake | 13 + .../DIRECTORY-TYPE-CacheDependent-all-check.cmake | 24 ++ .../install/DIRECTORY-TYPE-CacheDependent.cmake | 7 + .../install/DIRECTORY-TYPE-all-check.cmake | 42 +++ Tests/RunCMake/install/DIRECTORY-TYPE.cmake | 13 + .../FILES-DESTINATION-TYPE-result.txt} | 0 .../install/FILES-DESTINATION-TYPE-stderr.txt | 5 + .../RunCMake/install/FILES-DESTINATION-TYPE.cmake | 1 + .../install/FILES-TYPE-Cache-all-check.cmake | 29 ++ Tests/RunCMake/install/FILES-TYPE-Cache.cmake | 13 + .../FILES-TYPE-CacheDependent-all-check.cmake | 17 + .../install/FILES-TYPE-CacheDependent.cmake | 7 + Tests/RunCMake/install/FILES-TYPE-all-check.cmake | 29 ++ Tests/RunCMake/install/FILES-TYPE.cmake | 13 + Tests/RunCMake/install/RunCMakeTest.cmake | 46 +++ .../TARGETS-Apple-Defaults-result.txt} | 0 .../install/TARGETS-Apple-Defaults-stderr.txt | 12 + .../RunCMake/install/TARGETS-Apple-Defaults.cmake | 8 + .../install/TARGETS-Defaults-Cache-all-check.cmake | 49 +++ .../RunCMake/install/TARGETS-Defaults-Cache.cmake | 19 ++ .../install/TARGETS-Defaults-all-check.cmake | 49 +++ Tests/RunCMake/install/TARGETS-Defaults.cmake | 19 ++ Tests/RunCMake/install/obj3.c | 7 + Tests/RunCMake/install/obj3.h | 6 + Tests/RunCMake/install/obj4.c | 7 + Tests/RunCMake/install/obj4.h | 6 + Tests/RunCMake/install/obj5.c | 7 + Tests/RunCMake/install/obj5.h | 6 + 38 files changed, 950 insertions(+), 83 deletions(-) create mode 100644 Help/release/dev/install-defaults.rst copy Tests/RunCMake/{while/MissingArgument-result.txt => install/DIRECTORY-DESTINATION-TYPE-result.txt} (100%) create mode 100644 Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt create mode 100644 Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake create mode 100644 Tests/RunCMake/install/DIRECTORY-TYPE.cmake copy Tests/RunCMake/{while/MissingArgument-result.txt => install/FILES-DESTINATION-TYPE-result.txt} (100%) create mode 100644 Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt create mode 100644 Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE-Cache.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE-all-check.cmake create mode 100644 Tests/RunCMake/install/FILES-TYPE.cmake copy Tests/RunCMake/{while/MissingArgument-result.txt => install/TARGETS-Apple-Defaults-result.txt} (100%) create mode 100644 Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt create mode 100644 Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake create mode 100644 Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake create mode 100644 Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake create mode 100644 Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake create mode 100644 Tests/RunCMake/install/TARGETS-Defaults.cmake create mode 100644 Tests/RunCMake/install/obj3.c create mode 100644 Tests/RunCMake/install/obj3.h create mode 100644 Tests/RunCMake/install/obj4.c create mode 100644 Tests/RunCMake/install/obj4.h create mode 100644 Tests/RunCMake/install/obj5.c create mode 100644 Tests/RunCMake/install/obj5.h hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 9 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 9 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-356-g8db4bd1 Message-ID: <20181109050305.6791A127A2F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 8db4bd115c566460986ddd2f7a8f4f90ee5baf26 (commit) from 17e98e00c449ebdceac980c0ce65c800030605db (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8db4bd115c566460986ddd2f7a8f4f90ee5baf26 commit 8db4bd115c566460986ddd2f7a8f4f90ee5baf26 Author: Kitware Robot AuthorDate: Fri Nov 9 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Fri Nov 9 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 5f7dd8a..3671d53 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 13) -set(CMake_VERSION_PATCH 20181108) +set(CMake_VERSION_PATCH 20181109) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 9 10:43:10 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 9 Nov 2018 10:43:10 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-367-g65522e5 Message-ID: <20181109154310.3CB5412671B@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 65522e5e0ef95b7424714ec4d67345bf00e9b8bd (commit) via 9463d73cc4d58b190fac0cac6aeee424b5d29514 (commit) via f29e2292c90d4fbdadce041b1c9d649aca3c602b (commit) via 860338491ee96274ac110459b3b316149d4585f7 (commit) via e855bd5248bbb7b77b45e269e4fa098b29c9e889 (commit) via 8ba2a8d4a415d2288786a0d56e90b3d7693ad32e (commit) via 85498fccd8ac1dd7345d995e52e1bf63d663071e (commit) via e24ef9694275b9345bf08cf46ca1cf064b34813b (commit) via e4554149c476e9eb9fe00368b2ac1ac7ac9ffe5c (commit) via 3de551cc22bf80f63ec9f05e3e934f42f79b8965 (commit) via eba7273c203f0698ccd716604cc298b7da1d3ee6 (commit) from 8db4bd115c566460986ddd2f7a8f4f90ee5baf26 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=65522e5e0ef95b7424714ec4d67345bf00e9b8bd commit 65522e5e0ef95b7424714ec4d67345bf00e9b8bd Merge: 9463d73 f29e229 Author: Brad King AuthorDate: Fri Nov 9 15:37:07 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 9 10:37:14 2018 -0500 Merge topic 'cpack-improve-unknown-generator-error' f29e2292c9 cpack: When given an unknown generator print out all valid generators eba7273c20 cpack: Better error message when generator doesn't exist. Acked-by: Kitware Robot Acked-by: David Cole Merge-request: !2580 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9463d73cc4d58b190fac0cac6aeee424b5d29514 commit 9463d73cc4d58b190fac0cac6aeee424b5d29514 Merge: 8db4bd1 8603384 Author: Brad King AuthorDate: Fri Nov 9 15:34:40 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 9 10:35:28 2018 -0500 Merge topic 'env' 860338491e Help: Describe $CACHE and $ENV as operators e855bd5248 Help: Document if(DEFINED ENV{name}) 8ba2a8d4a4 Help: short/long variable reference in if command 85498fccd8 Help: Provide backreferences. e24ef96942 Help: New section on Environment Variables in cmake-language.7 e4554149c4 Help: Remove over-precise clause. 3de551cc22 Help: Clarify effect of set(ENV{..} ..) and unset(ENV{..}) Acked-by: Kitware Robot Merge-request: !2538 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f29e2292c90d4fbdadce041b1c9d649aca3c602b commit f29e2292c90d4fbdadce041b1c9d649aca3c602b Author: Robert Maynard AuthorDate: Thu Nov 8 09:27:28 2018 -0500 Commit: Brad King CommitDate: Thu Nov 8 19:07:24 2018 -0500 cpack: When given an unknown generator print out all valid generators This makes cpack behavior match cmake when passed an invalid generator diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 3df1b36..7cf69fc 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -21,6 +21,7 @@ #include "cmCPackLog.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" +#include "cmDocumentationFormatter.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateSnapshot.h" @@ -360,7 +361,19 @@ int main(int argc, char const* const* argv) cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Could not create CPack generator: " << gen << std::endl); - + // Print out all the valid generators + cmDocumentation generatorDocs; + std::vector v; + for (auto const& g : generators.GetGeneratorsList()) { + cmDocumentationEntry e; + e.Name = g.first; + e.Brief = g.second; + v.push_back(std::move(e)); + } + generatorDocs.SetSection("Generators", v); + std::cerr << "\n"; + generatorDocs.PrintDocumentation(cmDocumentation::ListGenerators, + std::cerr); parsed = 0; } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=860338491ee96274ac110459b3b316149d4585f7 commit 860338491ee96274ac110459b3b316149d4585f7 Author: Joachim Wuttke (l) AuthorDate: Thu Nov 1 11:18:15 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:33:13 2018 +0100 Help: Describe $CACHE and $ENV as operators This resolves issue #18514 Also add a cross-reference to if(DEFINED ENV{var}). diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index efb217d..7a7f0b8 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -241,7 +241,6 @@ Variables that Describe the System /variable/ANDROID /variable/APPLE /variable/BORLAND - /variable/CACHE /variable/CMAKE_CL_64 /variable/CMAKE_COMPILER_2005 /variable/CMAKE_HOST_APPLE @@ -260,7 +259,6 @@ Variables that Describe the System /variable/CMAKE_SYSTEM_PROCESSOR /variable/CMAKE_SYSTEM_VERSION /variable/CYGWIN - /variable/ENV /variable/GHS-MULTI /variable/MINGW /variable/MSVC @@ -599,3 +597,12 @@ Variables for CPack /variable/CPACK_PACKAGING_INSTALL_PREFIX /variable/CPACK_SET_DESTDIR /variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION + +Variable Expansion Operators +============================ + +.. toctree:: + :maxdepth: 1 + + /variable/CACHE + /variable/ENV diff --git a/Help/variable/CACHE.rst b/Help/variable/CACHE.rst index 230739a..2cef27e 100644 --- a/Help/variable/CACHE.rst +++ b/Help/variable/CACHE.rst @@ -1,7 +1,7 @@ CACHE ----- -Read cache variables. +Operator to read cache variables. Use the syntax ``$CACHE{VAR}`` to read cache entry ``VAR``. See the :ref:`cmake-language(7) variables ` @@ -14,4 +14,5 @@ found CMake will search for a cache entry with that name. The ``$CACHE{VAR}`` syntax can be used to do direct cache lookup and ignore any existing normal variable. -See the :command:`set` command to see how to write cache variables. +See the :command:`set` and :command:`unset` commands to see how to +write or remove cache variables. diff --git a/Help/variable/ENV.rst b/Help/variable/ENV.rst index 98677dd..2b43934 100644 --- a/Help/variable/ENV.rst +++ b/Help/variable/ENV.rst @@ -1,8 +1,12 @@ ENV --- -Read environment variables. +Operator to read environment variables. Use the syntax ``$ENV{VAR}`` to read environment variable ``VAR``. -See the :command:`set` command to see how to write environment variables. +To test whether an environment variable is defined, use the signature +``if(DEFINED ENV{})`` of the :command:`if` command. + +See the :command:`set` and :command:`unset` commands to see how to +write or remove environment variables. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e855bd5248bbb7b77b45e269e4fa098b29c9e889 commit e855bd5248bbb7b77b45e269e4fa098b29c9e889 Author: Joachim Wuttke (h) AuthorDate: Thu Nov 1 22:26:32 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:30:05 2018 +0100 Help: Document if(DEFINED ENV{name}) diff --git a/Help/command/if.rst b/Help/command/if.rst index ea5de7f..1cd9965 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -187,10 +187,11 @@ Possible conditions are: ``if( IN_LIST )`` True if the given element is contained in the named list variable. -``if(DEFINED )`` - True if the given variable is defined. It does not matter if the - variable is true or false just if it has been set. (Note macro - arguments are not variables.) +``if(DEFINED |ENV{})`` + True if a variable or environment variable + with given ```` is defined. + The value of the variable does not matter. + Note that macro arguments are not variables. ``if((condition) AND (condition OR (condition)))`` The conditions inside the parenthesis are evaluated first and then @@ -270,6 +271,7 @@ A quoted or bracketed variable or keyword will be interpreted as a string and not dereferenced or interpreted. See policy :policy:`CMP0054`. -There is no short form for environment or cache :ref:`Variable References`. -They can be referenced as ``$ENV{}`` or ``$CACHE{}`` -wherever the above-documented condition syntax accepts . +There is no automatic evaluation for environment or cache +:ref:`Variable References`. Their values must be referenced as +``$ENV{}`` or ``$CACHE{}`` wherever the above-documented +condition syntax accepts ````. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8ba2a8d4a415d2288786a0d56e90b3d7693ad32e commit 8ba2a8d4a415d2288786a0d56e90b3d7693ad32e Author: Joachim Wuttke (l) AuthorDate: Thu Nov 1 11:13:03 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:27:49 2018 +0100 Help: short/long variable reference in if command Explain that the short form of variable references in the if command does not apply to ENV and CACHE vars. diff --git a/Help/command/if.rst b/Help/command/if.rst index 4781f35..ea5de7f 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -231,7 +231,7 @@ which is true because ``var2`` is defined to "var1" which is not a false constant. Automatic evaluation applies in the other cases whenever the -above-documented signature accepts ````: +above-documented condition syntax accepts ````: * The left hand argument to ``MATCHES`` is first checked to see if it is a defined variable, if so the variable's value is used, otherwise the @@ -269,3 +269,7 @@ specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`. A quoted or bracketed variable or keyword will be interpreted as a string and not dereferenced or interpreted. See policy :policy:`CMP0054`. + +There is no short form for environment or cache :ref:`Variable References`. +They can be referenced as ``$ENV{}`` or ``$CACHE{}`` +wherever the above-documented condition syntax accepts . diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 1b5281a..5e5cfff 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -389,7 +389,7 @@ historical considerations.) Variable References ------------------- -A *variable reference* has the form ``${variable_name}`` and is +A *variable reference* has the form ``${}`` and is evaluated inside a `Quoted Argument`_ or an `Unquoted Argument`_. A variable reference is replaced by the value of the variable, or by the empty string if the variable is not set. @@ -405,12 +405,18 @@ the ``$`` is also technically permitted but is discouraged. The `Variables`_ section documents the scope of variable names and how their values are set. -An *environment variable reference* has the form ``$ENV{VAR}``. +An *environment variable reference* has the form ``$ENV{}``. See the `Environment Variables`_ section for more information. -A *cache variable reference* has the form ``$CACHE{VAR}``. +A *cache variable reference* has the form ``$CACHE{}``. See :variable:`CACHE` for more information. +The :command:`if` command has a special condition syntax that +allows for variable references in the short form ```` +instead of ``${}``. +However, environment and cache variables always need to be +referenced as ``$ENV{}`` or ``$CACHE{}``. + Comments -------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=85498fccd8ac1dd7345d995e52e1bf63d663071e commit 85498fccd8ac1dd7345d995e52e1bf63d663071e Author: Joachim Wuttke (h) AuthorDate: Sat Oct 27 16:04:15 2018 +0200 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:27:49 2018 +0100 Help: Provide backreferences. Short intro to pages cmake-variables.7 and cmake-env-variables.7, with backlinks to cmake-language.7. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index 31aa723..edf80f4 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -7,6 +7,14 @@ cmake-env-variables(7) .. contents:: +This page lists environment variables that have special +meaning to CMake. + +For general information on environment variables, see the +:ref:`Environment Variables ` +section in the cmake-language manual. + + Environment Variables that Control the Build ============================================ diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index ef5bb50..1b5281a 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -557,11 +557,11 @@ Otherwise, the variable reference evaluates to an empty string. The ``$CACHE{VAR}`` syntax can be used to do direct cache entry lookups. -The :manual:`cmake-variables(7)` manual documents many variables +The :manual:`cmake-variables(7)` manual documents the many variables that are provided by CMake or have meaning to CMake when set by project code. -.. _`CMake Language Lists`: +.. _`CMake Language Environment Variables`: Environment Variables ===================== @@ -589,6 +589,7 @@ Initialization The :manual:`cmake-env-variables(7)` manual documents environment variables that have special meaning to CMake. +.. _`CMake Language Lists`: Lists ===== diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 9b12fc5..efb217d 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -7,6 +7,14 @@ cmake-variables(7) .. contents:: +This page documents variables that are provided by CMake +or have meaning to CMake when set by project code. + +For general information on variables, see the +:ref:`Variables ` +section in the cmake-language manual. + + Variables that Provide Information ================================== https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e24ef9694275b9345bf08cf46ca1cf064b34813b commit e24ef9694275b9345bf08cf46ca1cf064b34813b Author: Joachim Wuttke (h) AuthorDate: Sat Oct 27 15:53:05 2018 +0200 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:27:49 2018 +0100 Help: New section on Environment Variables in cmake-language.7 diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 0283232..ef5bb50 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -406,7 +406,7 @@ The `Variables`_ section documents the scope of variable names and how their values are set. An *environment variable reference* has the form ``$ENV{VAR}``. -See :variable:`ENV` for more information. +See the `Environment Variables`_ section for more information. A *cache variable reference* has the form ``$CACHE{VAR}``. See :variable:`CACHE` for more information. @@ -563,6 +563,33 @@ by project code. .. _`CMake Language Lists`: +Environment Variables +===================== + +Environment Variables are like ordinary `Variables`_, with the +following differences: + +Scope + Environment variables have global scope in a CMake process. + They are never cached. + +References + `Variable References`_ have the form ``$ENV{}``. + +Initialization + Initial values of the CMake environment variables are those of + the calling process. + Values can be changed using the :command:`set` and :command:`unset` + commands. + These commands only affect the running CMake process, + not the system environment at large. + Changed values are not written back to the calling process, + and they are not seen by subsequent build or test processes. + +The :manual:`cmake-env-variables(7)` manual documents environment +variables that have special meaning to CMake. + + Lists ===== https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e4554149c476e9eb9fe00368b2ac1ac7ac9ffe5c commit e4554149c476e9eb9fe00368b2ac1ac7ac9ffe5c Author: Joachim Wuttke (h) AuthorDate: Sat Oct 27 15:27:31 2018 +0200 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:27:49 2018 +0100 Help: Remove over-precise clause. Section "Variables References" said that environment and cache variables are "evaluated in the same contexts as a normal variable reference". The reader has to guess what "contexts" means in this context. Probably "inside a Quoted Argument or an Unquoted Argument", exactly as for ordinary variable references. But this is exactly what the reader would tacitly assume anyway. Therefore I think the removed clause was unnecessary, and possibly more confusing than helpful. diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 630a86b..0283232 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -405,12 +405,10 @@ the ``$`` is also technically permitted but is discouraged. The `Variables`_ section documents the scope of variable names and how their values are set. -An *environment variable reference* has the form ``$ENV{VAR}`` and -is evaluated in the same contexts as a normal variable reference. +An *environment variable reference* has the form ``$ENV{VAR}``. See :variable:`ENV` for more information. -A *cache variable reference* has the form ``$CACHE{VAR}`` and -is evaluated in the same contexts as a normal variable reference. +A *cache variable reference* has the form ``$CACHE{VAR}``. See :variable:`CACHE` for more information. Comments https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3de551cc22bf80f63ec9f05e3e934f42f79b8965 commit 3de551cc22bf80f63ec9f05e3e934f42f79b8965 Author: Joachim Wuttke (h) AuthorDate: Sat Oct 27 15:08:43 2018 +0200 Commit: Joachim Wuttke (h) CommitDate: Thu Nov 8 20:27:10 2018 +0100 Help: Clarify effect of set(ENV{..} ..) and unset(ENV{..}) Explain that the commands affect only the current CMake process, not the process from which CMake was called, nor the system environment at large, nor the environment of subsequent build or test processes. diff --git a/Help/command/set.rst b/Help/command/set.rst index e37e693..dd5ea13 100644 --- a/Help/command/set.rst +++ b/Help/command/set.rst @@ -88,4 +88,10 @@ Set Environment Variable set(ENV{} ...) -Sets the current process environment ```` to the given value. +Sets an :manual:`Environment Variable ` +to the given value. +Subsequent calls of ``$ENV{}`` will return this new value. + +This command affects only the current CMake process, not the process +from which CMake was called, nor the system environment at large, +nor the environment of subsequent build or test processes. diff --git a/Help/command/unset.rst b/Help/command/unset.rst index 1a5e49f..7521052 100644 --- a/Help/command/unset.rst +++ b/Help/command/unset.rst @@ -3,6 +3,9 @@ unset Unset a variable, cache variable, or environment variable. +Unset Normal Variable or Cache Entry +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. code-block:: cmake unset( [CACHE | PARENT_SCOPE]) @@ -22,11 +25,17 @@ If ``PARENT_SCOPE`` is present then the variable is removed from the scope above the current scope. See the same option in the :command:`set` command for further details. -```` can be an environment variable such as: +Unset Environment Variable +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: cmake - unset(ENV{LD_LIBRARY_PATH}) + unset(ENV{}) + +Removes ```` from the currently available +:manual:`Environment Variables `. +Subsequent calls of ``$ENV{}`` will return the empty string. -in which case the variable will be removed from the current -environment. +This command affects only the current CMake process, not the process +from which CMake was called, nor the system environment at large, +nor the environment of subsequent build or test processes. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=eba7273c203f0698ccd716604cc298b7da1d3ee6 commit eba7273c203f0698ccd716604cc298b7da1d3ee6 Author: Robert Maynard AuthorDate: Thu Nov 8 09:06:52 2018 -0500 Commit: Robert Maynard CommitDate: Thu Nov 8 09:32:18 2018 -0500 cpack: Better error message when generator doesn't exist. Currently the CPack error message when passed an invalid generator name reads like the generator failed to work, rather than the name was invalid. diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index c083945..3df1b36 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -358,8 +358,9 @@ int main(int argc, char const* const* argv) cpackGenerator->SetTraceExpand(traceExpand); } else { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, - "Cannot initialize CPack generator: " << gen - << std::endl); + "Could not create CPack generator: " << gen + << std::endl); + parsed = 0; } diff --git a/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt b/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt index fe4e455..a553bde 100644 --- a/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt +++ b/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt @@ -1 +1 @@ -^CPack Error: Cannot initialize CPack generator: NotAGenerator +^CPack Error: Could not create CPack generator: NotAGenerator ----------------------------------------------------------------------- Summary of changes: Help/command/if.rst | 16 +++++--- Help/command/set.rst | 8 +++- Help/command/unset.rst | 17 ++++++-- Help/manual/cmake-env-variables.7.rst | 8 ++++ Help/manual/cmake-language.7.rst | 46 ++++++++++++++++++---- Help/manual/cmake-variables.7.rst | 19 ++++++++- Help/variable/CACHE.rst | 5 ++- Help/variable/ENV.rst | 8 +++- Source/CPack/cpack.cxx | 18 ++++++++- .../CPackCommandLine/NotAGenerator-stderr.txt | 2 +- 10 files changed, 121 insertions(+), 26 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 9 11:43:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 9 Nov 2018 11:43:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-369-ga027128 Message-ID: <20181109164305.7E07812733F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via a02712840021706cea43bd10ebf742ef38c8f710 (commit) via bd831ed0948a1e99f573f0056f2bee5d3b21009e (commit) from 65522e5e0ef95b7424714ec4d67345bf00e9b8bd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a02712840021706cea43bd10ebf742ef38c8f710 commit a02712840021706cea43bd10ebf742ef38c8f710 Merge: 65522e5 bd831ed Author: Brad King AuthorDate: Fri Nov 9 16:38:01 2018 +0000 Commit: Kitware Robot CommitDate: Fri Nov 9 11:38:07 2018 -0500 Merge topic 'FindBoost-link-threads' bd831ed094 FindBoost: Add system thread library to Boost_LIBRARIES Acked-by: Kitware Robot Merge-request: !2570 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd831ed0948a1e99f573f0056f2bee5d3b21009e commit bd831ed0948a1e99f573f0056f2bee5d3b21009e Author: Felix Geyer AuthorDate: Tue Nov 6 18:33:43 2018 +0100 Commit: Brad King CommitDate: Fri Nov 9 10:38:45 2018 -0500 FindBoost: Add system thread library to Boost_LIBRARIES Add the system thread library to Boost_LIBRARIES when the boost thread component has been found. The Boost::thread imported target already pulls in Threads::Threads. This changes does the same for projects using the Boost_LIBRARIES variable instead. diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index e983941..0794a6f 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -2074,6 +2074,9 @@ if(Boost_FOUND) message (STATUS " ${COMPONENT}") endif() list(APPEND Boost_LIBRARIES ${Boost_${UPPERCOMPONENT}_LIBRARY}) + if(COMPONENT STREQUAL "thread") + list(APPEND Boost_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + endif() endif() endforeach() else() ----------------------------------------------------------------------- Summary of changes: Modules/FindBoost.cmake | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 9 11:53:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 9 Nov 2018 11:53:03 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-371-g48bc747 Message-ID: <20181109165303.6AB36127776@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 48bc74710d4ddcf62e3dcf69e3400e4060a2bdc1 (commit) via cda0b14ec32ad3d3aa67dd12d75aa34ffb1bcd19 (commit) from a02712840021706cea43bd10ebf742ef38c8f710 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48bc74710d4ddcf62e3dcf69e3400e4060a2bdc1 commit 48bc74710d4ddcf62e3dcf69e3400e4060a2bdc1 Merge: a027128 cda0b14 Author: Brad King AuthorDate: Fri Nov 9 11:45:09 2018 -0500 Commit: Brad King CommitDate: Fri Nov 9 11:45:09 2018 -0500 Merge branch 'release-3.13' ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 9 11:53:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 9 Nov 2018 11:53:03 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-2-gcda0b14 Message-ID: <20181109165303.7C79A127776@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via cda0b14ec32ad3d3aa67dd12d75aa34ffb1bcd19 (commit) via bd831ed0948a1e99f573f0056f2bee5d3b21009e (commit) from 8d70ed5a10362209d265a15d993f319235aea7e5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindBoost.cmake | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- CMake From kwrobot at kitware.com Sat Nov 10 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sat, 10 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-372-g9474496 Message-ID: <20181110050305.A84E0127379@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 94744965f810958b58d94d4b3e4f67566b392396 (commit) from 48bc74710d4ddcf62e3dcf69e3400e4060a2bdc1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=94744965f810958b58d94d4b3e4f67566b392396 commit 94744965f810958b58d94d4b3e4f67566b392396 Author: Kitware Robot AuthorDate: Sat Nov 10 00:01:05 2018 -0500 Commit: Kitware Robot CommitDate: Sat Nov 10 00:01:05 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3671d53..d164a6d 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 13) -set(CMake_VERSION_PATCH 20181109) +set(CMake_VERSION_PATCH 20181110) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 11 00:03:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 11 Nov 2018 00:03:03 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-373-g206ce3c Message-ID: <20181111050303.C52B3127AE4@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 206ce3c0ba730f34444a8627d6a4f261bf60fc92 (commit) from 94744965f810958b58d94d4b3e4f67566b392396 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=206ce3c0ba730f34444a8627d6a4f261bf60fc92 commit 206ce3c0ba730f34444a8627d6a4f261bf60fc92 Author: Kitware Robot AuthorDate: Sun Nov 11 00:01:03 2018 -0500 Commit: Kitware Robot CommitDate: Sun Nov 11 00:01:03 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d164a6d..9df722c 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 13) -set(CMake_VERSION_PATCH 20181110) +set(CMake_VERSION_PATCH 20181111) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-374-g776fd9b Message-ID: <20181112050307.4AC4A127A47@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 776fd9b947c58be96485e3b579c51e4df239efb4 (commit) from 206ce3c0ba730f34444a8627d6a4f261bf60fc92 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=776fd9b947c58be96485e3b579c51e4df239efb4 commit 776fd9b947c58be96485e3b579c51e4df239efb4 Author: Kitware Robot AuthorDate: Mon Nov 12 00:01:07 2018 -0500 Commit: Kitware Robot CommitDate: Mon Nov 12 00:01:07 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9df722c..0d78906 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 13) -set(CMake_VERSION_PATCH 20181111) +set(CMake_VERSION_PATCH 20181112) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 08:23:48 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 08:23:48 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-391-gc310480 Message-ID: <20181112132348.32927127A52@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via c310480c5dc76ad0c1eb4e842869f92121d5b507 (commit) via a16b24c9ce2bde6503d7580d40e0eab38d279788 (commit) via a63a9363b27aa84d01341484f02897814204c922 (commit) via f52dc4cae14a13185d264540229af87fed23c3a3 (commit) via baf8af10a773a032ff8254a38cfc69da3834fa34 (commit) via 7704693e9aa9e278e3fbd1a9de3b6713ea66b2b9 (commit) via 0e97ef74d82fa4e18a0701216b1003bd346903b2 (commit) via 2ef8fe2222adbc3e76bd60f79d01451f99de16aa (commit) via 8c8731b422f30a626d4692cde98558eee65ef063 (commit) via 3baa817c34a673025ccfeceb87a7c1f870fbae75 (commit) via 3327d3bb20c2a4505648b59d72cfaada38e1ee93 (commit) via 4e4551f9f37ab95d70d9226103deb673e8f5cd02 (commit) via abe1a345b255f69b02219f2b893ce00c8ff2e55b (commit) via b71667a395dcbb32046646cf8a6f98ea8d595bba (commit) via 51bf23ed74bdebc7a98880cd13af8c5f37ab02ba (commit) via c84fb4812d99978c2608379825b78fe43cda8659 (commit) via 1320122d3fda5974f6ed51cef709481efd2d658d (commit) from 776fd9b947c58be96485e3b579c51e4df239efb4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c310480c5dc76ad0c1eb4e842869f92121d5b507 commit c310480c5dc76ad0c1eb4e842869f92121d5b507 Merge: a16b24c 0e97ef7 Author: Brad King AuthorDate: Mon Nov 12 13:22:19 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 08:22:39 2018 -0500 Merge topic 'autogen_global_target' 0e97ef74d8 Autogen: Add release notes for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET 2ef8fe2222 Autogen: Add documentation for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET 8c8731b422 Autogen: Add test for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET 3baa817c34 Autogen: Add support for global ``autogen`` and ``autorcc`` targets 3327d3bb20 Autogen: Add cmQtAutoGenGlobalInitializer class Acked-by: Kitware Robot Merge-request: !2567 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a16b24c9ce2bde6503d7580d40e0eab38d279788 commit a16b24c9ce2bde6503d7580d40e0eab38d279788 Merge: a63a936 4e4551f Author: Brad King AuthorDate: Mon Nov 12 13:19:19 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 08:19:32 2018 -0500 Merge topic 'FindODBC-mingw-avoid-hardcoded-odbc32' 4e4551f9f3 FindODBC: Do not assume odbc32.lib for MinGW Acked-by: Kitware Robot Merge-request: !2585 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a63a9363b27aa84d01341484f02897814204c922 commit a63a9363b27aa84d01341484f02897814204c922 Merge: f52dc4c 1320122 Author: Brad King AuthorDate: Mon Nov 12 13:18:40 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 08:18:47 2018 -0500 Merge topic 'FindICU-link-dl' 1320122d3f FindICU: Add libdl to the link libraries for icu-uc Acked-by: Kitware Robot Acked-by: Francois Budin Merge-request: !2581 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f52dc4cae14a13185d264540229af87fed23c3a3 commit f52dc4cae14a13185d264540229af87fed23c3a3 Merge: baf8af1 abe1a34 Author: Brad King AuthorDate: Mon Nov 12 08:17:41 2018 -0500 Commit: Brad King CommitDate: Mon Nov 12 08:17:41 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=baf8af10a773a032ff8254a38cfc69da3834fa34 commit baf8af10a773a032ff8254a38cfc69da3834fa34 Merge: 7704693 c84fb48 Author: Brad King AuthorDate: Mon Nov 12 13:13:30 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 08:16:28 2018 -0500 Merge topic 'asm-compiler-id-clang' c84fb4812d ASM: Detect compiler id for Clang used as Assembler Acked-by: Kitware Robot Merge-request: !2584 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7704693e9aa9e278e3fbd1a9de3b6713ea66b2b9 commit 7704693e9aa9e278e3fbd1a9de3b6713ea66b2b9 Merge: 776fd9b b71667a Author: Brad King AuthorDate: Mon Nov 12 13:13:21 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 08:14:48 2018 -0500 Merge topic 'FindBoost-compiler-guess-update' b71667a395 FindBoost: Improve compiler prefix detection for GCC 5+ and clang 4+ Acked-by: Kitware Robot Merge-request: !2579 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0e97ef74d82fa4e18a0701216b1003bd346903b2 commit 0e97ef74d82fa4e18a0701216b1003bd346903b2 Author: Sebastian Holtermann AuthorDate: Sun Nov 11 14:27:47 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sun Nov 11 14:29:38 2018 +0100 Autogen: Add release notes for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET diff --git a/Help/release/dev/autogen_global_target.rst b/Help/release/dev/autogen_global_target.rst new file mode 100644 index 0000000..d555395 --- /dev/null +++ b/Help/release/dev/autogen_global_target.rst @@ -0,0 +1,8 @@ +autogen_global_target +--------------------- + +* The new variables :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`, + :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME`, + :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` and + :variable:`CMAKE_GLOBAL_AUTORCC_TARGET_NAME` control the generation + of global ``autogen`` and ``autorcc`` targets. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2ef8fe2222adbc3e76bd60f79d01451f99de16aa commit 2ef8fe2222adbc3e76bd60f79d01451f99de16aa Author: Sebastian Holtermann AuthorDate: Sun Nov 11 13:50:17 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sun Nov 11 14:29:38 2018 +0100 Autogen: Add documentation for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 0382794..d8d6172 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -236,6 +236,7 @@ when either :prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071` - :prop_tgt:`AUTOGEN_TARGET_DEPENDS` lists a source file +- :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled qtmain.lib on Windows ===================== diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 7a7f0b8..d808b1c 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -345,6 +345,10 @@ Variables that Control the Build /variable/CMAKE_FOLDER /variable/CMAKE_Fortran_FORMAT /variable/CMAKE_Fortran_MODULE_DIRECTORY + /variable/CMAKE_GLOBAL_AUTOGEN_TARGET + /variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME + /variable/CMAKE_GLOBAL_AUTORCC_TARGET + /variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME /variable/CMAKE_GNUtoMS /variable/CMAKE_INCLUDE_CURRENT_DIR /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 70d89f2..7a3fd48 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -86,5 +86,9 @@ enabling :prop_sf:`SKIP_AUTOMOC` or the broader :prop_sf:`SKIP_AUTOGEN`. The number of parallel ``moc`` processes to start can be modified by setting :prop_tgt:`AUTOGEN_PARALLEL`. +A global ``autogen`` target that depends on all :prop_tgt:`AUTOMOC` generated +``_autogen`` targets in the project can be generated by enabling +:variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`. + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst index 99c2b0e..27fb149 100644 --- a/Help/prop_tgt/AUTORCC.rst +++ b/Help/prop_tgt/AUTORCC.rst @@ -35,5 +35,9 @@ generate unspecified unique names for ``rcc``. Therefore if Source files can be excluded from :prop_tgt:`AUTORCC` processing by enabling :prop_sf:`SKIP_AUTORCC` or the broader :prop_sf:`SKIP_AUTOGEN`. +A global ``autorcc`` target that depends on all :prop_tgt:`AUTORCC` targets +in the project can be generated by enabling +:variable:`CMAKE_GLOBAL_AUTORCC_TARGET`. + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 8cae0a7..4f58b35 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -36,5 +36,9 @@ enabling :prop_sf:`SKIP_AUTOUIC` or the broader :prop_sf:`SKIP_AUTOGEN`. The number of parallel ``uic`` processes to start can be modified by setting :prop_tgt:`AUTOGEN_PARALLEL`. +A global ``autogen`` target that depends on all :prop_tgt:`AUTOUIC` generated +``_autogen`` targets in the project can be generated by enabling +:variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`. + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst new file mode 100644 index 0000000..75903ab --- /dev/null +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst @@ -0,0 +1,18 @@ +CMAKE_GLOBAL_AUTOGEN_TARGET +--------------------------- + +Switch to enable generation of a global ``autogen`` target. + +When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target +``autogen`` is generated. This target depends on all :prop_tgt:`AUTOMOC` and +:prop_tgt:`AUTOUIC` generated ``_autogen`` targets in the project. +By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and +:prop_tgt:`AUTOUIC` files in the project will be generated. + +The name of the global ``autogen`` target can be changed by setting +:variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME`. + +By default :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst new file mode 100644 index 0000000..c86a5d0 --- /dev/null +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst @@ -0,0 +1,13 @@ +CMAKE_GLOBAL_AUTOGEN_TARGET_NAME +-------------------------------- + +Change the name of the global ``autogen`` target. + +When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a global custom target +named ``autogen`` is created. :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME` +allows to set a different name for that target. + +By default :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst new file mode 100644 index 0000000..f92128c --- /dev/null +++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst @@ -0,0 +1,18 @@ +CMAKE_GLOBAL_AUTORCC_TARGET +--------------------------- + +Switch to enable generation of a global ``autorcc`` target. + +When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target +``autorcc`` is generated. This target depends on all :prop_tgt:`AUTORCC` +generated ``_arcc_`` targets in the project. +By building the global ``autorcc`` target, all :prop_tgt:`AUTORCC` +files in the project will be generated. + +The name of the global ``autorcc`` target can be changed by setting +:variable:`CMAKE_GLOBAL_AUTORCC_TARGET_NAME`. + +By default :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst new file mode 100644 index 0000000..c6e05de --- /dev/null +++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst @@ -0,0 +1,13 @@ +CMAKE_GLOBAL_AUTORCC_TARGET_NAME +-------------------------------- + +Change the name of the global ``autorcc`` target. + +When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a global custom target +named ``autorcc`` is created. :variable:`CMAKE_GLOBAL_AUTORCC_TARGET_NAME` +allows to set a different name for that target. + +By default :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8c8731b422f30a626d4692cde98558eee65ef063 commit 8c8731b422f30a626d4692cde98558eee65ef063 Author: Sebastian Holtermann AuthorDate: Sun Nov 11 12:54:14 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sun Nov 11 14:29:38 2018 +0100 Autogen: Add test for CMAKE_GLOBAL_AUTOGEN/RCC_TARGET diff --git a/Tests/QtAutogen/CommonTests.cmake b/Tests/QtAutogen/CommonTests.cmake index 58d9f0b..1cd9e7e 100644 --- a/Tests/QtAutogen/CommonTests.cmake +++ b/Tests/QtAutogen/CommonTests.cmake @@ -7,6 +7,7 @@ ADD_AUTOGEN_TEST(UicOnly uicOnly) ADD_AUTOGEN_TEST(RccOnly rccOnly) ADD_AUTOGEN_TEST(RccEmpty rccEmpty) ADD_AUTOGEN_TEST(RccOffMocLibrary) +ADD_AUTOGEN_TEST(GlobalAutogenTarget) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocSkipSource) endif() diff --git a/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt new file mode 100644 index 0000000..e020673 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt @@ -0,0 +1,123 @@ +cmake_minimum_required(VERSION 3.12) +project(GlobalAutogenTarget) +include("../AutogenTest.cmake") + +# This tests +# CMAKE_GLOBAL_AUTOGEN_TARGET, +# CMAKE_GLOBAL_AUTORCC_TARGET, +# CMAKE_GLOBAL_AUTOGEN_TARGET_NAME and +# CMAKE_GLOBAL_AUTORCC_TARGET_NAME +# for the latter two with different values in different subdirectories. + +# Directories +set(GAT_SDIR "${CMAKE_CURRENT_SOURCE_DIR}/GAT") +set(GAT_BDIR "${CMAKE_CURRENT_BINARY_DIR}/GAT") +# Files +set(MCA "sda/sda_autogen/mocs_compilation.cpp") +set(MCB "sdb/sdb_autogen/mocs_compilation.cpp") +set(MCC "sdc/sdc_autogen/mocs_compilation.cpp") +set(MCG "gat_autogen/mocs_compilation.cpp") + +set(DRA "sda/sda_autogen/*qrc_data.cpp") +set(DRB "sdb/sdb_autogen/*qrc_data.cpp") +set(DRC "sdc/sdc_autogen/*qrc_data.cpp") +set(DRG "gat_autogen/*qrc_data.cpp") + +# -- Utility macros +macro(GAT_FIND_FILES VAR NAME) + file(GLOB_RECURSE ${VAR} ${GAT_BDIR}/*${NAME}) +endmacro() + +macro(GAT_FIND_FILE NAME) + GAT_FIND_FILES(LST ${NAME}) + if(LST) + message("Good find ${LST}") + else() + message(SEND_ERROR "Expected to find ${GAT_BDIR}/${NAME}") + endif() + unset(LST) +endmacro() + +macro(GAT_FIND_FILE_NOT NAME) + GAT_FIND_FILES(LST ${NAME}) + if(LST) + message(SEND_ERROR "Not expected to find ${GAT_BDIR}/${NAME}") + else() + message("Good not find ${GAT_BDIR}/${NAME}") + endif() + unset(LST) +endmacro() + +macro(GAT_BUILD_TARGET NAME) + message("___ Building GAT ${NAME} target ___") + execute_process( + COMMAND "${CMAKE_COMMAND}" --build "${GAT_BDIR}" --target ${NAME} + WORKING_DIRECTORY "${GAT_BDIR}" + RESULT_VARIABLE result) + if (result) + message(SEND_ERROR "Building of GAT ${NAME} target failed") + endif() +endmacro() + + +# -- Remove and recreate build directory +file(REMOVE_RECURSE ${GAT_BDIR}) +file(MAKE_DIRECTORY ${GAT_BDIR}) + + +# -- Configure project +message("___ Configuring GAT project ___") +execute_process( + COMMAND "${CMAKE_COMMAND}" "${GAT_SDIR}" + "-DQT_TEST_VERSION=${QT_TEST_VERSION}" + "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}" + "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" + WORKING_DIRECTORY "${GAT_BDIR}" + OUTPUT_VARIABLE output + RESULT_VARIABLE result) +if (result) + message(SEND_ERROR "Configuring of GAT project failed") +else() + message("Configuring of GAT project succeeded") + message("${output}") +endif() + + +# -- Build autogen subtargets +GAT_BUILD_TARGET("autogen") +GAT_FIND_FILE("${MCA}") +GAT_FIND_FILE_NOT("${MCB}") +GAT_FIND_FILE_NOT("${MCC}") +GAT_FIND_FILE("${MCG}") + +GAT_BUILD_TARGET("global_autogen_sdb") +GAT_FIND_FILE("${MCA}") +GAT_FIND_FILE("${MCB}") +GAT_FIND_FILE_NOT("${MCC}") +GAT_FIND_FILE("${MCG}") + +GAT_BUILD_TARGET("all_autogen") +GAT_FIND_FILE("${MCA}") +GAT_FIND_FILE("${MCB}") +GAT_FIND_FILE("${MCC}") +GAT_FIND_FILE("${MCG}") + + +# -- Build autorcc subtargets +GAT_BUILD_TARGET("autorcc") +GAT_FIND_FILE("${DRA}") +GAT_FIND_FILE_NOT("${DRB}") +GAT_FIND_FILE_NOT("${DRC}") +GAT_FIND_FILE("${DRG}") + +GAT_BUILD_TARGET("global_autorcc_sdb") +GAT_FIND_FILE("${DRA}") +GAT_FIND_FILE("${DRB}") +GAT_FIND_FILE_NOT("${DRC}") +GAT_FIND_FILE("${DRG}") + +GAT_BUILD_TARGET("all_autorcc") +GAT_FIND_FILE("${DRA}") +GAT_FIND_FILE("${DRB}") +GAT_FIND_FILE("${DRC}") +GAT_FIND_FILE("${DRG}") diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/GAT/CMakeLists.txt new file mode 100644 index 0000000..b1008e8 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.12) +project(GAT) +include("../../AutogenTest.cmake") + +# Include directories +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +# Enable AUTOMOC/UIC/RCC +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +# Disable ORIGN_DEPENDS and enable AUTOGEN global targets +set(CMAKE_AUTOGEN_ORIGIN_DEPENDS OFF) +set(CMAKE_GLOBAL_AUTOGEN_TARGET ON) +set(CMAKE_GLOBAL_AUTORCC_TARGET ON) + +add_subdirectory(sda) +add_subdirectory(sdb) +add_subdirectory(sdc) + +# Add custom target that depends on all autogen/autorcc targets +add_custom_target(all_autogen DEPENDS autogen global_autogen_sdb global_autogen_sdc) +add_custom_target(all_autorcc DEPENDS autorcc global_autorcc_sdb global_autorcc_sdc) + +# Main target +add_executable(gat data.qrc item.cpp main.cpp) +target_link_libraries(gat ${QT_LIBRARIES}) +target_link_libraries(gat sda sdb sdc) diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/data.qrc b/Tests/QtAutogen/GlobalAutogenTarget/GAT/data.qrc new file mode 100644 index 0000000..68d02c9 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/data.qrc @@ -0,0 +1,5 @@ + + + item.cpp + + diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.cpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.cpp new file mode 100644 index 0000000..3d1fbe7 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.cpp @@ -0,0 +1,20 @@ +#include "item.hpp" +// Include ui_view.h in source and header +#include + +class MocLocal : public QObject +{ + Q_OBJECT; + +public: + MocLocal() = default; + ~MocLocal() = default; +}; + +void Item::go() +{ + Ui_View ui; + MocLocal obj; +} + +#include "item.moc" diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.hpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.hpp new file mode 100644 index 0000000..75e83f4 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/item.hpp @@ -0,0 +1,15 @@ +#ifndef ITEM_HPP +#define ITEM_HPP + +#include +// Include ui_view.h in source and header +#include + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go(); +}; + +#endif diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/main.cpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/main.cpp new file mode 100644 index 0000000..79c00b4 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/main.cpp @@ -0,0 +1,15 @@ +#include "item.hpp" +#include "sda/sda.hpp" +#include "sdb/sdb.hpp" +#include "sdc/sdc.hpp" + +int main(int argv, char** args) +{ + // Object instances + Item item; + // Library calls + sda(); + sdb(); + sdc(); + return 0; +} diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/CMakeLists.txt new file mode 100644 index 0000000..795e91e --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(sda ../item.cpp ../data.qrc sda.cpp) +target_link_libraries(sda ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.cpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.cpp new file mode 100644 index 0000000..ec4dec8 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.cpp @@ -0,0 +1,6 @@ +#include + +void sda() +{ + Item item; +} diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.hpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.hpp new file mode 100644 index 0000000..89ac744 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.hpp @@ -0,0 +1,6 @@ +#ifndef SDA_HPP +#define SDA_HPP + +void sda(); + +#endif diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/CMakeLists.txt new file mode 100644 index 0000000..5c686fe --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/CMakeLists.txt @@ -0,0 +1,5 @@ +set(CMAKE_GLOBAL_AUTOGEN_TARGET_NAME "global_autogen_sdb") +set(CMAKE_GLOBAL_AUTORCC_TARGET_NAME "global_autorcc_sdb") + +add_library(sdb ../item.cpp ../data.qrc sdb.cpp) +target_link_libraries(sdb ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.cpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.cpp new file mode 100644 index 0000000..e32c467 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.cpp @@ -0,0 +1,6 @@ +#include + +void sdb() +{ + Item item; +} diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.hpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.hpp new file mode 100644 index 0000000..a5b0f62 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.hpp @@ -0,0 +1,6 @@ +#ifndef SDB_HPP +#define SDB_HPP + +void sdb(); + +#endif diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/CMakeLists.txt new file mode 100644 index 0000000..2698bda --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/CMakeLists.txt @@ -0,0 +1,5 @@ +set(CMAKE_GLOBAL_AUTOGEN_TARGET_NAME "global_autogen_sdc") +set(CMAKE_GLOBAL_AUTORCC_TARGET_NAME "global_autorcc_sdc") + +add_library(sdc ../item.cpp ../data.qrc sdc.cpp) +target_link_libraries(sdc ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.cpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.cpp new file mode 100644 index 0000000..a97cd42 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.cpp @@ -0,0 +1,6 @@ +#include + +void sdc() +{ + Item item; +} diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.hpp b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.hpp new file mode 100644 index 0000000..7e92179 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.hpp @@ -0,0 +1,6 @@ +#ifndef SDC_HPP +#define SDC_HPP + +void sdc(); + +#endif diff --git a/Tests/QtAutogen/GlobalAutogenTarget/GAT/view.ui b/Tests/QtAutogen/GlobalAutogenTarget/GAT/view.ui new file mode 100644 index 0000000..2ffe734 --- /dev/null +++ b/Tests/QtAutogen/GlobalAutogenTarget/GAT/view.ui @@ -0,0 +1,24 @@ + + + View + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + + + https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3baa817c34a673025ccfeceb87a7c1f870fbae75 commit 3baa817c34a673025ccfeceb87a7c1f870fbae75 Author: Sebastian Holtermann AuthorDate: Tue Nov 6 12:40:48 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sun Nov 11 14:28:55 2018 +0100 Autogen: Add support for global ``autogen`` and ``autorcc`` targets This teaches CMake the variables - CMAKE_GLOBAL_AUTOGEN_TARGET - CMAKE_GLOBAL_AUTOGEN_TARGET_NAME - CMAKE_GLOBAL_AUTORCC_TARGET - CMAKE_GLOBAL_AUTORCC_TARGET_NAME which control the generation of global ``autogen`` and ``autorcc`` targets. Closes #17721 diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index d815a43..5470ec3 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -1,15 +1,56 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenGlobalInitializer.h" +#include "cmQtAutoGen.h" +#include "cmQtAutoGenInitializer.h" + #include "cmAlgorithms.h" +#include "cmCustomCommandLines.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" -#include "cmQtAutoGenInitializer.h" +#include "cmMakefile.h" +#include "cmState.h" +#include "cmStateTypes.h" +#include "cmSystemTools.h" +#include "cmTarget.h" + +#include +#include cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( std::vector const& localGenerators) { for (cmLocalGenerator* localGen : localGenerators) { + // Detect global autogen and autorcc target names + bool globalAutoGenTarget = false; + bool globalAutoRccTarget = false; + { + cmMakefile* makefile = localGen->GetMakefile(); + // Detect global autogen target name + if (cmSystemTools::IsOn( + makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) { + std::string targetName = + makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME"); + if (targetName.empty()) { + targetName = "autogen"; + } + GlobalAutoGenTargets_.emplace(localGen, std::move(targetName)); + globalAutoGenTarget = true; + } + + // Detect global autorcc target name + if (cmSystemTools::IsOn( + makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) { + std::string targetName = + makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME"); + if (targetName.empty()) { + targetName = "autorcc"; + } + GlobalAutoRccTargets_.emplace(localGen, std::move(targetName)); + globalAutoRccTarget = true; + } + } + // Find targets that require AUTOMOC/UIC/RCC processing for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) { // Process only certain target types @@ -39,7 +80,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) { // Create autogen target initializer Initializers_.emplace_back(cm::make_unique( - target, moc, uic, rcc, qtVersion)); + this, target, qtVersion, moc, uic, rcc, globalAutoGenTarget, + globalAutoRccTarget)); } } } @@ -50,6 +92,58 @@ cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer() { } +void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( + cmLocalGenerator* localGen, std::string const& name, + std::string const& comment) +{ + // Test if the target already exists + if (localGen->FindGeneratorTargetToUse(name) == nullptr) { + cmMakefile* makefile = localGen->GetMakefile(); + + // Create utility target + cmTarget* target = makefile->AddUtilityCommand( + name, cmMakefile::TargetOrigin::Generator, true, + makefile->GetHomeOutputDirectory().c_str() /*work dir*/, + std::vector() /*output*/, + std::vector() /*depends*/, cmCustomCommandLines(), false, + comment.c_str()); + localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen)); + + // Set FOLDER property in the target + { + char const* folder = + makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); + if (folder != nullptr) { + target->SetProperty("FOLDER", folder); + } + } + } +} + +void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen( + cmLocalGenerator* localGen, std::string const& targetName) +{ + auto it = GlobalAutoGenTargets_.find(localGen); + if (it != GlobalAutoGenTargets_.end()) { + cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); + if (target != nullptr) { + target->Target->AddUtility(targetName, localGen->GetMakefile()); + } + } +} + +void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( + cmLocalGenerator* localGen, std::string const& targetName) +{ + auto it = GlobalAutoRccTargets_.find(localGen); + if (it != GlobalAutoRccTargets_.end()) { + cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); + if (target != nullptr) { + target->Target->AddUtility(targetName, localGen->GetMakefile()); + } + } +} + bool cmQtAutoGenGlobalInitializer::generate() { return (InitializeCustomTargets() && SetupCustomTargets()); @@ -57,8 +151,23 @@ bool cmQtAutoGenGlobalInitializer::generate() bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() { - for (auto& autoGen : Initializers_) { - if (!autoGen->InitCustomTargets()) { + // Initialize global autogen targets + { + std::string const comment = "Global AUTOGEN target"; + for (auto const& pair : GlobalAutoGenTargets_) { + GetOrCreateGlobalTarget(pair.first, pair.second, comment); + } + } + // Initialize global autorcc targets + { + std::string const comment = "Global AUTORCC target"; + for (auto const& pair : GlobalAutoRccTargets_) { + GetOrCreateGlobalTarget(pair.first, pair.second, comment); + } + } + // Initialize per target autogen targets + for (auto& initializer : Initializers_) { + if (!initializer->InitCustomTargets()) { return false; } } @@ -67,8 +176,8 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() bool cmQtAutoGenGlobalInitializer::SetupCustomTargets() { - for (auto& autoGen : Initializers_) { - if (!autoGen->SetupCustomTargets()) { + for (auto& initializer : Initializers_) { + if (!initializer->SetupCustomTargets()) { return false; } } diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index 42bf62f..9e6bac0 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -5,7 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include +#include +#include // IWYU pragma: keep +#include #include class cmLocalGenerator; @@ -22,11 +24,24 @@ public: bool generate(); private: + friend class cmQtAutoGenInitializer; + bool InitializeCustomTargets(); bool SetupCustomTargets(); + void GetOrCreateGlobalTarget(cmLocalGenerator* localGen, + std::string const& name, + std::string const& comment); + + void AddToGlobalAutoGen(cmLocalGenerator* localGen, + std::string const& targetName); + void AddToGlobalAutoRcc(cmLocalGenerator* localGen, + std::string const& targetName); + private: std::vector> Initializers_; + std::map GlobalAutoGenTargets_; + std::map GlobalAutoRccTargets_; }; #endif diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index a213c84..793c0b2 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenInitializer.h" #include "cmQtAutoGen.h" +#include "cmQtAutoGenGlobalInitializer.h" #include "cmAlgorithms.h" #include "cmCustomCommand.h" @@ -174,17 +175,19 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, return cycle; } -cmQtAutoGenInitializer::cmQtAutoGenInitializer(cmGeneratorTarget* target, - bool mocEnabled, - bool uicEnabled, - bool rccEnabled, - IntegerVersion const& qtVersion) - : Target(target) +cmQtAutoGenInitializer::cmQtAutoGenInitializer( + cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target, + IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled, + bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget) + : GlobalInitializer(globalInitializer) + , Target(target) , QtVersion(qtVersion) { + AutogenTarget.GlobalTarget = globalAutogenTarget; Moc.Enabled = mocEnabled; Uic.Enabled = uicEnabled; Rcc.Enabled = rccEnabled; + Rcc.GlobalTarget = globalAutoRccTarget; } bool cmQtAutoGenInitializer::InitCustomTargets() @@ -882,6 +885,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() if (!this->AutogenTarget.DependFiles.empty()) { usePRE_BUILD = false; } + // Cannot use PRE_BUILD when a global autogen target is in place + if (AutogenTarget.GlobalTarget) { + usePRE_BUILD = false; + } } // Create the autogen target/command if (usePRE_BUILD) { @@ -961,6 +968,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // Add autogen target to the origin target dependencies this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile); + + // Add autogen target to the global autogen target dependencies + if (this->AutogenTarget.GlobalTarget) { + this->GlobalInitializer->AddToGlobalAutoGen(localGen, + this->AutogenTarget.Name); + } } return true; @@ -1004,7 +1017,7 @@ bool cmQtAutoGenInitializer::InitRccTargets() std::string ccComment = "Automatic RCC for "; ccComment += FileProjectRelativePath(makefile, qrc.QrcFile); - if (qrc.Generated) { + if (qrc.Generated || this->Rcc.GlobalTarget) { // Create custom rcc target std::string ccName; { @@ -1035,6 +1048,11 @@ bool cmQtAutoGenInitializer::InitRccTargets() } // Add autogen target to the origin target dependencies this->Target->Target->AddUtility(ccName, makefile); + + // Add autogen target to the global autogen target dependencies + if (this->Rcc.GlobalTarget) { + this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName); + } } else { // Create custom rcc command { diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 1d3947b..53ad571 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -13,6 +13,7 @@ class cmGeneratorTarget; class cmTarget; +class cmQtAutoGenGlobalInitializer; /// @brief Initializes the QtAutoGen generators class cmQtAutoGenInitializer : public cmQtAutoGen @@ -46,9 +47,11 @@ public: public: static IntegerVersion GetQtVersion(cmGeneratorTarget const* target); - cmQtAutoGenInitializer(cmGeneratorTarget* target, bool mocEnabled, + cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer, + cmGeneratorTarget* target, + IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled, bool rccEnabled, - IntegerVersion const& qtVersion); + bool globalAutogenTarget, bool globalAutoRccTarget); bool InitCustomTargets(); bool SetupCustomTargets(); @@ -76,6 +79,7 @@ private: std::string& errorMessage); private: + cmQtAutoGenGlobalInitializer* GlobalInitializer; cmGeneratorTarget* Target; // Configuration @@ -100,6 +104,7 @@ private: struct { std::string Name; + bool GlobalTarget = false; // Settings std::string Parallel; // Configuration files @@ -148,6 +153,7 @@ private: struct { bool Enabled = false; + bool GlobalTarget = false; std::string Executable; std::vector ListOptions; std::vector Qrcs; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3327d3bb20c2a4505648b59d72cfaada38e1ee93 commit 3327d3bb20c2a4505648b59d72cfaada38e1ee93 Author: Sebastian Holtermann AuthorDate: Mon Nov 5 11:18:46 2018 +0100 Commit: Sebastian Holtermann CommitDate: Sun Nov 11 09:35:28 2018 +0100 Autogen: Add cmQtAutoGenGlobalInitializer class This moves the global ``AUTOMOC/UIC/RCC`` targets initializer generation code into a separate new ``cmQtAutoGenGlobalInitializer`` class. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ded21bc..9aebfa7 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -320,6 +320,8 @@ set(SRCS cmQtAutoGen.h cmQtAutoGenerator.cxx cmQtAutoGenerator.h + cmQtAutoGenGlobalInitializer.cxx + cmQtAutoGenGlobalInitializer.h cmQtAutoGenInitializer.cxx cmQtAutoGenInitializer.h cmQtAutoGeneratorMocUic.cxx diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index cf85473..2805395 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -34,8 +34,6 @@ #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmQtAutoGen.h" -#include "cmQtAutoGenInitializer.h" #include "cmSourceFile.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -46,6 +44,7 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmCryptoHash.h" +# include "cmQtAutoGenGlobalInitializer.h" # include "cm_jsoncpp_value.h" # include "cm_jsoncpp_writer.h" #endif @@ -1469,64 +1468,11 @@ bool cmGlobalGenerator::ComputeTargetDepends() bool cmGlobalGenerator::QtAutoGen() { #ifdef CMAKE_BUILD_WITH_CMAKE - std::vector> autogenInits; - - for (cmLocalGenerator* localGen : this->LocalGenerators) { - const std::vector& targets = - localGen->GetGeneratorTargets(); - // Find targets that require AUTOGEN processing - for (cmGeneratorTarget* target : targets) { - if (target->GetType() == cmStateEnums::GLOBAL_TARGET) { - continue; - } - if (target->GetType() != cmStateEnums::EXECUTABLE && - target->GetType() != cmStateEnums::STATIC_LIBRARY && - target->GetType() != cmStateEnums::SHARED_LIBRARY && - target->GetType() != cmStateEnums::MODULE_LIBRARY && - target->GetType() != cmStateEnums::OBJECT_LIBRARY) { - continue; - } - if (target->IsImported()) { - continue; - } - - const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); - const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); - const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); - if (!mocEnabled && !uicEnabled && !rccEnabled) { - continue; - } - - auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target); - // don't do anything if there is no Qt4 or Qt5Core (which contains moc) - if (qtVersion.Major != 4 && qtVersion.Major != 5) { - continue; - } - - autogenInits.emplace_back(cm::make_unique( - target, mocEnabled, uicEnabled, rccEnabled, qtVersion)); - } - } - - if (!autogenInits.empty()) { - // Initialize custom targets - for (auto& autoGen : autogenInits) { - if (!autoGen->InitCustomTargets()) { - return false; - } - } - - // Setup custom targets - for (auto& autoGen : autogenInits) { - if (!autoGen->SetupCustomTargets()) { - return false; - } - autoGen.reset(nullptr); - } - } -#endif - + cmQtAutoGenGlobalInitializer initializer(this->LocalGenerators); + return initializer.generate(); +#else return true; +#endif } cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer( diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx new file mode 100644 index 0000000..d815a43 --- /dev/null +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -0,0 +1,76 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmQtAutoGenGlobalInitializer.h" +#include "cmAlgorithms.h" +#include "cmGeneratorTarget.h" +#include "cmLocalGenerator.h" +#include "cmQtAutoGenInitializer.h" + +cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( + std::vector const& localGenerators) +{ + for (cmLocalGenerator* localGen : localGenerators) { + // Find targets that require AUTOMOC/UIC/RCC processing + for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) { + // Process only certain target types + switch (target->GetType()) { + case cmStateEnums::EXECUTABLE: + case cmStateEnums::STATIC_LIBRARY: + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::OBJECT_LIBRARY: + // Process target + break; + default: + // Don't process target + continue; + } + if (target->IsImported()) { + // Don't process target + continue; + } + + bool const moc = target->GetPropertyAsBool("AUTOMOC"); + bool const uic = target->GetPropertyAsBool("AUTOUIC"); + bool const rcc = target->GetPropertyAsBool("AUTORCC"); + if (moc || uic || rcc) { + // We support Qt4 and Qt5 + auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target); + if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) { + // Create autogen target initializer + Initializers_.emplace_back(cm::make_unique( + target, moc, uic, rcc, qtVersion)); + } + } + } + } +} + +cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer() +{ +} + +bool cmQtAutoGenGlobalInitializer::generate() +{ + return (InitializeCustomTargets() && SetupCustomTargets()); +} + +bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() +{ + for (auto& autoGen : Initializers_) { + if (!autoGen->InitCustomTargets()) { + return false; + } + } + return true; +} + +bool cmQtAutoGenGlobalInitializer::SetupCustomTargets() +{ + for (auto& autoGen : Initializers_) { + if (!autoGen->SetupCustomTargets()) { + return false; + } + } + return true; +} diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h new file mode 100644 index 0000000..42bf62f --- /dev/null +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -0,0 +1,32 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmQtAutoGenGlobalInitializer_h +#define cmQtAutoGenGlobalInitializer_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include +#include + +class cmLocalGenerator; +class cmQtAutoGenInitializer; + +/// @brief Initializes the QtAutoGen generators +class cmQtAutoGenGlobalInitializer +{ +public: + cmQtAutoGenGlobalInitializer( + std::vector const& localGenerators); + ~cmQtAutoGenGlobalInitializer(); + + bool generate(); + +private: + bool InitializeCustomTargets(); + bool SetupCustomTargets(); + +private: + std::vector> Initializers_; +}; + +#endif https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4e4551f9f37ab95d70d9226103deb673e8f5cd02 commit 4e4551f9f37ab95d70d9226103deb673e8f5cd02 Author: Mateusz ?oskot AuthorDate: Fri Nov 9 18:15:12 2018 +0100 Commit: Mateusz ?oskot CommitDate: Fri Nov 9 19:49:05 2018 +0100 FindODBC: Do not assume odbc32.lib for MinGW For MinGW, do not look for odbc32.lib but allow search for libodbc32.a. Fixes: #18539 diff --git a/Modules/FindODBC.cmake b/Modules/FindODBC.cmake index c8ca477..29d7af9 100644 --- a/Modules/FindODBC.cmake +++ b/Modules/FindODBC.cmake @@ -90,7 +90,9 @@ set(_odbc_required_libs_names) ### Try Windows Kits ########################################################## if(WIN32) # List names of ODBC libraries on Windows - set(ODBC_LIBRARY odbc32.lib) + if(NOT MINGW) + set(ODBC_LIBRARY odbc32.lib) + endif() set(_odbc_lib_names odbc32;) # List additional libraries required to use ODBC library https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1320122d3fda5974f6ed51cef709481efd2d658d commit 1320122d3fda5974f6ed51cef709481efd2d658d Author: Cameron Cawley AuthorDate: Thu Nov 8 11:29:27 2018 -0500 Commit: Cameron Cawley CommitDate: Thu Nov 8 11:29:27 2018 -0500 FindICU: Add libdl to the link libraries for icu-uc diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake index 685b10f..70e10f5 100644 --- a/Modules/FindICU.cmake +++ b/Modules/FindICU.cmake @@ -363,6 +363,10 @@ if(ICU_FOUND) IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" IMPORTED_LOCATION_DEBUG "${${_ICU_component_cache_debug}}") endif() + if(CMAKE_DL_LIBS AND _ICU_component STREQUAL "uc") + set_target_properties(${_ICU_imported_target} PROPERTIES + INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS}") + endif() endif() endif() unset(_ICU_component_upcase) ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-qt.7.rst | 1 + Help/manual/cmake-variables.7.rst | 4 + Help/prop_tgt/AUTOMOC.rst | 4 + Help/prop_tgt/AUTORCC.rst | 4 + Help/prop_tgt/AUTOUIC.rst | 4 + Help/release/dev/autogen_global_target.rst | 8 + Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst | 18 ++ Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst | 13 ++ Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst | 18 ++ Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst | 13 ++ Modules/CMakeDetermineASMCompiler.cmake | 8 + Modules/FindBoost.cmake | 33 +++- Modules/FindICU.cmake | 4 + Modules/FindODBC.cmake | 4 +- Source/CMakeLists.txt | 2 + Source/cmGlobalGenerator.cxx | 64 +------ Source/cmQtAutoGenGlobalInitializer.cxx | 185 +++++++++++++++++++++ Source/cmQtAutoGenGlobalInitializer.h | 47 ++++++ Source/cmQtAutoGenInitializer.cxx | 32 +++- Source/cmQtAutoGenInitializer.h | 10 +- Tests/QtAutogen/CommonTests.cmake | 1 + Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt | 123 ++++++++++++++ .../GlobalAutogenTarget/GAT/CMakeLists.txt | 28 ++++ Tests/QtAutogen/GlobalAutogenTarget/GAT/data.qrc | 5 + .../{SameName => GlobalAutogenTarget/GAT}/item.cpp | 0 .../{SameName => GlobalAutogenTarget/GAT}/item.hpp | 0 Tests/QtAutogen/GlobalAutogenTarget/GAT/main.cpp | 15 ++ .../GlobalAutogenTarget/GAT/sda/CMakeLists.txt | 2 + .../QtAutogen/GlobalAutogenTarget/GAT/sda/sda.cpp | 6 + .../QtAutogen/GlobalAutogenTarget/GAT/sda/sda.hpp | 6 + .../GlobalAutogenTarget/GAT/sdb/CMakeLists.txt | 5 + .../QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.cpp | 6 + .../QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.hpp | 6 + .../GlobalAutogenTarget/GAT/sdc/CMakeLists.txt | 5 + .../QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.cpp | 6 + .../QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.hpp | 6 + .../{SameName => GlobalAutogenTarget/GAT}/view.ui | 0 37 files changed, 620 insertions(+), 76 deletions(-) create mode 100644 Help/release/dev/autogen_global_target.rst create mode 100644 Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst create mode 100644 Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst create mode 100644 Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst create mode 100644 Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst create mode 100644 Source/cmQtAutoGenGlobalInitializer.cxx create mode 100644 Source/cmQtAutoGenGlobalInitializer.h create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/CMakeLists.txt create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/data.qrc copy Tests/QtAutogen/{SameName => GlobalAutogenTarget/GAT}/item.cpp (100%) copy Tests/QtAutogen/{SameName => GlobalAutogenTarget/GAT}/item.hpp (100%) create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/main.cpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/CMakeLists.txt create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.cpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sda/sda.hpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/CMakeLists.txt create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.cpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdb/sdb.hpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/CMakeLists.txt create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.cpp create mode 100644 Tests/QtAutogen/GlobalAutogenTarget/GAT/sdc/sdc.hpp copy Tests/QtAutogen/{SameName => GlobalAutogenTarget/GAT}/view.ui (100%) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 08:23:48 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 08:23:48 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-6-gabe1a34 Message-ID: <20181112132350.A9583127A87@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via abe1a345b255f69b02219f2b893ce00c8ff2e55b (commit) via b71667a395dcbb32046646cf8a6f98ea8d595bba (commit) via 51bf23ed74bdebc7a98880cd13af8c5f37ab02ba (commit) via c84fb4812d99978c2608379825b78fe43cda8659 (commit) from cda0b14ec32ad3d3aa67dd12d75aa34ffb1bcd19 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/CMakeDetermineASMCompiler.cmake | 8 ++++++++ Modules/FindBoost.cmake | 33 ++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 15:53:24 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 15:53:24 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-395-gddb967c Message-ID: <20181112205324.B1C96127976@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via ddb967cca1a37501dcf3fbd6f64c2d3be1c0c82b (commit) via c4b4d8b3a67718e29edb5676273e528dab566672 (commit) via 724a0346f7bd424ce0e5db246cee46db9f377a6f (commit) via 023188ffb48cc35ebab7cabbafefcd6dd31b750d (commit) from c310480c5dc76ad0c1eb4e842869f92121d5b507 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ddb967cca1a37501dcf3fbd6f64c2d3be1c0c82b commit ddb967cca1a37501dcf3fbd6f64c2d3be1c0c82b Merge: c310480 c4b4d8b Author: Craig Scott AuthorDate: Mon Nov 12 20:42:42 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 15:43:07 2018 -0500 Merge topic 'pie-link-options' c4b4d8b3a6 POSITION_INDEPENDENT_CODE: Manage link flags for executables 724a0346f7 POSITION_INDEPENDENT_CODE: Fix erroneous '-fPIE' flag for Sun Studio 023188ffb4 INTERFACE_POSITION_INDEPENDENT_CODE: add generator expressions support Acked-by: Kitware Robot Merge-request: !2465 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c4b4d8b3a67718e29edb5676273e528dab566672 commit c4b4d8b3a67718e29edb5676273e528dab566672 Author: Marc Chevrier AuthorDate: Tue Oct 2 17:34:57 2018 +0200 Commit: Marc Chevrier CommitDate: Sun Nov 11 17:34:09 2018 +0100 POSITION_INDEPENDENT_CODE: Manage link flags for executables Fixes: #14983, #16561 diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 0587429..98279ef 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14 .. toctree:: :maxdepth: 1 + CMP0083: Add PIE options when linking executable. CMP0082: Install rules from add_subdirectory() are interleaved with those in caller. Policies Introduced by CMake 3.13 diff --git a/Help/policy/CMP0083.rst b/Help/policy/CMP0083.rst new file mode 100644 index 0000000..7b467b0 --- /dev/null +++ b/Help/policy/CMP0083.rst @@ -0,0 +1,24 @@ +CMP0083 +------- + +To control generation of Position Independent Executable (``PIE``) or not, some +flags are required at link time. + +CMake 3.13 and lower did not add these link flags when +:prop_tgt:`POSITION_INDEPENDENT_CODE` is set. + +The ``OLD`` behavior for this policy is to not manage ``PIE`` link flags. The +``NEW`` behavior is to add link flags if :prop_tgt:`POSITION_INDEPENDENT_CODE` +is set: + +* Set to ``TRUE``: flags to produce a position independent executable are + passed to the linker step. For example ``-pie`` for ``GCC``. +* Set to ``FALSE``: flags not to produce a position independent executable are + passed to the linker step. For example ``-no-pie`` for ``GCC``. +* Not set: no flags are passed to the linker step. + +This policy was introduced in CMake version 3.14. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. Use +the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/link-option-PIE.rst b/Help/release/dev/link-option-PIE.rst new file mode 100644 index 0000000..824ab2c --- /dev/null +++ b/Help/release/dev/link-option-PIE.rst @@ -0,0 +1,6 @@ +link-option-PIE +--------------- + +* Required link options to manage Position Independent Executable are now + added when :prop_tgt:`POSITION_INDEPENDENT_CODE` is set. These flags are + controlled by policy :policy:`CMP0083`. diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake index 2975874..a896b99 100644 --- a/Modules/CMakeCXXInformation.cmake +++ b/Modules/CMakeCXXInformation.cmake @@ -105,6 +105,12 @@ endif() if(NOT CMAKE_CXX_COMPILE_OPTIONS_PIE) set(CMAKE_CXX_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE}) endif() +if(NOT CMAKE_CXX_LINK_OPTIONS_PIE) + set(CMAKE_CXX_LINK_OPTIONS_PIE ${CMAKE_C_LINK_OPTIONS_PIE}) +endif() +if(NOT CMAKE_CXX_LINK_OPTIONS_NO_PIE) + set(CMAKE_CXX_LINK_OPTIONS_NO_PIE ${CMAKE_C_LINK_OPTIONS_NO_PIE}) +endif() if(NOT CMAKE_CXX_COMPILE_OPTIONS_DLL) set(CMAKE_CXX_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL}) @@ -269,4 +275,3 @@ CMAKE_VERBOSE_MAKEFILE ) set(CMAKE_CXX_INFORMATION_LOADED 1) - diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index cceac83..ffa6a24 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake @@ -74,6 +74,12 @@ endif() if(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIE) set(CMAKE_Fortran_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE}) endif() +if(NOT CMAKE_Fortran_LINK_OPTIONS_PIE) + set(CMAKE_Fortran_LINK_OPTIONS_PIE ${CMAKE_C_LINK_OPTIONS_PIE}) +endif() +if(NOT CMAKE_Fortran_LINK_OPTIONS_NO_PIE) + set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE ${CMAKE_C_LINK_OPTIONS_NO_PIE}) +endif() if(NOT CMAKE_Fortran_COMPILE_OPTIONS_DLL) set(CMAKE_Fortran_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL}) diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake index a48adec..8754951 100644 --- a/Modules/Compiler/AppleClang-C.cmake +++ b/Modules/Compiler/AppleClang-C.cmake @@ -1,6 +1,9 @@ include(Compiler/Clang) __compiler_clang(C) +set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} -Xlinker -pie) +set(CMAKE_C_LINK_OPTIONS_NO_PIE -Xlinker -no_pie) + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake index e5fd647..54c1388 100644 --- a/Modules/Compiler/AppleClang-CXX.cmake +++ b/Modules/Compiler/AppleClang-CXX.cmake @@ -1,6 +1,9 @@ include(Compiler/Clang) __compiler_clang(CXX) +set(CMAKE_CXX_LINK_OPTIONS_PIE ${CMAKE_CXX_COMPILE_OPTIONS_PIE} -Xlinker -pie) +set(CMAKE_CXX_LINK_OPTIONS_NO_PIE -Xlinker -no_pie) + if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index e23470b..7cee9c7 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -21,6 +21,26 @@ else() macro(__compiler_clang lang) __compiler_gnu(${lang}) set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + # Link options for PIE are already set in 'Compiler/GNU.cmake' + # but clang may require alternate syntax on some platforms + if (NOT CMAKE_${lang}_FLAG_PIE) + cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-Xlinker;-pie" + CMAKE_${lang}_FLAG_XLINKER_PIE) + if (CMAKE_${lang}_FLAG_XLINKER_PIE) + set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-Xlinker" "-pie") + else() + set(CMAKE_${lang}_LINK_OPTIONS_PIE "") + endif() + endif() + if (NOT CMAKE_${lang}_FLAG_NO_PIE) + cmake_check_compiler_flag(${lang} "-Xlinker;-no_pie" + CMAKE_${lang}_FLAG_XLINKER_NO_PIE) + if (CMAKE_${lang}_FLAG_XLINKER_NO_PIE) + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-Xlinker" "-no_pie") + else() + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") + endif() + endif() set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0) diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 4491d4b..688a1b5 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -9,6 +9,7 @@ endif() set(__COMPILER_GNU 1) include(Compiler/CMakeCommonCompilerMacros) +include(Internal/CMakeCheckCompilerFlag) macro(__compiler_gnu lang) # Feature flags. @@ -16,6 +17,21 @@ macro(__compiler_gnu lang) set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4) set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + # Support of PIE at link stage depends on various elements : platform, compiler, linker + # so the easiest way is to check if compiler supports these flags + cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-pie" + CMAKE_${lang}_FLAG_PIE) + if (CMAKE_${lang}_FLAG_PIE) + set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie") + else() + set(CMAKE_${lang}_LINK_OPTIONS_PIE "") + endif() + cmake_check_compiler_flag(${lang} "-no-pie" CMAKE_${lang}_FLAG_NO_PIE) + if (CMAKE_${lang}_FLAG_NO_PIE) + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie") + else() + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") + endif() endif() if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.0) set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index 1988aae..75b8fe6 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -7,6 +7,8 @@ set(CMAKE_C_VERBOSE_FLAG "-#") set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-R") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index f463be3..662ac30 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -7,6 +7,8 @@ set(CMAKE_CXX_VERBOSE_FLAG "-v") set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC) set(CMAKE_CXX_COMPILE_OPTIONS_PIE "") +set(CMAKE_CXX_LINK_OPTIONS_PIE "") +set(CMAKE_CXX_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-R") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index d3a415f..e110253 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -4,6 +4,8 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC") set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "") +set(CMAKE_Fortran_LINK_OPTIONS_PIE "") +set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R") diff --git a/Modules/Internal/CMakeCheckCompilerFlag.cmake b/Modules/Internal/CMakeCheckCompilerFlag.cmake new file mode 100644 index 0000000..ca9b356 --- /dev/null +++ b/Modules/Internal/CMakeCheckCompilerFlag.cmake @@ -0,0 +1,146 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=[ + +NOTE: This function is used internally by CMake. Projects should not include + this file directly. + +The cmake_check_compiler_flag() function can be used to compile and link a +source file to check whether a specific compiler or linker flag is supported. +The function does not use the try_compile() command so as to avoid infinite +recursion. It may not work for all platforms or toolchains, the caller is +responsible for ensuring it is only called in valid situations. + +Parameters: + lang - Language to check. + flag - The flag to add to the compile/link command line. + result - Boolean output variable. It will be stored in the cache as an + internal variable and if true, will cause future tests that assign + to that variable to be bypassed. + +Optional parameters: + SRC_EXT - Overrides the extension of the source file used for the + check. Defaults are 'c' (C), 'cxx' (CXX), 'F' (Fortran). + COMMAND_PATTERN - Pattern to be used for the command line. The default is + ' -o ' + FAIL_REGEX - List of additional regular expressions that, if matched by + the output, give a failed result for the check. A common + set of regular expressions will be included in addition to + those given by FAIL_REGEX. + +#]=] + +include_guard(GLOBAL) +include(CMakeCheckCompilerFlagCommonPatterns) + +function(CMAKE_CHECK_COMPILER_FLAG lang flag result) + # Cache results between runs similar to check__source_compiles() + if(DEFINED ${result}) + return() + endif() + + set(comment "Is the '${flag}' option(s) supported") + string(REPLACE ";" " " comment "${comment}") + + if (NOT lang MATCHES "^(C|CXX|Fortran|ASM)$") + # other possible languages are not supported + # log message to keep trace of this problem... + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Function 'CMAKE_CHECK_COMPILER_FLAG' called with unsupported language: ${lang}\n") + set(${result} FALSE CACHE INTERNAL ${comment}) + return() + endif() + if (lang STREQUAL "ASM") + # assume ASM compiler is a multi-language compiler, so supports C language as well + set(check_lang C) + else() + set(check_lang ${lang}) + endif() + + cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN" "FAIL_REGEX" ${ARGN}) + + if (NOT CCCF_COMMAND_PATTERN) + set (CCCF_COMMAND_PATTERN " -o ") + endif() + + list (APPEND CCCF_FAIL_REGEX "argument unused during compilation") # clang + if (check_lang STREQUAL "C") + list(APPEND CCCF_FAIL_REGEX + "command line option .* is valid for .* but not for C") # GNU + elseif(check_lang STREQUAL "CXX") + list(APPEND CCCF_FAIL_REGEX + "command line option .* is valid for .* but not for C\\+\\+") # GNU + elseif(check_lang STREQUAL "Fortran") + list(APPEND CCCF_FAIL_REGEX + "command line option .* is valid for .* but not for Fortran") # GNU + endif() + + # Add patterns for common errors + check_compiler_flag_common_patterns(COMPILER_FLAG_COMMON_PATTERNS) + foreach(arg IN LISTS COMPILER_FLAG_COMMON_PATTERNS) + if(arg MATCHES "^FAIL_REGEX$") + continue() + endif() + list(APPEND CCCF_FAIL_REGEX "${arg}") + endforeach() + + if(NOT CCCF_SRC_EXT) + if (check_lang STREQUAL "C") + set(CCCF_SRC_EXT c) + elseif(check_lang STREQUAL "CXX") + set(CCCF_SRC_EXT cxx) + elseif(check_lang STREQUAL "Fortran") + set(CCCF_SRC_EXT F) + endif() + endif() + + # Compute the directory in which to run the test. + set(COMPILER_FLAG_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp") + # Compute source and output files. + set(COMPILER_FLAG_SRC + "${COMPILER_FLAG_DIR}/CompilerFlag${lang}.${CCCF_SRC_EXT}") + if(check_lang STREQUAL "Fortran") + file(WRITE "${COMPILER_FLAG_SRC}" + " program simple\n end program simple\n") + else() + file(WRITE "${COMPILER_FLAG_SRC}" "int main (void)\n{ return 0; }\n") + endif() + get_filename_component(COMPILER_FLAG_EXE "${COMPILER_FLAG_SRC}" NAME_WE) + string(APPEND COMPILER_FLAG_EXE "${CMAKE_EXECUTABLE_SUFFIX}") + + # Build command line + separate_arguments(CCCF_COMMAND_PATTERN UNIX_COMMAND + "${CCCF_COMMAND_PATTERN}") + list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${COMPILER_FLAG_SRC}") + list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${COMPILER_FLAG_EXE}") + list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${flag}") + + execute_process( + COMMAND "${CMAKE_COMMAND}" -E env LC_ALL=C LC_MESSAGES=C LANG=C + "${CMAKE_${lang}_COMPILER}" ${CCCF_COMMAND_PATTERN} + WORKING_DIRECTORY "${COMPILER_FLAG_DIR}" + OUTPUT_VARIABLE COMPILER_FLAG_OUTPUT + ERROR_VARIABLE COMPILER_FLAG_OUTPUT + RESULT_VARIABLE COMPILER_FLAG_RESULT) + + # Record result in the cache so we can avoid re-testing every CMake run + if (COMPILER_FLAG_RESULT) + set(${result} FALSE CACHE INTERNAL ${comment}) + else() + foreach(regex IN LISTS CCCF_FAIL_REGEX) + if(COMPILER_FLAG_OUTPUT MATCHES "${regex}") + set(${result} FALSE CACHE INTERNAL ${comment}) + endif() + endforeach() + endif() + if (DEFINED ${result}) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the ${flag} option " + "is supported for ${lang} language failed with the following output:\n" + "${COMPILER_FLAG_OUTPUT}\n") + return() + endif() + + set(${result} TRUE CACHE INTERNAL ${comment}) +endfunction() diff --git a/Modules/Platform/Android/abi-common.cmake b/Modules/Platform/Android/abi-common.cmake index 10fb897..a0b47f4 100644 --- a/Modules/Platform/Android/abi-common.cmake +++ b/Modules/Platform/Android/abi-common.cmake @@ -12,10 +12,6 @@ if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() -if(CMAKE_POSITION_INDEPENDENT_CODE) - string(APPEND _ANDROID_ABI_INIT_EXE_LDFLAGS " -fPIE -pie") -endif() - string(APPEND _ANDROID_ABI_INIT_EXE_LDFLAGS " -Wl,--gc-sections") if(NOT _ANDROID_ABI_INIT_EXE_LDFLAGS_NO_nocopyreloc) diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index 784c8c6..f55b80d 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -27,6 +27,8 @@ macro(__cygwin_compiler_gnu lang) # No -fPIC on cygwin set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "") # Initialize C link type selection flags. These flags are used when diff --git a/Modules/Platform/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake index 082e9f6..4a4c00d 100644 --- a/Modules/Platform/FreeBSD.cmake +++ b/Modules/Platform/FreeBSD.cmake @@ -1,6 +1,7 @@ set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") +# PIE link options are managed in Compiler/.cmake file set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib diff --git a/Modules/Platform/Fuchsia.cmake b/Modules/Platform/Fuchsia.cmake index 896da7b..7b33434 100644 --- a/Modules/Platform/Fuchsia.cmake +++ b/Modules/Platform/Fuchsia.cmake @@ -3,6 +3,8 @@ set(FUCHSIA 1) set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") +set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} "-pie") +set(CMAKE_C_LINK_OPTIONS_NO_PIE "-no-pie") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake index f712e2b..ab22b1d 100644 --- a/Modules/Platform/Linux-Intel.cmake +++ b/Modules/Platform/Linux-Intel.cmake @@ -23,6 +23,10 @@ endif() macro(__linux_compiler_intel lang) set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 13.0) + set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie") + endif() set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake index db032c2..3e7e391 100644 --- a/Modules/Platform/Linux-PGI.cmake +++ b/Modules/Platform/Linux-PGI.cmake @@ -12,6 +12,8 @@ macro(__linux_compiler_pgi lang) # Shared library compile and link flags. set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS " ") diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake index a8f4cc8..d99cb4a 100644 --- a/Modules/Platform/NetBSD.cmake +++ b/Modules/Platform/NetBSD.cmake @@ -1,6 +1,7 @@ set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") +# PIE link options are managed in Compiler/.cmake file set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib diff --git a/Modules/Platform/SINIX.cmake b/Modules/Platform/SINIX.cmake index c37a113..e44ceef 100644 --- a/Modules/Platform/SINIX.cmake +++ b/Modules/Platform/SINIX.cmake @@ -1,4 +1,6 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") include(Platform/UnixPaths) diff --git a/Modules/Platform/UNIX_SV.cmake b/Modules/Platform/UNIX_SV.cmake index 1ec96ae..433daf3 100644 --- a/Modules/Platform/UNIX_SV.cmake +++ b/Modules/Platform/UNIX_SV.cmake @@ -1,5 +1,7 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-Bexport") include(Platform/UnixPaths) diff --git a/Modules/Platform/UnixWare.cmake b/Modules/Platform/UnixWare.cmake index e649bd2..8c9d430 100644 --- a/Modules/Platform/UnixWare.cmake +++ b/Modules/Platform/UnixWare.cmake @@ -1,5 +1,7 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_PIE "") +set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-Wl,-Bexport") include(Platform/UnixPaths) diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index cfb325b..2e854e5 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -72,6 +72,8 @@ macro(__windows_compiler_gnu lang) # No -fPIC on Windows set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_PIE "") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "") set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS ${__WINDOWS_GNU_LD_RESPONSE}) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index a278a7f..0b28d1e 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -495,6 +495,36 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature, return this->LocalGenerator->GetFeature(feature, config); } +const char* cmGeneratorTarget::GetLinkPIEProperty( + const std::string& config) const +{ + static std::string PICValue; + + PICValue = this->GetLinkInterfaceDependentStringAsBoolProperty( + "POSITION_INDEPENDENT_CODE", config); + + if (PICValue == "(unset)") { + // POSITION_INDEPENDENT_CODE is not set + return nullptr; + } + + switch (this->GetPolicyStatusCMP0083()) { + case cmPolicies::WARN: { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0083); + this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + CM_FALLTHROUGH; + } + case cmPolicies::OLD: + return nullptr; + default: + // nothing to do + break; + } + + return PICValue.c_str(); +} + bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang, std::string const& config) const { @@ -4237,6 +4267,29 @@ void cmGeneratorTarget::CheckPropertyCompatibility( } } +template +std::string valueAsString(PropertyType); +template <> +std::string valueAsString(bool value) +{ + return value ? "TRUE" : "FALSE"; +} +template <> +std::string valueAsString(const char* value) +{ + return value ? value : "(unset)"; +} +template <> +std::string valueAsString(std::string value) +{ + return value; +} +template <> +std::string valueAsString(std::nullptr_t /*unused*/) +{ + return "(unset)"; +} + std::string compatibilityType(CompatibleType t) { switch (t) { @@ -4299,17 +4352,18 @@ const char* getTypedProperty( return genexInterpreter->Evaluate(value, prop).c_str(); } -template -std::string valueAsString(PropertyType); -template <> -std::string valueAsString(bool value) -{ - return value ? "TRUE" : "FALSE"; -} template <> -std::string valueAsString(const char* value) +std::string getTypedProperty( + cmGeneratorTarget const* tgt, const std::string& prop, + cmGeneratorExpressionInterpreter* genexInterpreter) { - return value ? value : "(unset)"; + const char* value = tgt->GetProperty(prop); + + if (genexInterpreter == nullptr) { + return valueAsString(value); + } + + return genexInterpreter->Evaluate(value, prop); } template @@ -4324,6 +4378,12 @@ const char* impliedValue(const char* /*unused*/) { return ""; } +template <> +std::string impliedValue( + std::string /*unused*/) // NOLINT(clang-tidy) +{ + return std::string(); +} template std::pair consistentProperty(PropertyType lhs, @@ -4344,6 +4404,13 @@ std::pair consistentStringProperty(const char* lhs, return std::make_pair(b, b ? lhs : nullptr); } +std::pair consistentStringProperty(const std::string& lhs, + const std::string& rhs) +{ + const bool b = lhs == rhs; + return std::make_pair(b, b ? lhs : valueAsString(nullptr)); +} + std::pair consistentNumberProperty(const char* lhs, const char* rhs, CompatibleType t) @@ -4386,9 +4453,10 @@ std::pair consistentProperty(const char* lhs, const char* const null_ptr = nullptr; switch (t) { - case BoolType: - assert(false && "consistentProperty for strings called with BoolType"); - return std::pair(false, null_ptr); + case BoolType: { + bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs); + return std::make_pair(same, same ? lhs : nullptr); + } case StringType: return consistentStringProperty(lhs, rhs); case NumberMinType: @@ -4399,6 +4467,40 @@ std::pair consistentProperty(const char* lhs, return std::pair(false, null_ptr); } +std::pair consistentProperty(const std::string& lhs, + const std::string& rhs, + CompatibleType t) +{ + const std::string null_ptr = valueAsString(nullptr); + + if (lhs == null_ptr && rhs == null_ptr) { + return std::make_pair(true, lhs); + } + if (lhs == null_ptr) { + return std::make_pair(true, rhs); + } + if (rhs == null_ptr) { + return std::make_pair(true, lhs); + } + + switch (t) { + case BoolType: { + bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs); + return std::make_pair(same, same ? lhs : null_ptr); + } + case StringType: + return consistentStringProperty(lhs, rhs); + case NumberMinType: + case NumberMaxType: { + auto value = consistentNumberProperty(lhs.c_str(), rhs.c_str(), t); + return std::make_pair( + value.first, value.first ? std::string(value.second) : null_ptr); + } + } + assert(false && "Unreachable!"); + return std::pair(false, null_ptr); +} + template PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, const std::string& p, @@ -4408,6 +4510,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, PropertyType* /*unused*/) { PropertyType propContent = getTypedProperty(tgt, p); + std::vector headPropKeys = tgt->GetPropertyKeys(); const bool explicitlySet = std::find(headPropKeys.begin(), headPropKeys.end(), p) != @@ -4552,6 +4655,13 @@ bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty( BoolType, nullptr); } +std::string cmGeneratorTarget::GetLinkInterfaceDependentStringAsBoolProperty( + const std::string& p, const std::string& config) const +{ + return checkInterfacePropertyCompatibility( + this, p, config, "FALSE", BoolType, nullptr); +} + const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty( const std::string& p, const std::string& config) const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 5e7cf12..52defee 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -173,6 +173,8 @@ public: const char* GetFeature(const std::string& feature, const std::string& config) const; + const char* GetLinkPIEProperty(const std::string& config) const; + bool IsIPOEnabled(std::string const& lang, std::string const& config) const; bool IsLinkInterfaceDependentBoolProperty(const std::string& p, @@ -789,6 +791,9 @@ private: cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap( std::string const& config) const; + std::string GetLinkInterfaceDependentStringAsBoolProperty( + const std::string& p, const std::string& config) const; + // Cache import information from properties for each configuration. struct ImportInfo { diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index b7a361e..8a38f9b 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1755,6 +1755,26 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( } } +void cmGlobalXCodeGenerator::AddPositionIndependentLinkAttribute( + cmGeneratorTarget* target, cmXCodeObject* buildSettings, + const std::string& configName) +{ + // For now, only EXECUTABLE is concerned + if (target->GetType() != cmStateEnums::EXECUTABLE) { + return; + } + + const char* PICValue = target->GetLinkPIEProperty(configName); + if (PICValue == nullptr) { + // POSITION_INDEPENDENT_CODE is not set + return; + } + + buildSettings->AddAttribute( + "LD_NO_PIE", + this->CreateString(cmSystemTools::IsOn(PICValue) ? "NO" : "YES")); +} + void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, cmXCodeObject* buildSettings, const std::string& configName) @@ -1806,6 +1826,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, buildSettings->AddAttribute("LLVM_LTO", this->CreateString(ltoValue)); } + // Handle PIE linker configuration + this->AddPositionIndependentLinkAttribute(gtgt, buildSettings, configName); + // Add define flags this->CurrentLocalGenerator->AppendFlags( defFlags, this->CurrentMakefile->GetDefineFlags()); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 62f7030..9b0d4fe 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -171,6 +171,9 @@ private: const std::string& configName); cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt); void AddDependAndLinkInformation(cmXCodeObject* target); + void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target, + cmXCodeObject* buildSettings, + const std::string& configName); void CreateBuildSettings(cmGeneratorTarget* gtgt, cmXCodeObject* buildSettings, const std::string& buildType); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index a703f4d..da48950 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1201,6 +1201,8 @@ void cmLocalGenerator::GetTargetFlags( break; } + this->AppendPositionIndependentLinkerFlags(linkFlags, target, config, + linkLanguage); this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage); } @@ -2027,6 +2029,36 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, } } +void cmLocalGenerator::AppendPositionIndependentLinkerFlags( + std::string& flags, cmGeneratorTarget* target, const std::string& config, + const std::string& lang) +{ + // For now, only EXECUTABLE is concerned + if (target->GetType() != cmStateEnums::EXECUTABLE) { + return; + } + + const char* PICValue = target->GetLinkPIEProperty(config); + if (PICValue == nullptr) { + // POSITION_INDEPENDENT_CODE is not set + return; + } + + std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_"; + name += cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE"; + + auto pieFlags = this->Makefile->GetSafeDefinition(name); + if (pieFlags.empty()) { + return; + } + + std::vector flagsList; + cmSystemTools::ExpandListArgument(pieFlags, flagsList); + for (const auto& flag : flagsList) { + this->AppendFlagEscape(flags, flag); + } +} + void cmLocalGenerator::AppendCompileOptions(std::string& options, const char* options_list, const char* regex) const diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 3dd6929..2fa0070 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -126,6 +126,10 @@ public: void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, const std::string& config, const std::string& lang); + void AppendPositionIndependentLinkerFlags(std::string& flags, + cmGeneratorTarget* target, + const std::string& config, + const std::string& lang); ///! Get the include flags for the current makefile and language std::string GetIncludeFlags(const std::vector& includes, cmGeneratorTarget* target, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 3c46784..9acae49 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -97,6 +97,9 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags( this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage); // LINK_OPTIONS are escaped. this->LocalGenerator->AppendCompileOptions(flags, opts); + + this->LocalGenerator->AppendPositionIndependentLinkerFlags( + flags, this->GeneratorTarget, this->ConfigName, linkLanguage); } void cmMakefileTargetGenerator::CreateRuleFile() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 5c27124..52ef470 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -244,7 +244,9 @@ class cmMakefile; SELECT(POLICY, CMP0082, \ "Install rules from add_subdirectory() are interleaved with those " \ "in caller.", \ - 3, 14, 0, cmPolicies::WARN) + 3, 14, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0083, "Add PIE options when linking executable.", 3, 14, \ + 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ @@ -271,7 +273,8 @@ class cmMakefile; F(CMP0069) \ F(CMP0073) \ F(CMP0076) \ - F(CMP0081) + F(CMP0081) \ + F(CMP0083) /** \class cmPolicies * \brief Handles changes in CMake behavior and policies diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e23926f..b6b6519 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -190,7 +190,8 @@ add_RunCMake_test(PolicyScope) add_RunCMake_test(WriteCompilerDetectionHeader) add_RunCMake_test(SourceProperties) if(NOT WIN32) - add_RunCMake_test(PositionIndependentCode) + add_RunCMake_test(PositionIndependentCode -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} + -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) endif() if(NOT CMAKE_GENERATOR MATCHES "Visual Studio") add_RunCMake_test(VisibilityPreset) diff --git a/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_new-check.cmake b/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_new-check.cmake new file mode 100644 index 0000000..255e63d --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_new-check.cmake @@ -0,0 +1,22 @@ + +include ("${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/CMP0083_config.cmake") + + +# retrieve default type of executable +check_executable ("${cmp0083_ref}" ref) + +if (ref STREQUAL "PIE") + # check no_pie executable is really no position independent + check_executable ("${cmp0083_new_no_pie}" new_no_pie) + if (NOT new_no_pie STREQUAL "NO_PIE") + set (RunCMake_TEST_FAILED "CMP0083(NEW) do not produce expected executable.") + endif() +elseif (ref STREQUAL "NO_PIE") + # check pie executable is really position independent + check_executable ("${cmp0083_new_pie}" new_pie) + if (NOT new_pie MATCHES "PIE") + set (RunCMake_TEST_FAILED "CMP0083(NEW) do not produce expected executable.") + endif() +else() + set (RunCMake_TEST_FAILED "CMP0083(NEW) unexpected result.") +endif() diff --git a/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_old-check.cmake b/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_old-check.cmake new file mode 100644 index 0000000..b66b672 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_old-check.cmake @@ -0,0 +1,20 @@ + +include ("${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/CMP0083_config.cmake") + + +# retrieve default type of executable +check_executable ("${cmp0083_ref}" ref) + +# POSITION_INDEPENDENT_CODE must not have influence on executable +# pie and no_pie executable must have same type as reference +check_executable ("${cmp0083_old_pie}" old_pie) +if (NOT old_pie STREQUAL ref) + set (RunCMake_TEST_FAILED "CMP0083(OLD) do not produce expected executable.") + return() +endif() + +check_executable ("${cmp0083_old_no_pie}" old_no_pie) +if (NOT old_no_pie STREQUAL ref) + set (RunCMake_TEST_FAILED "CMP0083(OLD) do not produce expected executable.") + return() +endif() diff --git a/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake new file mode 100644 index 0000000..9713ea4 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake @@ -0,0 +1,45 @@ + +# create reference to detect default : PIE or not +add_executable (cmp0083_ref main.cpp) + + +set (CMAKE_POSITION_INDEPENDENT_CODE ON) + +cmake_policy(SET CMP0083 NEW) +add_executable (cmp0083_new_pie main.cpp) + + +cmake_policy(SET CMP0083 OLD) +add_executable (cmp0083_old_pie main.cpp) + + +set (CMAKE_POSITION_INDEPENDENT_CODE OFF) + +cmake_policy(SET CMP0083 NEW) +add_executable (cmp0083_new_no_pie main.cpp) + + +cmake_policy(SET CMP0083 OLD) +add_executable (cmp0083_old_no_pie main.cpp) + +# high-level targets +add_custom_target(cmp0083_new) +add_dependencies(cmp0083_new cmp0083_ref cmp0083_new_pie cmp0083_new_no_pie) + +# high-level targets +add_custom_target(cmp0083_old) +add_dependencies(cmp0083_old cmp0083_ref cmp0083_old_pie cmp0083_old_no_pie) + + +# generate file holding paths to executables +file (GENERATE OUTPUT "${CMAKE_BINARY_DIR}/$/CMP0083_config.cmake" + CONTENT +[==[ +include ("${RunCMake_TEST_SOURCE_DIR}/PIE_validator.cmake") + +set (cmp0083_ref "$") +set (cmp0083_new_pie "$") +set (cmp0083_old_pie "$") +set (cmp0083_new_no_pie "$") +set (cmp0083_old_no_pie "$") +]==]) diff --git a/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake new file mode 100644 index 0000000..1e0a2c9 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake @@ -0,0 +1,12 @@ + +if (CMAKE_CXX_LINK_OPTIONS_PIE) + file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED TRUE)\n") +else() + file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED FALSE)\n") +endif() + +if (CMAKE_CXX_LINK_OPTIONS_NO_PIE) + file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED TRUE)\n") +else() + file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED FALSE)\n") +endif() diff --git a/Tests/RunCMake/PositionIndependentCode/PIE-pie_off-check.cmake b/Tests/RunCMake/PositionIndependentCode/PIE-pie_off-check.cmake new file mode 100644 index 0000000..096395c --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/PIE-pie_off-check.cmake @@ -0,0 +1,7 @@ + +include ("${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/PIE_config.cmake") + +check_executable ("${pie_off}" status) +if (NOT status STREQUAL "NO_PIE") + set (RunCMake_TEST_FAILED "Executable is NOT 'no PIE' (${status}).") +endif() diff --git a/Tests/RunCMake/PositionIndependentCode/PIE-pie_on-check.cmake b/Tests/RunCMake/PositionIndependentCode/PIE-pie_on-check.cmake new file mode 100644 index 0000000..bf3d018 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/PIE-pie_on-check.cmake @@ -0,0 +1,7 @@ + +include ("${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/PIE_config.cmake") + +check_executable ("${pie_on}" status) +if (NOT status STREQUAL "PIE") + set (RunCMake_TEST_FAILED "Executable is NOT 'PIE' (${status}).") +endif() diff --git a/Tests/RunCMake/PositionIndependentCode/PIE.cmake b/Tests/RunCMake/PositionIndependentCode/PIE.cmake new file mode 100644 index 0000000..a9d579d --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/PIE.cmake @@ -0,0 +1,19 @@ + +cmake_policy(SET CMP0083 NEW) + +add_executable (pie_on main.cpp) +set_property(TARGET pie_on PROPERTY POSITION_INDEPENDENT_CODE ON) + +add_executable (pie_off main.cpp) +set_property(TARGET pie_off PROPERTY POSITION_INDEPENDENT_CODE OFF) + + +# generate file holding paths to executables +file (GENERATE OUTPUT "${CMAKE_BINARY_DIR}/$/PIE_config.cmake" + CONTENT +[==[ +include ("${RunCMake_TEST_SOURCE_DIR}/PIE_validator.cmake") + +set (pie_on "$") +set (pie_off "$") +]==]) diff --git a/Tests/RunCMake/PositionIndependentCode/PIE_validator.cmake b/Tests/RunCMake/PositionIndependentCode/PIE_validator.cmake new file mode 100644 index 0000000..7be35db --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/PIE_validator.cmake @@ -0,0 +1,32 @@ + +include_guard(GLOBAL) + +function (CHECK_EXECUTABLE executable result) + set (${result} "UNKNOWN" PARENT_SCOPE) + + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set (tool otool -hv) + else() + set (tool "${CMAKE_COMMAND}" -E env LANG=C LC_ALL=C readelf -lW) + endif() + + execute_process(COMMAND ${tool} "${executable}" + OUTPUT_VARIABLE output + ERROR_VARIABLE output) + + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + if (output MATCHES "( |\t)PIE( |\n|$)") + set (${result} "PIE" PARENT_SCOPE) + else() + set (${result} "NO_PIE" PARENT_SCOPE) + endif() + else() + if (output MATCHES "Elf file type is DYN") + set (${result} "PIE" PARENT_SCOPE) + elseif (output MATCHES "Elf file type is EXEC") + set (${result} "NO_PIE" PARENT_SCOPE) + else() + message(SEND_ERROR "Did not find a known file type") + endif() + endif() +endfunction() diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake index 20187d3..6efa0d4 100644 --- a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake +++ b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake @@ -9,3 +9,65 @@ run_cmake(Conflict6) run_cmake(Debug) run_cmake(Genex1) run_cmake(Genex2) + +set(RunCMake_TEST_OPTIONS "-DPIE_SUPPORTED=${RunCMake_BINARY_DIR}/PIESupported.cmake") +run_cmake(CheckPIESupported) +include ("${RunCMake_BINARY_DIR}/PIESupported.cmake" OPTIONAL) + +if (PIE_SUPPORTED OR NO_PIE_SUPPORTED) + if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|(Free|Net|Open)BSD)$") + # try to locate readelf needed for validation + find_program (READELF NAMES readelf) + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # try to locate otool needed for validation + find_program (OTOOL NAMES otool) + endif() + + if ((READELF OR OTOOL) AND + (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) + macro(run_cmake_target test subtest) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_CONFIG Release) + run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --config Release --target ${subtest} ${ARGN}) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + endmacro() + + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_SOURCE_DIR}") + set(RunCMake_TEST_OUTPUT_MERGE TRUE) + if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release) + endif() + + run_cmake(PIE) + if (PIE_SUPPORTED) + run_cmake_target(PIE pie_on) + endif() + if (NO_PIE_SUPPORTED) + run_cmake_target(PIE pie_off) + endif() + + run_cmake(CMP0083) + run_cmake_target(CMP0083 cmp0083_ref) + + # retrieve default mode + include("${RunCMake_SOURCE_DIR}/PIE_validator.cmake") + include("${RunCMake_BINARY_DIR}/CMP0083-build/Release/CMP0083_config.cmake") + check_executable("${cmp0083_ref}" cmp0083_ref_mode) + + if ((cmp0083_ref_mode STREQUAL "PIE" AND NO_PIE_SUPPORTED) + OR (cmp0083_ref_mode STREQUAL "NO_PIE" AND PIE_SUPPORTED)) + run_cmake_target(CMP0083 cmp0083_new) + endif() + run_cmake_target(CMP0083 cmp0083_old) + + unset(RunCMake_TEST_SOURCE_DIR) + unset(RunCMake_TEST_OPTIONS) + unset(RunCMake_TEST_OUTPUT_MERGE) + endif() +endif() diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt index 2441a9c..0bcf886 100644 --- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt +++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt @@ -26,6 +26,7 @@ \* CMP0073 \* CMP0076 \* CMP0081 + \* CMP0083 Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=724a0346f7bd424ce0e5db246cee46db9f377a6f commit 724a0346f7bd424ce0e5db246cee46db9f377a6f Author: Marc Chevrier AuthorDate: Thu Oct 11 12:20:29 2018 +0200 Commit: Marc Chevrier CommitDate: Thu Nov 8 14:58:57 2018 +0100 POSITION_INDEPENDENT_CODE: Fix erroneous '-fPIE' flag for Sun Studio Fixes: #16311 diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index 047de43..1988aae 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -6,6 +6,7 @@ include(Compiler/SunPro) set(CMAKE_C_VERBOSE_FLAG "-#") set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC) +set(CMAKE_C_COMPILE_OPTIONS_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-R") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index 4c1ac5b..f463be3 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -6,6 +6,7 @@ include(Compiler/SunPro) set(CMAKE_CXX_VERBOSE_FLAG "-v") set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC) +set(CMAKE_CXX_COMPILE_OPTIONS_PIE "") set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-R") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index 2247dd0..d3a415f 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -3,6 +3,7 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC") +set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=023188ffb48cc35ebab7cabbafefcd6dd31b750d commit 023188ffb48cc35ebab7cabbafefcd6dd31b750d Author: Marc Chevrier AuthorDate: Fri Sep 28 17:30:22 2018 +0200 Commit: Marc Chevrier CommitDate: Thu Nov 8 14:58:57 2018 +0100 INTERFACE_POSITION_INDEPENDENT_CODE: add generator expressions support Fixes: #16532 diff --git a/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst index ea700df..4336d71 100644 --- a/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst +++ b/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst @@ -14,3 +14,9 @@ undefined, then consumers will determine their :prop_tgt:`POSITION_INDEPENDENT_CODE` property by other means. Consumers must ensure that the targets that they link to have a consistent requirement for their ``INTERFACE_POSITION_INDEPENDENT_CODE`` property. + +Contents of ``INTERFACE_POSITION_INDEPENDENT_CODE`` may use +"generator expressions" with the syntax ``$<...>``. See the +:manual:`cmake-generator-expressions(7)` manual for available expressions. +See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem +properties. diff --git a/Help/release/dev/INTERFACE_POSITION_INDEPENDENT_CODE.rst b/Help/release/dev/INTERFACE_POSITION_INDEPENDENT_CODE.rst new file mode 100644 index 0000000..7732ff6 --- /dev/null +++ b/Help/release/dev/INTERFACE_POSITION_INDEPENDENT_CODE.rst @@ -0,0 +1,5 @@ +INTERFACE_POSITION_INDEPENDENT_CODE +----------------------------------- + +* :prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` target property gains the + support of :manual:`generator expressions `. diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 8d57441..56eb2bf 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -166,6 +166,18 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL"; } +bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression() +{ + const cmGeneratorExpressionDAGChecker* top = this; + const cmGeneratorExpressionDAGChecker* parent = this->Parent; + while (parent) { + top = parent; + parent = parent->Parent; + } + + return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE"; +} + bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries( cmGeneratorTarget const* tgt) { diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index a5134c3..1525c39 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -66,6 +66,7 @@ struct cmGeneratorExpressionDAGChecker const std::string& expr); bool EvaluatingGenexExpression(); + bool EvaluatingPICExpression(); bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr); #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index f901215..49b97fb 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1225,7 +1225,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode const char* prop = target->GetProperty(propertyName); if (dagCheckerParent) { - if (dagCheckerParent->EvaluatingGenexExpression()) { + if (dagCheckerParent->EvaluatingGenexExpression() || + dagCheckerParent->EvaluatingPICExpression()) { // No check required. } else if (dagCheckerParent->EvaluatingLinkLibraries()) { #define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \ diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 1663400..a278a7f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4268,21 +4268,35 @@ std::string compatibilityAgree(CompatibleType t, bool dominant) } template -PropertyType getTypedProperty(cmGeneratorTarget const* tgt, - const std::string& prop); +PropertyType getTypedProperty( + cmGeneratorTarget const* tgt, const std::string& prop, + cmGeneratorExpressionInterpreter* genexInterpreter = nullptr); template <> bool getTypedProperty(cmGeneratorTarget const* tgt, - const std::string& prop) + const std::string& prop, + cmGeneratorExpressionInterpreter* genexInterpreter) { - return tgt->GetPropertyAsBool(prop); + if (genexInterpreter == nullptr) { + return tgt->GetPropertyAsBool(prop); + } + + const char* value = tgt->GetProperty(prop); + return cmSystemTools::IsOn(genexInterpreter->Evaluate(value, prop)); } template <> -const char* getTypedProperty(cmGeneratorTarget const* tgt, - const std::string& prop) +const char* getTypedProperty( + cmGeneratorTarget const* tgt, const std::string& prop, + cmGeneratorExpressionInterpreter* genexInterpreter) { - return tgt->GetProperty(prop); + const char* value = tgt->GetProperty(prop); + + if (genexInterpreter == nullptr) { + return value; + } + + return genexInterpreter->Evaluate(value, prop).c_str(); } template @@ -4423,6 +4437,11 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, } std::string interfaceProperty = "INTERFACE_" + p; + std::unique_ptr genexInterpreter( + p == "POSITION_INDEPENDENT_CODE" ? new cmGeneratorExpressionInterpreter( + tgt->GetLocalGenerator(), config, tgt) + : nullptr); + for (cmGeneratorTarget const* theTarget : deps) { // An error should be reported if one dependency // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other @@ -4434,8 +4453,8 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, const bool ifaceIsSet = std::find(propKeys.begin(), propKeys.end(), interfaceProperty) != propKeys.end(); - PropertyType ifacePropContent = - getTypedProperty(theTarget, interfaceProperty); + PropertyType ifacePropContent = getTypedProperty( + theTarget, interfaceProperty, genexInterpreter.get()); std::string reportEntry; if (ifaceIsSet) { diff --git a/Tests/RunCMake/PositionIndependentCode/Genex1-result.txt b/Tests/RunCMake/PositionIndependentCode/Genex1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Genex1-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Genex1-stderr.txt new file mode 100644 index 0000000..c242a05 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex1-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict1" does +not match the INTERFACE_POSITION_INDEPENDENT_CODE property requirement +of dependency "genex_pic". diff --git a/Tests/RunCMake/PositionIndependentCode/Genex1.cmake b/Tests/RunCMake/PositionIndependentCode/Genex1.cmake new file mode 100644 index 0000000..a91be3e --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex1.cmake @@ -0,0 +1,9 @@ + +add_library(genex_pic UNKNOWN IMPORTED) +# PIC is ON if sibling target is a library, OFF if it is an executable +set_property(TARGET genex_pic PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE $,EXECUTABLE>>) + + +add_library(conflict1 STATIC main.cpp) +set_property(TARGET conflict1 PROPERTY POSITION_INDEPENDENT_CODE OFF) +target_link_libraries(conflict1 PRIVATE genex_pic) diff --git a/Tests/RunCMake/PositionIndependentCode/Genex2-result.txt b/Tests/RunCMake/PositionIndependentCode/Genex2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Genex2-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Genex2-stderr.txt new file mode 100644 index 0000000..735a926 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex2-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict2" does +not match the INTERFACE_POSITION_INDEPENDENT_CODE property requirement +of dependency "genex_pic". diff --git a/Tests/RunCMake/PositionIndependentCode/Genex2.cmake b/Tests/RunCMake/PositionIndependentCode/Genex2.cmake new file mode 100644 index 0000000..fb0a5db --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Genex2.cmake @@ -0,0 +1,9 @@ + +add_library(genex_pic UNKNOWN IMPORTED) +# PIC is ON if sibling target is a library, OFF if it is an executable +set_property(TARGET genex_pic PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE $,EXECUTABLE>>) + + +add_executable(conflict2 main.cpp) +set_property(TARGET conflict2 PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(conflict2 PRIVATE genex_pic) diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake index 6a67e3c..20187d3 100644 --- a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake +++ b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake @@ -7,3 +7,5 @@ run_cmake(Conflict4) run_cmake(Conflict5) run_cmake(Conflict6) run_cmake(Debug) +run_cmake(Genex1) +run_cmake(Genex2) ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0083.rst | 24 +++ .../INTERFACE_POSITION_INDEPENDENT_CODE.rst | 6 + .../dev/INTERFACE_POSITION_INDEPENDENT_CODE.rst | 5 + Help/release/dev/link-option-PIE.rst | 6 + Modules/CMakeCXXInformation.cmake | 7 +- Modules/CMakeFortranInformation.cmake | 6 + Modules/Compiler/AppleClang-C.cmake | 3 + Modules/Compiler/AppleClang-CXX.cmake | 3 + Modules/Compiler/Clang.cmake | 20 +++ Modules/Compiler/GNU.cmake | 16 ++ Modules/Compiler/SunPro-C.cmake | 3 + Modules/Compiler/SunPro-CXX.cmake | 3 + Modules/Compiler/SunPro-Fortran.cmake | 3 + Modules/Internal/CMakeCheckCompilerFlag.cmake | 146 ++++++++++++++++++ Modules/Platform/Android/abi-common.cmake | 4 - Modules/Platform/CYGWIN-GNU.cmake | 2 + Modules/Platform/FreeBSD.cmake | 1 + Modules/Platform/Fuchsia.cmake | 2 + Modules/Platform/Linux-Intel.cmake | 4 + Modules/Platform/Linux-PGI.cmake | 2 + Modules/Platform/NetBSD.cmake | 1 + Modules/Platform/SINIX.cmake | 2 + Modules/Platform/UNIX_SV.cmake | 2 + Modules/Platform/UnixWare.cmake | 2 + Modules/Platform/Windows-GNU.cmake | 2 + Source/cmGeneratorExpressionDAGChecker.cxx | 12 ++ Source/cmGeneratorExpressionDAGChecker.h | 1 + Source/cmGeneratorExpressionNode.cxx | 3 +- Source/cmGeneratorTarget.cxx | 171 ++++++++++++++++++--- Source/cmGeneratorTarget.h | 5 + Source/cmGlobalXCodeGenerator.cxx | 23 +++ Source/cmGlobalXCodeGenerator.h | 3 + Source/cmLocalGenerator.cxx | 32 ++++ Source/cmLocalGenerator.h | 4 + Source/cmMakefileTargetGenerator.cxx | 3 + Source/cmPolicies.h | 7 +- Tests/RunCMake/CMakeLists.txt | 3 +- .../CMP0083-cmp0083_new-check.cmake | 22 +++ .../CMP0083-cmp0083_old-check.cmake | 20 +++ .../RunCMake/PositionIndependentCode/CMP0083.cmake | 45 ++++++ .../CheckPIESupported.cmake | 12 ++ .../Genex1-result.txt} | 0 .../PositionIndependentCode/Genex1-stderr.txt | 3 + .../RunCMake/PositionIndependentCode/Genex1.cmake | 9 ++ .../Genex2-result.txt} | 0 .../PositionIndependentCode/Genex2-stderr.txt | 3 + .../RunCMake/PositionIndependentCode/Genex2.cmake | 9 ++ .../PIE-pie_off-check.cmake | 7 + .../PositionIndependentCode/PIE-pie_on-check.cmake | 7 + Tests/RunCMake/PositionIndependentCode/PIE.cmake | 19 +++ .../PositionIndependentCode/PIE_validator.cmake | 32 ++++ .../PositionIndependentCode/RunCMakeTest.cmake | 64 ++++++++ .../RunCMake/TargetPolicies/PolicyList-stderr.txt | 1 + 54 files changed, 766 insertions(+), 30 deletions(-) create mode 100644 Help/policy/CMP0083.rst create mode 100644 Help/release/dev/INTERFACE_POSITION_INDEPENDENT_CODE.rst create mode 100644 Help/release/dev/link-option-PIE.rst create mode 100644 Modules/Internal/CMakeCheckCompilerFlag.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_new-check.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/CMP0083-cmp0083_old-check.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/CMP0083.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake copy Tests/RunCMake/{while/MissingArgument-result.txt => PositionIndependentCode/Genex1-result.txt} (100%) create mode 100644 Tests/RunCMake/PositionIndependentCode/Genex1-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Genex1.cmake copy Tests/RunCMake/{while/MissingArgument-result.txt => PositionIndependentCode/Genex2-result.txt} (100%) create mode 100644 Tests/RunCMake/PositionIndependentCode/Genex2-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Genex2.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/PIE-pie_off-check.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/PIE-pie_on-check.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/PIE.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/PIE_validator.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 16:33:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 16:33:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-405-gf370254 Message-ID: <20181112213304.6E366127A8F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via f3702546521cbc09f1180365e9389a0eef87831b (commit) via 48849544135924f13f1dea5b05afe17889b91b04 (commit) via 45fb82483cdcdfe154ad0be63ff5729a68eb9439 (commit) via db984477e466761311b5e102e90793b3de27f9b5 (commit) via 72d54f1c532035fd0040a38d24712777400a0aa1 (commit) via e286627334b08b524d228beccd818ebc4a10f799 (commit) via 36e9d2d12427fea463650aee4cf6fb16d3be324d (commit) via 1c94129e98dfc9a56a3bb69e22f2b31cd1b9083e (commit) via ff800a768c5e5bebdde05326644bfcb5f7fd0452 (commit) via b93b3b55003d4f7467569320061ae8a2b536ae97 (commit) from ddb967cca1a37501dcf3fbd6f64c2d3be1c0c82b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f3702546521cbc09f1180365e9389a0eef87831b commit f3702546521cbc09f1180365e9389a0eef87831b Merge: 4884954 36e9d2d Author: Brad King AuthorDate: Mon Nov 12 21:31:47 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:31:53 2018 -0500 Merge topic 'DocumentationVTK' 36e9d2d124 Help: remove reference to inexistent file DocumentationVTK.cmake. Acked-by: Kitware Robot Merge-request: !2597 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48849544135924f13f1dea5b05afe17889b91b04 commit 48849544135924f13f1dea5b05afe17889b91b04 Merge: 45fb824 b93b3b5 Author: Brad King AuthorDate: Mon Nov 12 21:28:31 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:31:03 2018 -0500 Merge topic 'CMakeAddFortranSubdirectory' b93b3b5500 Help: better summary and xrefs for CMakeAddFortranSubdirectory Acked-by: Kitware Robot Merge-request: !2592 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=45fb82483cdcdfe154ad0be63ff5729a68eb9439 commit 45fb82483cdcdfe154ad0be63ff5729a68eb9439 Merge: db98447 1c94129 Author: Brad King AuthorDate: Mon Nov 12 21:27:52 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:29:56 2018 -0500 Merge topic 'CMakePrintHelpers' 1c94129e98 Help: correct macro -> function in CMakePrintHelpers Acked-by: Kitware Robot Merge-request: !2596 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=db984477e466761311b5e102e90793b3de27f9b5 commit db984477e466761311b5e102e90793b3de27f9b5 Merge: 72d54f1 ff800a7 Author: Brad King AuthorDate: Mon Nov 12 21:26:58 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:28:30 2018 -0500 Merge topic 'deprecate-ParseArguments' ff800a768c Help: move CMakeParseArguments to deprecated section Acked-by: Kitware Robot Merge-request: !2595 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=72d54f1c532035fd0040a38d24712777400a0aa1 commit 72d54f1c532035fd0040a38d24712777400a0aa1 Merge: ddb967c e286627 Author: Brad King AuthorDate: Mon Nov 12 21:26:06 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:26:11 2018 -0500 Merge topic 'CPack-sections' e286627334 Help: Insert section headers in CPack module Acked-by: Kitware Robot Merge-request: !2593 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e286627334b08b524d228beccd818ebc4a10f799 commit e286627334b08b524d228beccd818ebc4a10f799 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 11 23:02:55 2018 +0100 Commit: Brad King CommitDate: Mon Nov 12 09:18:02 2018 -0500 Help: Insert section headers in CPack module The one extant section header was confusing at least: Not all the doc page is on Variables. diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index f3e3423..ebce851 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -7,8 +7,8 @@ CPack Build binary and source package installers. -Variables common to all CPack generators -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Introduction +^^^^^^^^^^^^ The CPack module generates binary and source installers in a variety of formats using the cpack program. Inclusion of the CPack module adds @@ -23,6 +23,9 @@ installers on macOS and Windows), CPack generates installers that allow users to select individual application components to install. See :module:`CPackComponent` module for further details. +CPack generators +^^^^^^^^^^^^^^^^ + The :variable:`CPACK_GENERATOR` variable has different meanings in different contexts. In a ``CMakeLists.txt`` file, :variable:`CPACK_GENERATOR` is a *list of generators*: and when :manual:`cpack ` is run with no other @@ -57,6 +60,9 @@ This is the key: For each generator listed in :variable:`CPACK_GENERATOR` in internally to *the one currently being used* and then include the :variable:`CPACK_PROJECT_CONFIG_FILE`. +Variables common to all CPack generators +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Before including this CPack module in your ``CMakeLists.txt`` file, there are a variety of variables that can be set to customize the resulting installers. The most commonly-used variables are: https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=36e9d2d12427fea463650aee4cf6fb16d3be324d commit 36e9d2d12427fea463650aee4cf6fb16d3be324d Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 14:27:41 2018 +0100 Commit: Joachim Wuttke (l) CommitDate: Mon Nov 12 14:27:41 2018 +0100 Help: remove reference to inexistent file DocumentationVTK.cmake. diff --git a/Modules/Documentation.cmake b/Modules/Documentation.cmake index 229b8ab..aaf24f6 100644 --- a/Modules/Documentation.cmake +++ b/Modules/Documentation.cmake @@ -5,9 +5,7 @@ Documentation ------------- -DocumentationVTK.cmake - -This file provides support for the VTK documentation framework. It +This module provides support for the VTK documentation framework. It relies on several tools (Doxygen, Perl, etc). #]=======================================================================] https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1c94129e98dfc9a56a3bb69e22f2b31cd1b9083e commit 1c94129e98dfc9a56a3bb69e22f2b31cd1b9083e Author: Joachim Wuttke (h) AuthorDate: Sun Nov 11 23:18:37 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Sun Nov 11 23:18:37 2018 +0100 Help: correct macro -> function in CMakePrintHelpers and apply lower case throughout diff --git a/Modules/CMakePrintHelpers.cmake b/Modules/CMakePrintHelpers.cmake index d5bbb4f..1af0bb7 100644 --- a/Modules/CMakePrintHelpers.cmake +++ b/Modules/CMakePrintHelpers.cmake @@ -5,32 +5,33 @@ CMakePrintHelpers ----------------- -Convenience macros for printing properties and variables, useful e.g. for debugging. +Convenience functions for printing properties and variables, useful +e.g. for debugging. :: - CMAKE_PRINT_PROPERTIES([TARGETS target1 .. targetN] + cmake_print_properties([TARGETS target1 .. targetN] [SOURCES source1 .. sourceN] [DIRECTORIES dir1 .. dirN] [TESTS test1 .. testN] [CACHE_ENTRIES entry1 .. entryN] PROPERTIES prop1 .. propN ) -This macro prints the values of the properties of the given targets, +This function prints the values of the properties of the given targets, source files, directories, tests or cache entries. Exactly one of the scope keywords must be used. Example:: - cmake_print_properties(TARGETS foo bar PROPERTIES - LOCATION INTERFACE_INCLUDE_DIRS) + cmake_print_properties(TARGETS foo bar PROPERTIES + LOCATION INTERFACE_INCLUDE_DIRS) This will print the LOCATION and INTERFACE_INCLUDE_DIRS properties for both targets foo and bar. +:: + cmake_print_variables(var1 var2 .. varN) -CMAKE_PRINT_VARIABLES(var1 var2 .. varN) - -This macro will print the name of each variable followed by its value. +This function will print the name of each variable followed by its value. Example:: cmake_print_variables(CMAKE_C_COMPILER CMAKE_MAJOR_VERSION DOES_NOT_EXIST) @@ -40,7 +41,7 @@ Gives:: -- CMAKE_C_COMPILER="/usr/bin/gcc" ; CMAKE_MAJOR_VERSION="2" ; DOES_NOT_EXIST="" #]=======================================================================] -function(CMAKE_PRINT_VARIABLES) +function(cmake_print_variables) set(msg "") foreach(var ${ARGN}) if(msg) @@ -52,7 +53,7 @@ function(CMAKE_PRINT_VARIABLES) endfunction() -function(CMAKE_PRINT_PROPERTIES ) +function(cmake_print_properties) set(options ) set(oneValueArgs ) set(multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES ) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ff800a768c5e5bebdde05326644bfcb5f7fd0452 commit ff800a768c5e5bebdde05326644bfcb5f7fd0452 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 11 23:14:37 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Sun Nov 11 23:14:37 2018 +0100 Help: move CMakeParseArguments to deprecated section diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 95744df..266c7a1 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -48,7 +48,6 @@ These modules are loaded using the :command:`include` command. /module/CMakeFindPackageMode /module/CMakeGraphVizOptions /module/CMakePackageConfigHelpers - /module/CMakeParseArguments /module/CMakePrintHelpers /module/CMakePrintSystemInformation /module/CMakePushCheckState @@ -270,6 +269,7 @@ Deprecated Utility Modules /module/CMakeDetermineVSServicePack /module/CMakeExpandImportedTargets /module/CMakeForceCompiler + /module/CMakeParseArguments /module/TestCXXAcceptsFlag /module/Use_wxWindows /module/WriteBasicConfigVersionFile https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b93b3b55003d4f7467569320061ae8a2b536ae97 commit b93b3b55003d4f7467569320061ae8a2b536ae97 Author: Joachim Wuttke (h) AuthorDate: Sun Nov 11 22:57:13 2018 +0100 Commit: Joachim Wuttke (h) CommitDate: Sun Nov 11 22:57:13 2018 +0100 Help: better summary and xrefs for CMakeAddFortranSubdirectory diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 2bb3128..50b2807 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -5,18 +5,18 @@ CMakeAddFortranSubdirectory --------------------------- -Use MinGW gfortran from VS if a fortran compiler is not found. +Add a fortran-only subdirectory, find a fortran compiler, and build. -The 'add_fortran_subdirectory' function adds a subdirectory to a -project that contains a fortran only sub-project. The module will +The ``cmake_add_fortran_subdirectory`` function adds a subdirectory +to a project that contains a fortran-only subproject. The module will check the current compiler and see if it can support fortran. If no fortran compiler is found and the compiler is MSVC, then this module will find the MinGW gfortran. It will then use an external project to build with the MinGW tools. It will also create imported targets for the libraries created. This will only work if the fortran code is -built into a dll, so BUILD_SHARED_LIBS is turned on in the project. -In addition the CMAKE_GNUtoMS option is set to on, so that the MS .lib -files are created. Usage is as follows: +built into a dll, so :variable:`BUILD_SHARED_LIBS` is turned on in +the project. In addition the :variable:`CMAKE_GNUtoMS` option is set +to on, so that Microsoft .lib files are created. Usage is as follows: :: ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-modules.7.rst | 2 +- Modules/CMakeAddFortranSubdirectory.cmake | 12 ++++++------ Modules/CMakePrintHelpers.cmake | 21 +++++++++++---------- Modules/CPack.cmake | 10 ++++++++-- Modules/Documentation.cmake | 4 +--- 5 files changed, 27 insertions(+), 22 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 12 16:43:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 12 Nov 2018 16:43:03 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-411-g518b0cf Message-ID: <20181112214303.44BC1127550@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 518b0cf3b63956b577c984a3c8735d2d75d174d3 (commit) via 68c86a20cea84f3de7721415a6cde8653e0994fd (commit) via a39d6f6bc3ac8a99969c8627cc9ce18a095366aa (commit) via 96c31fad71cab6bd45c094bbde7c4fded5805eef (commit) via f05d7ed5ffb00b4d146172e2fd29a988a534d99e (commit) via 89b5f4fcc7b8d3942fd92409ac57ddc3e7328560 (commit) from f3702546521cbc09f1180365e9389a0eef87831b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=518b0cf3b63956b577c984a3c8735d2d75d174d3 commit 518b0cf3b63956b577c984a3c8735d2d75d174d3 Merge: 68c86a2 96c31fa Author: Brad King AuthorDate: Mon Nov 12 21:33:53 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:36:01 2018 -0500 Merge topic 'BundleUtilities' 96c31fad71 Help: Downcase functions in BundleUtilities Acked-by: Kitware Robot Merge-request: !2599 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=68c86a20cea84f3de7721415a6cde8653e0994fd commit 68c86a20cea84f3de7721415a6cde8653e0994fd Merge: a39d6f6 89b5f4f Author: Brad King AuthorDate: Mon Nov 12 21:33:09 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:34:24 2018 -0500 Merge topic 'FindPackageMessage' 89b5f4fcc7 Help: Correct macro -> function in FindPackageMessage. Acked-by: Kitware Robot Merge-request: !2598 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a39d6f6bc3ac8a99969c8627cc9ce18a095366aa commit a39d6f6bc3ac8a99969c8627cc9ce18a095366aa Merge: f370254 f05d7ed Author: Brad King AuthorDate: Mon Nov 12 21:32:29 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 12 16:33:10 2018 -0500 Merge topic 'CheckPrototypeDefinition' f05d7ed5ff Help: correct macro -> function in CheckPrototypeDefinition Acked-by: Kitware Robot Merge-request: !2591 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=96c31fad71cab6bd45c094bbde7c4fded5805eef commit 96c31fad71cab6bd45c094bbde7c4fded5805eef Author: Joachim Wuttke (o) AuthorDate: Mon Nov 12 15:49:31 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Mon Nov 12 15:49:31 2018 +0100 Help: Downcase functions in BundleUtilities Presumably, capitalization was left over from very old times diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index 4a3f476..10e5510 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -41,7 +41,7 @@ Instead, invoke them from an :command:`install(CODE)` or .. code-block:: cmake - FIXUP_BUNDLE( ) + fixup_bundle( ) Fix up a bundle in-place and make it standalone, such that it can be drag-n-drop copied to another machine and run on that machine as long @@ -64,14 +64,14 @@ which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe") .. code-block:: cmake - COPY_AND_FIXUP_BUNDLE( ) + copy_and_fixup_bundle( ) Makes a copy of the bundle at location and then fixes up the new copied bundle in-place at ... .. code-block:: cmake - VERIFY_APP() + verify_app() Verifies that an application appears valid based on running analysis tools on it. Calls "message(FATAL_ERROR" if the application @@ -82,14 +82,14 @@ which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe") .. code-block:: cmake - GET_BUNDLE_MAIN_EXECUTABLE( ) + get_bundle_main_executable( ) The result will be the full path name of the bundle's main executable file or an "error:" prefixed string if it could not be determined. .. code-block:: cmake - GET_DOTAPP_DIR( ) + get_dotapp_dir( ) Returns the nearest parent dir whose name ends with ".app" given the full path to an executable. If there is no such parent dir, then @@ -99,7 +99,7 @@ The returned directory may or may not exist. .. code-block:: cmake - GET_BUNDLE_AND_EXECUTABLE( ) + get_bundle_and_executable( ) Takes either a ".app" directory name or the name of an executable nested inside a ".app" directory and returns the path to the ".app" @@ -108,14 +108,14 @@ directory in and the path to its main executable in .. code-block:: cmake - GET_BUNDLE_ALL_EXECUTABLES( ) + get_bundle_all_executables( ) Scans the given bundle recursively for all executable files and accumulates them into a variable. .. code-block:: cmake - GET_ITEM_KEY( ) + get_item_key( ) Given a file (item) name, generate a key that should be unique considering the set of libraries that need copying or fixing up to @@ -127,7 +127,7 @@ associate a set of variables with a given item based on its key. .. code-block:: cmake - CLEAR_BUNDLE_KEYS() + clear_bundle_keys() Loop over the list of keys, clearing all the variables associated with each key. After the loop, clear the list of keys itself. @@ -137,7 +137,7 @@ list of keys. .. code-block:: cmake - SET_BUNDLE_KEY_VALUES( + set_bundle_key_values( []) Add a key to the list (if necessary) for the given item. If added, @@ -145,7 +145,7 @@ also set all the variables associated with that key. .. code-block:: cmake - GET_BUNDLE_KEYS( ) + get_bundle_keys( ) Loop over all the executable and library files within the bundle (and given as extra ) and accumulate a list of keys representing @@ -158,7 +158,7 @@ which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe") .. code-block:: cmake - COPY_RESOLVED_ITEM_INTO_BUNDLE( ) + copy_resolved_item_into_bundle( ) Copy a resolved item into the bundle if necessary. Copy is not necessary if the resolved_item is "the same as" the @@ -166,7 +166,7 @@ resolved_embedded_item. .. code-block:: cmake - COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE( ) + copy_resolved_framework_into_bundle( ) Copy a resolved framework into the bundle if necessary. Copy is not necessary if the resolved_item is "the same as" the @@ -180,7 +180,7 @@ dylib itself plus the framework Resources directory. .. code-block:: cmake - FIXUP_BUNDLE_ITEM( ) + fixup_bundle_item( ) Get the direct/non-system prerequisites of the resolved embedded item. For each prerequisite, change the way it is referenced to the value of @@ -206,7 +206,7 @@ marked writable before install_name_tool tries to change them. .. code-block:: cmake - VERIFY_BUNDLE_PREREQUISITES( ) + verify_bundle_prerequisites( ) Verifies that the sum of all prerequisites of all files inside the bundle are contained within the bundle or are "system" libraries, @@ -217,7 +217,7 @@ which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe") .. code-block:: cmake - VERIFY_BUNDLE_SYMLINKS( ) + verify_bundle_symlinks( ) Verifies that any symlinks found in the bundle point to other files that are already also in the bundle... Anything that points to an https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f05d7ed5ffb00b4d146172e2fd29a988a534d99e commit f05d7ed5ffb00b4d146172e2fd29a988a534d99e Author: Joachim Wuttke (o) AuthorDate: Mon Nov 12 15:41:09 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Mon Nov 12 15:41:09 2018 +0100 Help: correct macro -> function in CheckPrototypeDefinition Correct in text, and downcase function name in function statement. diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake index b379ec4..c90b766 100644 --- a/Modules/CheckPrototypeDefinition.cmake +++ b/Modules/CheckPrototypeDefinition.cmake @@ -28,7 +28,7 @@ Example: "unistd.h;pwd.h" SOLARIS_GETPWENT_R) -The following variables may be set before calling this macro to modify +The following variables may be set before calling this function to modify the way the check is run: :: @@ -46,7 +46,7 @@ get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) include_guard(GLOBAL) -function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE) +function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE) if (NOT DEFINED ${_VARIABLE}) set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=89b5f4fcc7b8d3942fd92409ac57ddc3e7328560 commit 89b5f4fcc7b8d3942fd92409ac57ddc3e7328560 Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 14:35:44 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Mon Nov 12 15:34:41 2018 +0100 Help: Correct macro -> function in FindPackageMessage. Correct in the text, and change capitalization accordingly. diff --git a/Modules/FindPackageMessage.cmake b/Modules/FindPackageMessage.cmake index 1cdfde8..0628b98 100644 --- a/Modules/FindPackageMessage.cmake +++ b/Modules/FindPackageMessage.cmake @@ -5,14 +5,14 @@ FindPackageMessage ------------------ +.. code-block:: cmake + find_package_message( "message for user" "find result details") -FIND_PACKAGE_MESSAGE( "message for user" "find result details") - -This macro is intended to be used in FindXXX.cmake modules files. It -will print a message once for each unique find result. This is useful -for telling the user where a package was found. The first argument -specifies the name (XXX) of the package. The second argument +This function is intended to be used in FindXXX.cmake modules files. +It will print a message once for each unique find result. This is +useful for telling the user where a package was found. The first +argument specifies the name (XXX) of the package. The second argument specifies the message to display. The third argument lists details about the find result so that if they change the message will be displayed again. The macro also obeys the QUIET argument to the @@ -20,17 +20,17 @@ find_package command. Example: -:: +.. code-block:: cmake if(X11_FOUND) - FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" + find_package_message(X11 "Found X11: ${X11_X11_LIB}" "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") else() ... endif() #]=======================================================================] -function(FIND_PACKAGE_MESSAGE pkg msg details) +function(find_package_message pkg msg details) # Avoid printing a message repeatedly for the same find result. if(NOT ${pkg}_FIND_QUIETLY) string(REPLACE "\n" "" details "${details}") ----------------------------------------------------------------------- Summary of changes: Modules/BundleUtilities.cmake | 32 ++++++++++++++++---------------- Modules/CheckPrototypeDefinition.cmake | 4 ++-- Modules/FindPackageMessage.cmake | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 00:03:07 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 00:03:07 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-412-g5e12fad Message-ID: <20181113050307.1ED9F12797C@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 5e12fad8704e4797ecda3906f3b558775b70539f (commit) from 518b0cf3b63956b577c984a3c8735d2d75d174d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5e12fad8704e4797ecda3906f3b558775b70539f commit 5e12fad8704e4797ecda3906f3b558775b70539f Author: Kitware Robot AuthorDate: Tue Nov 13 00:01:07 2018 -0500 Commit: Kitware Robot CommitDate: Tue Nov 13 00:01:07 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0d78906..19e2da7 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 13) -set(CMake_VERSION_PATCH 20181112) +set(CMake_VERSION_PATCH 20181113) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 10:33:41 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 10:33:41 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-416-gd3b932f Message-ID: <20181113153341.EC9F9127AB1@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via d3b932fa678516d3f5bb7f7209547a876a182d02 (commit) via 71e77972c18e1ab905b36782d7b2c2f838957e26 (commit) via ffdec37a197499929e2cbc4fa825f5bf9b7d0f26 (commit) via 1222f02e343e804f1fcc8ff09e56dc13ac233d98 (commit) from 5e12fad8704e4797ecda3906f3b558775b70539f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d3b932fa678516d3f5bb7f7209547a876a182d02 commit d3b932fa678516d3f5bb7f7209547a876a182d02 Merge: 71e7797 ffdec37 Author: Brad King AuthorDate: Tue Nov 13 15:31:19 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:32:05 2018 -0500 Merge topic 'colored-ctest-summary' ffdec37a19 CTest: Add colored output on tests summary where supported Acked-by: Kitware Robot Merge-request: !2577 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=71e77972c18e1ab905b36782d7b2c2f838957e26 commit 71e77972c18e1ab905b36782d7b2c2f838957e26 Merge: 5e12fad 1222f02 Author: Brad King AuthorDate: Tue Nov 13 15:29:21 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:29:36 2018 -0500 Merge topic 'if_support_checking_if_cache_var_defined' 1222f02e34 If: Support the 'DEFINED CACHE{}' syntax Acked-by: Kitware Robot Merge-request: !2561 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ffdec37a197499929e2cbc4fa825f5bf9b7d0f26 commit ffdec37a197499929e2cbc4fa825f5bf9b7d0f26 Author: Sylvain Joubert AuthorDate: Wed Nov 7 16:33:28 2018 +0100 Commit: Sylvain Joubert CommitDate: Fri Nov 9 18:57:41 2018 +0100 CTest: Add colored output on tests summary where supported - Number of passed/failed tests is colored according to the whole outcome - Individual listed tested are colored according to their completion status: * Disabled: blue * Failed: red * Not Run: yellow diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index c936910..1d938e6 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -535,11 +535,21 @@ int cmCTestTestHandler::ProcessHandler() percent = 99; } + std::string passColorCode; + std::string failedColorCode; + if (failed.empty()) { + passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN); + } else { + failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED); + } cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl - << static_cast(percent + .5f) << "% tests passed, " - << failed.size() << " tests failed out of " << total - << std::endl); + << passColorCode << static_cast(percent + .5f) + << "% tests passed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << ", " << failedColorCode << failed.size() << " tests failed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << " out of " << total << std::endl); if ((!this->CTest->GetLabelsForSubprojects().empty() && this->CTest->GetSubprojectSummary())) { this->PrintLabelOrSubprojectSummary(true); @@ -562,6 +572,8 @@ int cmCTestTestHandler::ProcessHandler() this->StartLogFile("TestsDisabled", ofs); const char* disabled_reason; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::BLUE)); for (cmCTestTestResult const& dt : disabledTests) { ofs << dt.TestCount << ":" << dt.Name << std::endl; if (dt.CompletionStatus == "Disabled") { @@ -573,6 +585,8 @@ int cmCTestTestHandler::ProcessHandler() "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name << " (" << disabled_reason << ")" << std::endl); } + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)); } if (!failed.empty()) { @@ -587,10 +601,17 @@ int cmCTestTestHandler::ProcessHandler() !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") && ft.CompletionStatus != "Disabled") { ofs << ft.TestCount << ":" << ft.Name << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - "\t" << std::setw(3) << ft.TestCount << " - " << ft.Name - << " (" << this->GetTestStatus(ft) << ")" - << std::endl); + auto testColor = cmCTest::Color::RED; + if (this->GetTestStatus(ft) == "Not Run") { + testColor = cmCTest::Color::YELLOW; + } + cmCTestLog( + this->CTest, HANDLER_OUTPUT, + "\t" << this->CTest->GetColorCode(testColor) << std::setw(3) + << ft.TestCount << " - " << ft.Name << " (" + << this->GetTestStatus(ft) << ")" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << std::endl); } } } @@ -1725,7 +1746,7 @@ void cmCTestTestHandler::UseExcludeRegExp() this->UseExcludeRegExpFirst = !this->UseIncludeRegExpFlag; } -const char* cmCTestTestHandler::GetTestStatus(cmCTestTestResult const& result) +std::string cmCTestTestHandler::GetTestStatus(cmCTestTestResult const& result) { static const char* statuses[] = { "Not Run", "Timeout", "SEGFAULT", "ILLEGAL", "INTERRUPT", "NUMERICAL", @@ -1737,7 +1758,7 @@ const char* cmCTestTestHandler::GetTestStatus(cmCTestTestResult const& result) return "No Status"; } if (status == cmCTestTestHandler::OTHER_FAULT) { - return result.ExceptionStatus.c_str(); + return result.ExceptionStatus; } return statuses[status]; } diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index d2694a1..bcacf23 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -274,7 +274,7 @@ private: */ std::string FindTheExecutable(const char* exe); - const char* GetTestStatus(cmCTestTestResult const&); + std::string GetTestStatus(cmCTestTestResult const&); void ExpandTestsToRunInformation(size_t numPossibleTests); void ExpandTestsToRunInformationForRerunFailed(); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 9a046db..c2b6575 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -296,6 +296,7 @@ cmCTest::cmCTest() this->DropSiteCDash = false; this->BuildID = ""; this->OutputTestOutputOnTestFailure = false; + this->OutputColorCode = this->ColoredOutputSupportedByConsole(); this->RepeatTests = 1; // default to run each test once this->RepeatUntilFail = false; @@ -2075,7 +2076,18 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, return true; } -bool cmCTest::ProgressOutputSupportedByConsole() const +#if !defined(_WIN32) +bool cmCTest::ConsoleIsNotDumb() +{ + std::string term_env_variable; + if (cmSystemTools::GetEnv("TERM", term_env_variable)) { + return isatty(1) && term_env_variable != "dumb"; + } + return false; +} +#endif + +bool cmCTest::ProgressOutputSupportedByConsole() { #if defined(_WIN32) // On Windows we need a console buffer. @@ -2084,12 +2096,19 @@ bool cmCTest::ProgressOutputSupportedByConsole() const return GetConsoleScreenBufferInfo(console, &csbi); #else // On UNIX we need a non-dumb tty. - std::string term_env_variable; - if (cmSystemTools::GetEnv("TERM", term_env_variable)) { - return isatty(1) && term_env_variable != "dumb"; - } + return ConsoleIsNotDumb(); #endif +} + +bool cmCTest::ColoredOutputSupportedByConsole() +{ +#if defined(_WIN32) + // Not supported on Windows return false; +#else + // On UNIX we need a non-dumb tty. + return ConsoleIsNotDumb(); +#endif } // handle the -S -SR and -SP arguments @@ -2958,6 +2977,20 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, } } +std::string cmCTest::GetColorCode(Color color) const +{ + if (this->OutputColorCode) { +#if defined(_WIN32) + // Not supported on Windows + static_cast(color); +#else + return "\033[0;" + std::to_string(static_cast(color)) + "m"; +#endif + } + + return ""; +} + cmDuration cmCTest::GetRemainingTimeAllowed() { if (!this->GetHandler("script")) { diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 1ee002a..427049d 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -405,6 +405,19 @@ public: void Log(int logType, const char* file, int line, const char* msg, bool suppress = false); + /** Color values */ + enum class Color + { + CLEAR_COLOR = 0, + RED = 31, + GREEN = 32, + YELLOW = 33, + BLUE = 34 + }; + + /** Get color code characters for a specific color */ + std::string GetColorCode(Color color) const; + /** Get the version of dart server */ int GetDartVersion() { return this->DartVersion; } int GetDropSiteCDash() { return this->DropSiteCDash; } @@ -575,8 +588,16 @@ private: bool HandleCommandLineArguments(size_t& i, std::vector& args, std::string& errormsg); +#if !defined(_WIN32) /** returns true iff the console supports progress output */ - bool ProgressOutputSupportedByConsole() const; + static bool ConsoleIsNotDumb(); +#endif + + /** returns true iff the console supports progress output */ + static bool ProgressOutputSupportedByConsole(); + + /** returns true iff the console supports colored output */ + static bool ColoredOutputSupportedByConsole(); /** handle the -S -SP and -SR arguments */ void HandleScriptArguments(size_t& i, std::vector& args, @@ -625,6 +646,7 @@ private: int OutputLogFileLastTag; bool OutputTestOutputOnTestFailure; + bool OutputColorCode; std::map Definitions; }; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1222f02e343e804f1fcc8ff09e56dc13ac233d98 commit 1222f02e343e804f1fcc8ff09e56dc13ac233d98 Author: Robert Maynard AuthorDate: Fri Nov 2 17:27:09 2018 -0400 Commit: Robert Maynard CommitDate: Fri Nov 9 10:38:07 2018 -0500 If: Support the 'DEFINED CACHE{}' syntax diff --git a/Help/command/if.rst b/Help/command/if.rst index 1cd9965..a682c83 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -187,11 +187,10 @@ Possible conditions are: ``if( IN_LIST )`` True if the given element is contained in the named list variable. -``if(DEFINED |ENV{})`` - True if a variable or environment variable - with given ```` is defined. - The value of the variable does not matter. - Note that macro arguments are not variables. +``if(DEFINED |CACHE{}|ENV{})`` + True if a variable, cache variable or environment variable + with given ```` is defined. The value of the variable + does not matter. Note that macro arguments are not variables. ``if((condition) AND (condition OR (condition)))`` The conditions inside the parenthesis are evaluated first and then diff --git a/Help/release/dev/if-supports-cache-defined.rst b/Help/release/dev/if-supports-cache-defined.rst new file mode 100644 index 0000000..1e700c0 --- /dev/null +++ b/Help/release/dev/if-supports-cache-defined.rst @@ -0,0 +1,5 @@ +if-supports-cache-defined +------------------------- + +* The :command:`if` command gained support for checking if cache variables + are defined with the ``DEFINED CACHE{VAR}`` syntax. diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 172ef92..3b4206f 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -495,6 +495,12 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&, argP1->GetValue().operator[](argP1len - 1) == '}') { std::string env = argP1->GetValue().substr(4, argP1len - 5); bdef = cmSystemTools::HasEnv(env); + } else if (argP1len > 6 && + argP1->GetValue().substr(0, 6) == "CACHE{" && + argP1->GetValue().operator[](argP1len - 1) == '}') { + std::string cache = argP1->GetValue().substr(6, argP1len - 7); + bdef = + this->Makefile.GetState()->GetCacheEntryValue(cache) != nullptr; } else { bdef = this->Makefile.IsDefinitionSet(argP1->GetValue()); } diff --git a/Tests/Unset/CMakeLists.txt b/Tests/Unset/CMakeLists.txt index 07aa68e..a40367b 100644 --- a/Tests/Unset/CMakeLists.txt +++ b/Tests/Unset/CMakeLists.txt @@ -21,17 +21,26 @@ set(x 43) if(NOT x EQUAL 43) message(FATAL_ERROR "x!=43") endif() +if(DEFINED CACHE{x}) + message(FATAL_ERROR "x shouldn't be found in the cache") +endif() + set(x) if(DEFINED x) message(FATAL_ERROR "x should be undefined now!") endif() + # Cache variable set(BAR "test" CACHE STRING "documentation") if(NOT DEFINED BAR) message(FATAL_ERROR "BAR not defined") endif() +if(NOT DEFINED CACHE{BAR}) + message(FATAL_ERROR "BAR could not be found by CACHE{BAR}") +endif() + # Test interaction of cache entries with variables. set(BAR "test-var") if(NOT "$CACHE{BAR}" STREQUAL "test") ----------------------------------------------------------------------- Summary of changes: Help/command/if.rst | 9 +++--- Help/release/dev/if-supports-cache-defined.rst | 5 +++ Source/CTest/cmCTestTestHandler.cxx | 39 +++++++++++++++++------ Source/CTest/cmCTestTestHandler.h | 2 +- Source/cmCTest.cxx | 43 +++++++++++++++++++++++--- Source/cmCTest.h | 24 +++++++++++++- Source/cmConditionEvaluator.cxx | 6 ++++ Tests/Unset/CMakeLists.txt | 9 ++++++ 8 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 Help/release/dev/if-supports-cache-defined.rst hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 10:43:16 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 10:43:16 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-426-g06ef9ed Message-ID: <20181113154323.7C67711D978@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 06ef9edd51a8ffbd77fb96f733cbe45af84e9559 (commit) via bd04db899f51b93581107ef35fc970b4fd54c410 (commit) via 4fd97bbc2cfb91a29fd25d35e12c5784f2637aee (commit) via 9bb203ed0f983305462a9d42ce9c906a292d42c1 (commit) via ad6ef6c1d5ba1434215bf9e891c87f71514446e9 (commit) via 5045cd82d03c7cba5f9bd1a128996de289196b92 (commit) via 247266aa3f1483c55e3169f02f10db59b87027f1 (commit) via 0470ee96b1268d5565905581fc137ea33cd0c906 (commit) via 3a7f02197bb71553d47f24130fda1add30dbcb27 (commit) via 516c6fc38c0bdfd7905edb169a4ebfef689cf116 (commit) from d3b932fa678516d3f5bb7f7209547a876a182d02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=06ef9edd51a8ffbd77fb96f733cbe45af84e9559 commit 06ef9edd51a8ffbd77fb96f733cbe45af84e9559 Merge: bd04db8 3a7f021 Author: Brad King AuthorDate: Tue Nov 13 15:40:52 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:41:20 2018 -0500 Merge topic 'DeployQt4' 3a7f02197b Help: Downcase function names in DeployQt4 doc. Acked-by: Kitware Robot Merge-request: !2600 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd04db899f51b93581107ef35fc970b4fd54c410 commit bd04db899f51b93581107ef35fc970b4fd54c410 Merge: 4fd97bb 0470ee9 Author: Brad King AuthorDate: Tue Nov 13 15:40:31 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:40:38 2018 -0500 Merge topic 'WriteCompilerDetectionHeader' 0470ee96b1 Help: Remove duplication of function name. Acked-by: Kitware Robot Merge-request: !2605 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4fd97bbc2cfb91a29fd25d35e12c5784f2637aee commit 4fd97bbc2cfb91a29fd25d35e12c5784f2637aee Merge: 9bb203e ad6ef6c Author: Brad King AuthorDate: Tue Nov 13 10:39:12 2018 -0500 Commit: Brad King CommitDate: Tue Nov 13 10:39:12 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9bb203ed0f983305462a9d42ce9c906a292d42c1 commit 9bb203ed0f983305462a9d42ce9c906a292d42c1 Merge: 247266a 5045cd8 Author: Brad King AuthorDate: Tue Nov 13 15:38:43 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:38:54 2018 -0500 Merge topic 'FindBoost-1.69' 5045cd82d0 FindBoost: Additional fixes for 1.69 Acked-by: Kitware Robot Merge-request: !2601 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=247266aa3f1483c55e3169f02f10db59b87027f1 commit 247266aa3f1483c55e3169f02f10db59b87027f1 Merge: d3b932f 516c6fc Author: Brad King AuthorDate: Tue Nov 13 15:32:10 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:33:05 2018 -0500 Merge topic 'vs-just-my-code-flag-map' 516c6fc38c VS: Add flag table entry for -JMC Acked-by: Kitware Robot Merge-request: !2587 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0470ee96b1268d5565905581fc137ea33cd0c906 commit 0470ee96b1268d5565905581fc137ea33cd0c906 Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 22:33:11 2018 +0100 Commit: Joachim Wuttke (l) CommitDate: Mon Nov 12 22:33:11 2018 +0100 Help: Remove duplication of function name. diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index a556567..21ccd7c 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -7,9 +7,8 @@ WriteCompilerDetectionHeader This module provides the function write_compiler_detection_header(). -The ``WRITE_COMPILER_DETECTION_HEADER`` function can be used to generate -a file suitable for preprocessor inclusion which contains macros to be -used in source code:: +This function can be used to generate a file suitable for preprocessor +inclusion which contains macros to be used in source code:: write_compiler_detection_header( FILE @@ -25,8 +24,8 @@ used in source code:: [ALLOW_UNKNOWN_COMPILER_VERSIONS] ) -The ``write_compiler_detection_header`` function generates the -file ```` with macros which all have the prefix ````. +This generates the file ```` with macros which all have the prefix +````. By default, all content is written directly to the ````. The ``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3a7f02197bb71553d47f24130fda1add30dbcb27 commit 3a7f02197bb71553d47f24130fda1add30dbcb27 Author: Joachim Wuttke (o) AuthorDate: Mon Nov 12 16:13:57 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Mon Nov 12 19:51:43 2018 +0100 Help: Downcase function names in DeployQt4 doc. diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake index c69cd38..4a18927 100644 --- a/Modules/DeployQt4.cmake +++ b/Modules/DeployQt4.cmake @@ -26,13 +26,13 @@ PARENT_SCOPE. Also depends on BundleUtilities.cmake. :: - WRITE_QT4_CONF( ) + write_qt4_conf( ) Writes a qt.conf file with the into . :: - RESOLVE_QT4_PATHS( []) + resolve_qt4_paths( []) Loop through list and if any don't exist resolve them relative to the (if supplied) or the @@ -40,7 +40,7 @@ CMAKE_INSTALL_PREFIX. :: - FIXUP_QT4_EXECUTABLE( + fixup_qt4_executable( [ ]) Copies Qt plugins, writes a Qt configuration file (if needed) and @@ -67,7 +67,7 @@ needed. :: - INSTALL_QT4_PLUGIN_PATH(plugin executable copy installed_plugin_path_var + install_qt4_plugin_path(plugin executable copy installed_plugin_path_var ) Install (or copy) a resolved to the default plugins directory @@ -82,7 +82,7 @@ If is set then anything installed will use this COMPONENT. :: - INSTALL_QT4_PLUGIN(plugin executable copy installed_plugin_path_var + install_qt4_plugin(plugin executable copy installed_plugin_path_var ) Install (or copy) an unresolved to the default plugins @@ -92,7 +92,7 @@ INSTALL_QT4_PLUGIN_PATH. :: - INSTALL_QT4_EXECUTABLE( + install_qt4_executable( [ ]) Installs Qt plugins, writes a Qt configuration file (if needed) and https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=516c6fc38c0bdfd7905edb169a4ebfef689cf116 commit 516c6fc38c0bdfd7905edb169a4ebfef689cf116 Author: Tengiz Sharafiev AuthorDate: Sat Nov 10 10:59:29 2018 +0800 Commit: Tengiz Sharafiev CommitDate: Sat Nov 10 11:06:37 2018 +0800 VS: Add flag table entry for -JMC Add support for mapping Just My Code compiler flag Fixes: #18289 diff --git a/Source/cmVS141CLFlagTable.h b/Source/cmVS141CLFlagTable.h index 2a9944a..7d219be 100644 --- a/Source/cmVS141CLFlagTable.h +++ b/Source/cmVS141CLFlagTable.h @@ -194,6 +194,8 @@ static cmVS7FlagTable cmVS141CLFlagTable[] = { { "EnablePREfast", "analyze", "", "true", 0 }, { "UseFullPaths", "FC", "", "true", 0 }, { "OmitDefaultLibName", "Zl", "", "true", 0 }, + { "SupportJustMyCode", "JMC-", "", "false", 0 }, + { "SupportJustMyCode", "JMC", "", "true", 0 }, // Bool Properties With Argument { "MultiProcessorCompilation", "MP", "", "true", ----------------------------------------------------------------------- Summary of changes: Modules/DeployQt4.cmake | 12 ++++++------ Modules/FindBoost.cmake | 6 +++--- Modules/WriteCompilerDetectionHeader.cmake | 9 ++++----- Source/cmVS141CLFlagTable.h | 2 ++ Utilities/Scripts/BoostScanDeps.cmake | 4 ++-- 5 files changed, 17 insertions(+), 16 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 10:43:23 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 10:43:23 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-8-gad6ef6c Message-ID: <20181113154340.F174F11D7F1@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via ad6ef6c1d5ba1434215bf9e891c87f71514446e9 (commit) via 5045cd82d03c7cba5f9bd1a128996de289196b92 (commit) from abe1a345b255f69b02219f2b893ce00c8ff2e55b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindBoost.cmake | 6 +++--- Utilities/Scripts/BoostScanDeps.cmake | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 10:53:13 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 10:53:13 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-430-g9fee704 Message-ID: <20181113155329.CAD88127D1A@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 9fee70422783af120bdaeff62ba77a71226f611d (commit) via fb93f7f23022254ca8a6c67a2abb39484176b803 (commit) via fe15a1029cc02ce67f8f050763aca444641510b2 (commit) via 26a70449cce3c29446ebe1562bb2213c2566275b (commit) from 06ef9edd51a8ffbd77fb96f733cbe45af84e9559 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9fee70422783af120bdaeff62ba77a71226f611d commit 9fee70422783af120bdaeff62ba77a71226f611d Merge: fb93f7f fe15a10 Author: Brad King AuthorDate: Tue Nov 13 15:46:33 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:46:54 2018 -0500 Merge topic 'SelectLibraryConfigurations' fe15a1029c Help: Revise documentation of SelectLibraryConfigurations Acked-by: Kitware Robot Merge-request: !2608 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fb93f7f23022254ca8a6c67a2abb39484176b803 commit fb93f7f23022254ca8a6c67a2abb39484176b803 Merge: 06ef9ed 26a7044 Author: Brad King AuthorDate: Tue Nov 13 15:46:00 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 10:46:07 2018 -0500 Merge topic 'env2' 26a70449cc Help: Describe environment variables as such. Acked-by: Kitware Robot Merge-request: !2609 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fe15a1029cc02ce67f8f050763aca444641510b2 commit fe15a1029cc02ce67f8f050763aca444641510b2 Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 23:20:25 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 13 12:12:52 2018 +0100 Help: Revise documentation of SelectLibraryConfigurations List format for chosen variables. New paragraph before description of special cases. diff --git a/Modules/SelectLibraryConfigurations.cmake b/Modules/SelectLibraryConfigurations.cmake index 8cb714d..4c0e9a8 100644 --- a/Modules/SelectLibraryConfigurations.cmake +++ b/Modules/SelectLibraryConfigurations.cmake @@ -5,33 +5,41 @@ SelectLibraryConfigurations --------------------------- +.. code-block:: cmake - -select_library_configurations( basename ) + select_library_configurations(basename) This macro takes a library base name as an argument, and will choose -good values for basename_LIBRARY, basename_LIBRARIES, -basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -has been found and set. If only basename_LIBRARY_RELEASE is defined, -basename_LIBRARY will be set to the release value, and -basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -take the debug value, and basename_LIBRARY_RELEASE will be set to -basename_LIBRARY_RELEASE-NOTFOUND. +good values for the variables + +:: + + basename_LIBRARY + basename_LIBRARIES + basename_LIBRARY_DEBUG + basename_LIBRARY_RELEASE + +depending on what has been found and set. + +If only ``basename_LIBRARY_RELEASE`` is defined, ``basename_LIBRARY`` will +be set to the release value, and ``basename_LIBRARY_DEBUG`` will be set +to ``basename_LIBRARY_DEBUG-NOTFOUND``. If only ``basename_LIBRARY_DEBUG`` +is defined, then ``basename_LIBRARY`` will take the debug value, and +``basename_LIBRARY_RELEASE`` will be set to ``basename_LIBRARY_RELEASE-NOTFOUND``. -If the generator supports configuration types, then basename_LIBRARY -and basename_LIBRARIES will be set with debug and optimized flags +If the generator supports configuration types, then ``basename_LIBRARY`` +and ``basename_LIBRARIES`` will be set with debug and optimized flags specifying the library to be used for the given configuration. If no build type has been set or the generator in use does not support -configuration types, then basename_LIBRARY and basename_LIBRARIES will -take only the release value, or the debug value if the release one is -not set. +configuration types, then ``basename_LIBRARY`` and ``basename_LIBRARIES`` +will take only the release value, or the debug value if the release one +is not set. #]=======================================================================] # This macro was adapted from the FindQt4 CMake module and is maintained by Will # Dicharry . -macro( select_library_configurations basename ) +macro(select_library_configurations basename) if(NOT ${basename}_LIBRARY_RELEASE) set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=26a70449cce3c29446ebe1562bb2213c2566275b commit 26a70449cce3c29446ebe1562bb2213c2566275b Author: Joachim Wuttke (l) AuthorDate: Tue Nov 13 09:19:11 2018 +0100 Commit: Joachim Wuttke (l) CommitDate: Tue Nov 13 09:29:36 2018 +0100 Help: Describe environment variables as such. In each environment variable doc page, insert an opening paragraph (ENV_VAR.txt) to say that this is an environment variable, and provide a link to the cmake-language section on environment variables. diff --git a/Help/envvar/ASM_DIALECT.rst b/Help/envvar/ASM_DIALECT.rst index ec48f71..cabb959 100644 --- a/Help/envvar/ASM_DIALECT.rst +++ b/Help/envvar/ASM_DIALECT.rst @@ -1,6 +1,8 @@ ASM ------------ +.. include:: ENV_VAR.txt + Preferred executable for compiling a specific dialect of assembly language files. ``ASM`` can be ``ASM``, ``ASM_NASM``, ``ASM_MASM`` or ``ASM-ATT``. Will only be used by CMake on the first configuration to determine diff --git a/Help/envvar/ASM_DIALECTFLAGS.rst b/Help/envvar/ASM_DIALECTFLAGS.rst index 4ed02fe..90cbbdb 100644 --- a/Help/envvar/ASM_DIALECTFLAGS.rst +++ b/Help/envvar/ASM_DIALECTFLAGS.rst @@ -1,6 +1,8 @@ ASMFLAGS ----------------- +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling a specific dialect of an assembly language. ``ASMFLAGS`` can be ``ASMFLAGS``, ``ASM_NASMFLAGS``, ``ASM_MASMFLAGS`` or ``ASM-ATTFLAGS``. Will only be used by CMake on the diff --git a/Help/envvar/CC.rst b/Help/envvar/CC.rst index 7e68110..ef12059 100644 --- a/Help/envvar/CC.rst +++ b/Help/envvar/CC.rst @@ -1,6 +1,8 @@ CC -- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``C`` language files. Will only be used by CMake on the first configuration to determine ``C`` compiler, after which the value for ``CC`` is stored in the cache as diff --git a/Help/envvar/CFLAGS.rst b/Help/envvar/CFLAGS.rst index 60b2cd3..fda9ccc 100644 --- a/Help/envvar/CFLAGS.rst +++ b/Help/envvar/CFLAGS.rst @@ -1,6 +1,8 @@ CFLAGS ------ +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling ``C`` files. Will only be used by CMake on the first configuration to determine ``CC`` default compilation flags, after which the value for ``CFLAGS`` is stored in the cache diff --git a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst index 198dc51..199ca3e 100644 --- a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst +++ b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst @@ -1,6 +1,8 @@ CMAKE_BUILD_PARALLEL_LEVEL -------------------------- +.. include:: ENV_VAR.txt + Specifies the maximum number of concurrent processes to use when building using the ``cmake --build`` command line :ref:`Build Tool Mode `. diff --git a/Help/envvar/CMAKE_CONFIG_TYPE.rst b/Help/envvar/CMAKE_CONFIG_TYPE.rst index 1306b47..168593d 100644 --- a/Help/envvar/CMAKE_CONFIG_TYPE.rst +++ b/Help/envvar/CMAKE_CONFIG_TYPE.rst @@ -1,5 +1,7 @@ CMAKE_CONFIG_TYPE ----------------- +.. include:: ENV_VAR.txt + The default build configuration for :ref:`Build Tool Mode` and ``ctest`` build handler when there is no explicit configuration given. diff --git a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst index 54d5f9e..77ead4d 100644 --- a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst +++ b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst @@ -1,6 +1,8 @@ CMAKE_MSVCIDE_RUN_PATH ---------------------- +.. include:: ENV_VAR.txt + Extra PATH locations for custom commands when using :generator:`Visual Studio 9 2008` (or above) generators. diff --git a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst index 5fd6e52..ef7d547 100644 --- a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst +++ b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst @@ -1,6 +1,8 @@ CMAKE_OSX_ARCHITECTURES ----------------------- +.. include:: ENV_VAR.txt + Target specific architectures for macOS. The ``CMAKE_OSX_ARCHITECTURES`` environment variable sets the default value for diff --git a/Help/envvar/CSFLAGS.rst b/Help/envvar/CSFLAGS.rst index 251ddc5..404bb59 100644 --- a/Help/envvar/CSFLAGS.rst +++ b/Help/envvar/CSFLAGS.rst @@ -1,6 +1,8 @@ CSFLAGS ------- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``CSharp`` language files. Will only be used by CMake on the first configuration to determine ``CSharp`` default compilation flags, after which the value for ``CSFLAGS`` is stored in the cache diff --git a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst index 25ed14f..b769d51 100644 --- a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst +++ b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst @@ -1,5 +1,7 @@ CTEST_INTERACTIVE_DEBUG_MODE ---------------------------- +.. include:: ENV_VAR.txt + Environment variable that will exist and be set to ``1`` when a test executed by CTest is run in interactive mode. diff --git a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst index 1fcf42b..bf860cb 100644 --- a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst +++ b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst @@ -1,6 +1,8 @@ CTEST_OUTPUT_ON_FAILURE ----------------------- +.. include:: ENV_VAR.txt + Boolean environment variable that controls if the output should be logged for failed tests. Set the value to 1, True, or ON to enable output on failure. See :manual:`ctest(1)` for more information on controlling output of failed diff --git a/Help/envvar/CTEST_PARALLEL_LEVEL.rst b/Help/envvar/CTEST_PARALLEL_LEVEL.rst index c767a01..fd4936e 100644 --- a/Help/envvar/CTEST_PARALLEL_LEVEL.rst +++ b/Help/envvar/CTEST_PARALLEL_LEVEL.rst @@ -1,5 +1,7 @@ CTEST_PARALLEL_LEVEL -------------------- +.. include:: ENV_VAR.txt + Specify the number of tests for CTest to run in parallel. See :manual:`ctest(1)` for more information on parallel test execution. diff --git a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst index a8e15bc..de23e11 100644 --- a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst +++ b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst @@ -1,6 +1,8 @@ CTEST_PROGRESS_OUTPUT --------------------- +.. include:: ENV_VAR.txt + Boolean environment variable that affects how :manual:`ctest ` command output reports overall progress. When set to 1, TRUE, ON or anything else that evaluates to boolean true, progress is reported by repeatedly diff --git a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst index 8d8eea5..79dbb79 100644 --- a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst +++ b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst @@ -1,4 +1,6 @@ CTEST_USE_LAUNCHERS_DEFAULT --------------------------- +.. include:: ENV_VAR.txt + Initializes the :variable:`CTEST_USE_LAUNCHERS` variable if not already defined. diff --git a/Help/envvar/CUDACXX.rst b/Help/envvar/CUDACXX.rst index 8a5fd4b..10c0f9d 100644 --- a/Help/envvar/CUDACXX.rst +++ b/Help/envvar/CUDACXX.rst @@ -1,6 +1,8 @@ CUDACXX ------- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``CUDA`` language files. Will only be used by CMake on the first configuration to determine ``CUDA`` compiler, after which the value for ``CUDA`` is stored in the cache as diff --git a/Help/envvar/CUDAFLAGS.rst b/Help/envvar/CUDAFLAGS.rst index 3dff49f..4456d6b 100644 --- a/Help/envvar/CUDAFLAGS.rst +++ b/Help/envvar/CUDAFLAGS.rst @@ -1,6 +1,8 @@ CUDAFLAGS --------- +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling ``CUDA`` files. Will only be used by CMake on the first configuration to determine ``CUDA`` default compilation flags, after which the value for ``CUDAFLAGS`` is stored in the diff --git a/Help/envvar/CUDAHOSTCXX.rst b/Help/envvar/CUDAHOSTCXX.rst index bb786ca..b9f65bd 100644 --- a/Help/envvar/CUDAHOSTCXX.rst +++ b/Help/envvar/CUDAHOSTCXX.rst @@ -1,6 +1,8 @@ CUDAHOSTCXX ----------- +.. include:: ENV_VAR.txt + Preferred executable for compiling host code when compiling ``CUDA`` language files. Will only be used by CMake on the first configuration to determine ``CUDA`` host compiler, after which the value for ``CUDAHOSTCXX`` is diff --git a/Help/envvar/CXX.rst b/Help/envvar/CXX.rst index 3b1e445..d655350 100644 --- a/Help/envvar/CXX.rst +++ b/Help/envvar/CXX.rst @@ -1,6 +1,8 @@ CXX --- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``CXX`` language files. Will only be used by CMake on the first configuration to determine ``CXX`` compiler, after which the value for ``CXX`` is stored in the cache as diff --git a/Help/envvar/CXXFLAGS.rst b/Help/envvar/CXXFLAGS.rst index 8b58abd..d7296dc 100644 --- a/Help/envvar/CXXFLAGS.rst +++ b/Help/envvar/CXXFLAGS.rst @@ -1,6 +1,8 @@ CXXFLAGS -------- +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling ``CXX`` (C++) files. Will only be used by CMake on the first configuration to determine ``CXX`` default compilation flags, after which the value for ``CXXFLAGS`` is stored in the cache diff --git a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst index fab1c0c..2b303a4 100644 --- a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst +++ b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst @@ -1,5 +1,7 @@ DASHBOARD_TEST_FROM_CTEST ------------------------- +.. include:: ENV_VAR.txt + Environment variable that will exist when a test executed by CTest is run in non-interactive mode. The value will be equal to :variable:`CMAKE_VERSION`. diff --git a/Help/envvar/DESTDIR.rst b/Help/envvar/DESTDIR.rst index 87f1115..d2144ae 100644 --- a/Help/envvar/DESTDIR.rst +++ b/Help/envvar/DESTDIR.rst @@ -1,6 +1,8 @@ DESTDIR ------- +.. include:: ENV_VAR.txt + On UNIX one can use the ``DESTDIR`` mechanism in order to relocate the whole installation. ``DESTDIR`` means DESTination DIRectory. It is commonly used by makefile users in order to install software at diff --git a/Help/envvar/ENV_VAR.txt b/Help/envvar/ENV_VAR.txt new file mode 100644 index 0000000..e1e70cd --- /dev/null +++ b/Help/envvar/ENV_VAR.txt @@ -0,0 +1,3 @@ +This is a CMake :ref:`Environment Variable `. Its initial value is taken from +the calling process environment. diff --git a/Help/envvar/FC.rst b/Help/envvar/FC.rst index 7d293fd..d6cabbc 100644 --- a/Help/envvar/FC.rst +++ b/Help/envvar/FC.rst @@ -1,6 +1,8 @@ FC -- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``Fortran`` language files. Will only be used by CMake on the first configuration to determine ``Fortran`` compiler, after which the value for ``Fortran`` is stored in the cache as diff --git a/Help/envvar/FFLAGS.rst b/Help/envvar/FFLAGS.rst index 19d6169..02d3c34 100644 --- a/Help/envvar/FFLAGS.rst +++ b/Help/envvar/FFLAGS.rst @@ -1,6 +1,8 @@ FFLAGS ------ +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling ``Fortran`` files. Will only be used by CMake on the first configuration to determine ``Fortran`` default compilation flags, after which the value for ``FFLAGS`` is stored in the cache diff --git a/Help/envvar/LDFLAGS.rst b/Help/envvar/LDFLAGS.rst index 52da99c..816d6ef 100644 --- a/Help/envvar/LDFLAGS.rst +++ b/Help/envvar/LDFLAGS.rst @@ -1,6 +1,8 @@ LDFLAGS ------- +.. include:: ENV_VAR.txt + Will only be used by CMake on the first configuration to determine the default linker flags, after which the value for ``LDFLAGS`` is stored in the cache as :variable:`CMAKE_EXE_LINKER_FLAGS_INIT`, diff --git a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst index 9dafa32..662bd03 100644 --- a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst +++ b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst @@ -1,6 +1,8 @@ MACOSX_DEPLOYMENT_TARGET ------------------------ +.. include:: ENV_VAR.txt + Specify the minimum version of macOS on which the target binaries are to be deployed. diff --git a/Help/envvar/PackageName_ROOT.rst b/Help/envvar/PackageName_ROOT.rst index e01009b..ecec63b 100644 --- a/Help/envvar/PackageName_ROOT.rst +++ b/Help/envvar/PackageName_ROOT.rst @@ -1,6 +1,8 @@ _ROOT ------------------ +.. include:: ENV_VAR.txt + Calls to :command:`find_package()` will search in prefixes specified by the ``_ROOT`` environment variable, where ```` is the name given to the ``find_package`` call diff --git a/Help/envvar/RC.rst b/Help/envvar/RC.rst index 6c2db19..557520e 100644 --- a/Help/envvar/RC.rst +++ b/Help/envvar/RC.rst @@ -1,6 +1,8 @@ RC -- +.. include:: ENV_VAR.txt + Preferred executable for compiling ``resource`` files. Will only be used by CMake on the first configuration to determine ``resource`` compiler, after which the value for ``RC`` is stored in the cache as diff --git a/Help/envvar/RCFLAGS.rst b/Help/envvar/RCFLAGS.rst index 4f2f31c..45419fe 100644 --- a/Help/envvar/RCFLAGS.rst +++ b/Help/envvar/RCFLAGS.rst @@ -1,6 +1,8 @@ RCFLAGS ------- +.. include:: ENV_VAR.txt + Default compilation flags to be used when compiling ``resource`` files. Will only be used by CMake on the first configuration to determine ``resource`` default compilation flags, after which the value for ``RCFLAGS`` is stored in ----------------------------------------------------------------------- Summary of changes: Help/envvar/ASM_DIALECT.rst | 2 ++ Help/envvar/ASM_DIALECTFLAGS.rst | 2 ++ Help/envvar/CC.rst | 2 ++ Help/envvar/CFLAGS.rst | 2 ++ Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst | 2 ++ Help/envvar/CMAKE_CONFIG_TYPE.rst | 2 ++ Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst | 2 ++ Help/envvar/CMAKE_OSX_ARCHITECTURES.rst | 2 ++ Help/envvar/CSFLAGS.rst | 2 ++ Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst | 2 ++ Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst | 2 ++ Help/envvar/CTEST_PARALLEL_LEVEL.rst | 2 ++ Help/envvar/CTEST_PROGRESS_OUTPUT.rst | 2 ++ Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst | 2 ++ Help/envvar/CUDACXX.rst | 2 ++ Help/envvar/CUDAFLAGS.rst | 2 ++ Help/envvar/CUDAHOSTCXX.rst | 2 ++ Help/envvar/CXX.rst | 2 ++ Help/envvar/CXXFLAGS.rst | 2 ++ Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst | 2 ++ Help/envvar/DESTDIR.rst | 2 ++ Help/envvar/ENV_VAR.txt | 3 +++ Help/envvar/FC.rst | 2 ++ Help/envvar/FFLAGS.rst | 2 ++ Help/envvar/LDFLAGS.rst | 2 ++ Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst | 2 ++ Help/envvar/PackageName_ROOT.rst | 2 ++ Help/envvar/RC.rst | 2 ++ Help/envvar/RCFLAGS.rst | 2 ++ Modules/SelectLibraryConfigurations.cmake | 40 +++++++++++++++++----------- 30 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 Help/envvar/ENV_VAR.txt hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 13:43:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 13:43:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-432-g3603b39 Message-ID: <20181113184304.B5FE110308B@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 3603b3964b308273725198cafdc2ce78a80fa862 (commit) via dcf11cbcdcfc15f44e07821ded87252ec31bc40b (commit) from 9fee70422783af120bdaeff62ba77a71226f611d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3603b3964b308273725198cafdc2ce78a80fa862 commit 3603b3964b308273725198cafdc2ce78a80fa862 Merge: 9fee704 dcf11cb Author: Brad King AuthorDate: Tue Nov 13 18:40:48 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 13:40:55 2018 -0500 Merge topic 'macro' dcf11cbcdc Help: Mention endmacro argument as legacy only. Acked-by: Kitware Robot Merge-request: !2606 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dcf11cbcdcfc15f44e07821ded87252ec31bc40b commit dcf11cbcdcfc15f44e07821ded87252ec31bc40b Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 22:36:35 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 13 12:14:55 2018 +0100 Help: Mention endmacro argument as legacy only. Same change as previously done for function, if, while, ... diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 2746b1b..287855b 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -7,7 +7,7 @@ Start recording a macro for later invocation as a command macro( [ ...]) - endmacro() + endmacro() Defines a macro named ```` that takes arguments named ````, ... @@ -31,6 +31,11 @@ behavior. Checking that ``${ARGC}`` is greater than ``#`` is the only way to ensure that ``${ARGV#}`` was passed to the function as an extra argument. +Per legacy, the :command:`endmacro` command admits an optional +```` argument. If used, it must be a verbatim repeat of the +argument of the opening ``macro`` command. + + See the :command:`cmake_policy()` command documentation for the behavior of policies inside macros. ----------------------------------------------------------------------- Summary of changes: Help/command/macro.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 13 14:33:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 13 Nov 2018 14:33:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-437-g64bc4bd Message-ID: <20181113193304.7229E12797F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 64bc4bda748b6c33d496fe294e959e7609b89260 (commit) via dc551c2b0d8d92227a56faad80781349381869f2 (commit) via abb5945bd0b10b14cdc43966145b1a34125393cc (commit) via 357cdee3a133a943828d85d6441dfdee9d347751 (commit) via df780bcc018f65b6b182028df06dcd03ca10a4e7 (commit) from 3603b3964b308273725198cafdc2ce78a80fa862 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=64bc4bda748b6c33d496fe294e959e7609b89260 commit 64bc4bda748b6c33d496fe294e959e7609b89260 Merge: dc551c2 df780bc Author: Brad King AuthorDate: Tue Nov 13 19:25:10 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 14:25:58 2018 -0500 Merge topic 'deprecate-modules2' df780bcc01 Help: Move deprecated modules to appropriate section. Acked-by: Kitware Robot Merge-request: !2603 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dc551c2b0d8d92227a56faad80781349381869f2 commit dc551c2b0d8d92227a56faad80781349381869f2 Merge: 3603b39 abb5945 Author: Brad King AuthorDate: Tue Nov 13 19:25:03 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 13 14:25:10 2018 -0500 Merge topic 'macro+function-invocation' abb5945bd0 Help: Document that function invocation is case-insensitive 357cdee3a1 Help: Document that macro invocation is case-insensitive Acked-by: Kitware Robot Merge-request: !2607 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=abb5945bd0b10b14cdc43966145b1a34125393cc commit abb5945bd0b10b14cdc43966145b1a34125393cc Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 23:07:59 2018 +0100 Commit: Brad King CommitDate: Tue Nov 13 13:47:26 2018 -0500 Help: Document that function invocation is case-insensitive diff --git a/Help/command/function.rst b/Help/command/function.rst index 4a223b4..7b10381 100644 --- a/Help/command/function.rst +++ b/Help/command/function.rst @@ -9,27 +9,9 @@ Start recording a function for later invocation as a command. endfunction() -Defines a function named ```` that takes arguments -named ````, ... -The ```` in the function definition are recorded; -they are not invoked until the function is invoked. When -the function is invoked, the recorded ```` are first -modified by replacing formal parameters (``${arg1}``, ...) -with the arguments passed, and then invoked as normal commands. - -In addition to referencing the formal parameters you can reference the -``ARGC`` variable which will be set to the number of arguments passed -into the function as well as ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which -will have the actual values of the arguments passed in. -This facilitates creating functions with optional arguments. - -Furthermore, ``ARGV`` holds the list of all arguments given to the -function and ``ARGN`` holds the list of arguments past the last expected -argument. -Referencing to ``ARGV#`` arguments beyond ``ARGC`` have undefined -behavior. Checking that ``ARGC`` is greater than ``#`` is the only way -to ensure that ``ARGV#`` was passed to the function as an extra -argument. +Defines a function named ```` that takes arguments named +````, ... The ```` in the function definition +are recorded; they are not executed until the function is invoked. Per legacy, the :command:`endfunction` command admits an optional ```` argument. If used, it must be a verbatim repeat of the @@ -40,3 +22,46 @@ details. See the :command:`cmake_policy()` command documentation for the behavior of policies inside functions. + +Invocation +^^^^^^^^^^ + +The function invocation is case-insensitive. A function defined as + +.. code-block:: cmake + + function(foo) + + endfunction() + +can be invoked through any of + +.. code-block:: cmake + + foo() + Foo() + FOO() + +and so on. However, it is strongly recommended to stay with the +case chosen in the function definition. Typically functions use +all-lowercase names. + +Arguments +^^^^^^^^^ + +When the function is invoked, the recorded ```` are first +modified by replacing formal parameters (``${arg1}``, ...) with the +arguments passed, and then invoked as normal commands. + +In addition to referencing the formal parameters you can reference the +``ARGC`` variable which will be set to the number of arguments passed +into the function as well as ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which +will have the actual values of the arguments passed in. This facilitates +creating functions with optional arguments. + +Furthermore, ``ARGV`` holds the list of all arguments given to the +function and ``ARGN`` holds the list of arguments past the last expected +argument. Referencing to ``ARGV#`` arguments beyond ``ARGC`` have +undefined behavior. Checking that ``ARGC`` is greater than ``#`` is +the only way to ensure that ``ARGV#`` was passed to the function as an +extra argument. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=357cdee3a133a943828d85d6441dfdee9d347751 commit 357cdee3a133a943828d85d6441dfdee9d347751 Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 22:58:20 2018 +0100 Commit: Brad King CommitDate: Tue Nov 13 13:47:24 2018 -0500 Help: Document that macro invocation is case-insensitive diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 287855b..e15e206 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -9,12 +9,46 @@ Start recording a macro for later invocation as a command endmacro() -Defines a macro named ```` that takes arguments -named ````, ... -Commands listed after macro, but before the matching -:command:`endmacro()`, are not invoked until the macro is invoked. -When it is invoked, the commands recorded in the macro are first -modified by replacing formal parameters (``${arg1}``, ...) +Defines a macro named ```` that takes arguments named +````, ... Commands listed after macro, but before the +matching :command:`endmacro()`, are not executed until the macro +is invoked. + +Per legacy, the :command:`endmacro` command admits an optional +```` argument. If used, it must be a verbatim repeat of the +argument of the opening ``macro`` command. + +See the :command:`cmake_policy()` command documentation for the behavior +of policies inside macros. + +Invocation +^^^^^^^^^^ + +The macro invocation is case-insensitive. A macro defined as + +.. code-block:: cmake + + macro(foo) + + endmacro() + +can be invoked through any of + +.. code-block:: cmake + + foo() + Foo() + FOO() + +and so on. However, it is strongly recommended to stay with the +case chosen in the macro definition. Typically macros use +all-lowercase names. + +Arguments +^^^^^^^^^ + +When a macro is invoked, the commands recorded in the macro are +first modified by replacing formal parameters (``${arg1}``, ...) with the arguments passed, and then invoked as normal commands. In addition to referencing the formal parameters you can reference the @@ -31,16 +65,8 @@ behavior. Checking that ``${ARGC}`` is greater than ``#`` is the only way to ensure that ``${ARGV#}`` was passed to the function as an extra argument. -Per legacy, the :command:`endmacro` command admits an optional -```` argument. If used, it must be a verbatim repeat of the -argument of the opening ``macro`` command. - - -See the :command:`cmake_policy()` command documentation for the behavior -of policies inside macros. - -Macro Argument Caveats -^^^^^^^^^^^^^^^^^^^^^^ +Argument Caveats +^^^^^^^^^^^^^^^^ Note that the parameters to a macro and values such as ``ARGN`` are not variables in the usual CMake sense. They are string https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=df780bcc018f65b6b182028df06dcd03ca10a4e7 commit df780bcc018f65b6b182028df06dcd03ca10a4e7 Author: Joachim Wuttke (l) AuthorDate: Mon Nov 12 22:13:12 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Tue Nov 13 13:06:30 2018 +0100 Help: Move deprecated modules to appropriate section. Move deprecated or obsolete modules to the section "Deprectated Modules" of cmake-modules(7): - MacroAddFileDependencies (Text says: Using the macro MACRO_ADD_FILE_DEPENDENCIES() is discouraged.) - UsePkgConfig (Text calls it "obsolete") - Use_wxWindows (was already listed in deprecation section) diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 266c7a1..57dcac2 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -76,7 +76,6 @@ These modules are loaded using the :command:`include` command. /module/GNUInstallDirs /module/GoogleTest /module/InstallRequiredSystemLibraries - /module/MacroAddFileDependencies /module/ProcessorCount /module/SelectLibraryConfigurations /module/SquishTestScript @@ -89,10 +88,8 @@ These modules are loaded using the :command:`include` command. /module/UseJavaClassFilelist /module/UseJava /module/UseJavaSymlinks - /module/UsePkgConfig /module/UseSWIG /module/UsewxWidgets - /module/Use_wxWindows /module/WriteCompilerDetectionHeader Find Modules @@ -270,7 +267,9 @@ Deprecated Utility Modules /module/CMakeExpandImportedTargets /module/CMakeForceCompiler /module/CMakeParseArguments + /module/MacroAddFileDependencies /module/TestCXXAcceptsFlag + /module/UsePkgConfig /module/Use_wxWindows /module/WriteBasicConfigVersionFile ----------------------------------------------------------------------- Summary of changes: Help/command/function.rst | 67 ++++++++++++++++++++++++++++------------- Help/command/macro.rst | 58 +++++++++++++++++++++++++---------- Help/manual/cmake-modules.7.rst | 5 ++- 3 files changed, 90 insertions(+), 40 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 14 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 14 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-438-gaa4ab1f Message-ID: <20181114050305.107EA127938@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via aa4ab1f904dfd7f6e3a95d310cd4d38875902c4b (commit) from 64bc4bda748b6c33d496fe294e959e7609b89260 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=aa4ab1f904dfd7f6e3a95d310cd4d38875902c4b commit aa4ab1f904dfd7f6e3a95d310cd4d38875902c4b Author: Kitware Robot AuthorDate: Wed Nov 14 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Wed Nov 14 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 19e2da7..82bbbb3 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 13) -set(CMake_VERSION_PATCH 20181113) +set(CMake_VERSION_PATCH 20181114) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 14 09:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 14 Nov 2018 09:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-442-g1172724 Message-ID: <20181114140306.CBA6B127B61@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 117272412e9dee1a1595718590a48e4c6750df59 (commit) via f835f189aeb38a791ad09ba5c2d89300a3fd16f1 (commit) via 4c0d97dd98805a5d9fc73ab9818a653888c16103 (commit) via 1b8f0ca5154c9fe8122b31e25dac65a4df94f5b1 (commit) from aa4ab1f904dfd7f6e3a95d310cd4d38875902c4b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=117272412e9dee1a1595718590a48e4c6750df59 commit 117272412e9dee1a1595718590a48e4c6750df59 Merge: aa4ab1f f835f18 Author: Brad King AuthorDate: Wed Nov 14 13:59:10 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 14 08:59:19 2018 -0500 Merge topic 'GNUInstallDirs-FreeBSD-info' f835f189ae GNUInstallDirs: Update FreeBSD "info" destination to share/info 4c0d97dd98 GNUInstallDirs: Split "info" and "man" default logic 1b8f0ca515 Tests: Split GNUInstallDirs expectations for FreeBSD Acked-by: Kitware Robot Acked-by: Rolf Eike Beer Merge-request: !2588 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f835f189aeb38a791ad09ba5c2d89300a3fd16f1 commit f835f189aeb38a791ad09ba5c2d89300a3fd16f1 Author: Tobias C. Berner AuthorDate: Sun Nov 11 20:04:46 2018 +0100 Commit: Brad King CommitDate: Tue Nov 13 13:35:50 2018 -0500 GNUInstallDirs: Update FreeBSD "info" destination to share/info FreeBSD ports commit r484628 (Install texinfo files (GNU info) into ${PREFIX}/share/info, 2018-11-10) changed the "info" destination from "info" to "share/info". The commit included a patch to their distribution of CMake to fix the `GNUInstallDirs` module too. Apply a similar logic change to our upstream version of the module. We already made a similar change for GNU/kFreeBSD in commit v3.13.0-rc2~8^2 (GNUInstallDirs: Don't use BSD info and man paths on GNU/kFreeBSD, 2018-10-21). Fixes: #18585 diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake index 49d36f6..4db4e18 100644 --- a/Modules/GNUInstallDirs.cmake +++ b/Modules/GNUInstallDirs.cmake @@ -277,7 +277,7 @@ _GNUInstallDirs_cache_path(CMAKE_INSTALL_DATAROOTDIR "share" _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}" "Read-only architecture-independent data (DATAROOTDIR)") -if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") +if(CMAKE_SYSTEM_NAME MATCHES "^(([^kF].*)?BSD|DragonFly)$") _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_INFODIR "info" "Info documentation (info)") else() diff --git a/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt index 09ae303..feb747b 100644 --- a/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt +++ b/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt @@ -3,7 +3,7 @@ CMAKE_INSTALL_DATADIR='share' CMAKE_INSTALL_DATAROOTDIR='share' CMAKE_INSTALL_DOCDIR='share/doc/Opt' CMAKE_INSTALL_INCLUDEDIR='include' -CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_INFODIR='share/info' CMAKE_INSTALL_LIBDIR='(lib|lib64)' CMAKE_INSTALL_LIBEXECDIR='libexec' CMAKE_INSTALL_LOCALEDIR='share/locale' @@ -18,7 +18,7 @@ CMAKE_INSTALL_FULL_DATADIR='/opt/Opt/share' CMAKE_INSTALL_FULL_DATAROOTDIR='/opt/Opt/share' CMAKE_INSTALL_FULL_DOCDIR='/opt/Opt/share/doc/Opt' CMAKE_INSTALL_FULL_INCLUDEDIR='/opt/Opt/include' -CMAKE_INSTALL_FULL_INFODIR='/opt/Opt/info' +CMAKE_INSTALL_FULL_INFODIR='/opt/Opt/share/info' CMAKE_INSTALL_FULL_LIBDIR='/opt/Opt/(lib|lib64)' CMAKE_INSTALL_FULL_LIBEXECDIR='/opt/Opt/libexec' CMAKE_INSTALL_FULL_LOCALEDIR='/opt/Opt/share/locale' diff --git a/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt index 4be66bc..4284a15 100644 --- a/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt +++ b/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt @@ -3,7 +3,7 @@ CMAKE_INSTALL_DATADIR='usr/share' CMAKE_INSTALL_DATAROOTDIR='usr/share' CMAKE_INSTALL_DOCDIR='usr/share/doc/Root' CMAKE_INSTALL_INCLUDEDIR='usr/include' -CMAKE_INSTALL_INFODIR='usr/info' +CMAKE_INSTALL_INFODIR='usr/share/info' CMAKE_INSTALL_LIBDIR='usr/(lib|lib64)' CMAKE_INSTALL_LIBEXECDIR='usr/libexec' CMAKE_INSTALL_LOCALEDIR='usr/share/locale' @@ -18,7 +18,7 @@ CMAKE_INSTALL_FULL_DATADIR='/usr/share' CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share' CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Root' CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include' -CMAKE_INSTALL_FULL_INFODIR='/usr/info' +CMAKE_INSTALL_FULL_INFODIR='/usr/share/info' CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64)' CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec' CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale' diff --git a/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt index 3d7b4c8..9efc110 100644 --- a/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt +++ b/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt @@ -3,7 +3,7 @@ CMAKE_INSTALL_DATADIR='share' CMAKE_INSTALL_DATAROOTDIR='share' CMAKE_INSTALL_DOCDIR='share/doc/Usr' CMAKE_INSTALL_INCLUDEDIR='include' -CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_INFODIR='share/info' CMAKE_INSTALL_LIBDIR='(lib|lib64|lib/arch)' CMAKE_INSTALL_LIBEXECDIR='libexec' CMAKE_INSTALL_LOCALEDIR='share/locale' @@ -18,7 +18,7 @@ CMAKE_INSTALL_FULL_DATADIR='/usr/share' CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share' CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Usr' CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include' -CMAKE_INSTALL_FULL_INFODIR='/usr/info' +CMAKE_INSTALL_FULL_INFODIR='/usr/share/info' CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64|lib/arch)' CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec' CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale' diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt index e1425d5..505bf08 100644 --- a/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt +++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt @@ -3,7 +3,7 @@ CMAKE_INSTALL_DATADIR='share' CMAKE_INSTALL_DATAROOTDIR='share' CMAKE_INSTALL_DOCDIR='share/doc/UsrLocal' CMAKE_INSTALL_INCLUDEDIR='include' -CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_INFODIR='share/info' CMAKE_INSTALL_LIBDIR='(lib|lib64)' CMAKE_INSTALL_LIBEXECDIR='libexec' CMAKE_INSTALL_LOCALEDIR='share/locale' @@ -18,7 +18,7 @@ CMAKE_INSTALL_FULL_DATADIR='/usr/local/share' CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/local/share' CMAKE_INSTALL_FULL_DOCDIR='/usr/local/share/doc/UsrLocal' CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/local/include' -CMAKE_INSTALL_FULL_INFODIR='/usr/local/info' +CMAKE_INSTALL_FULL_INFODIR='/usr/local/share/info' CMAKE_INSTALL_FULL_LIBDIR='/usr/local/(lib|lib64)' CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/local/libexec' CMAKE_INSTALL_FULL_LOCALEDIR='/usr/local/share/locale' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4c0d97dd98805a5d9fc73ab9818a653888c16103 commit 4c0d97dd98805a5d9fc73ab9818a653888c16103 Author: Brad King AuthorDate: Tue Nov 13 11:55:28 2018 -0500 Commit: Brad King CommitDate: Tue Nov 13 13:35:35 2018 -0500 GNUInstallDirs: Split "info" and "man" default logic The conditions may soon differ. diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake index 48d830f..49d36f6 100644 --- a/Modules/GNUInstallDirs.cmake +++ b/Modules/GNUInstallDirs.cmake @@ -280,11 +280,15 @@ _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAR if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_INFODIR "info" "Info documentation (info)") - _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_MANDIR "man" - "Man documentation (man)") else() _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info" "Info documentation (DATAROOTDIR/info)") +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") + _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_MANDIR "man" + "Man documentation (man)") +else() _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man" "Man documentation (DATAROOTDIR/man)") endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1b8f0ca5154c9fe8122b31e25dac65a4df94f5b1 commit 1b8f0ca5154c9fe8122b31e25dac65a4df94f5b1 Author: Brad King AuthorDate: Tue Nov 13 13:33:51 2018 -0500 Commit: Brad King CommitDate: Tue Nov 13 13:35:19 2018 -0500 Tests: Split GNUInstallDirs expectations for FreeBSD diff --git a/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt new file mode 100644 index 0000000..09ae303 --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/Opt-FreeBSD-stderr.txt @@ -0,0 +1,30 @@ +^CMAKE_INSTALL_BINDIR='bin' +CMAKE_INSTALL_DATADIR='share' +CMAKE_INSTALL_DATAROOTDIR='share' +CMAKE_INSTALL_DOCDIR='share/doc/Opt' +CMAKE_INSTALL_INCLUDEDIR='include' +CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_LIBDIR='(lib|lib64)' +CMAKE_INSTALL_LIBEXECDIR='libexec' +CMAKE_INSTALL_LOCALEDIR='share/locale' +CMAKE_INSTALL_LOCALSTATEDIR='var' +CMAKE_INSTALL_RUNSTATEDIR='var/run' +CMAKE_INSTALL_MANDIR='man' +CMAKE_INSTALL_SBINDIR='sbin' +CMAKE_INSTALL_SHAREDSTATEDIR='com' +CMAKE_INSTALL_SYSCONFDIR='etc' +CMAKE_INSTALL_FULL_BINDIR='/opt/Opt/bin' +CMAKE_INSTALL_FULL_DATADIR='/opt/Opt/share' +CMAKE_INSTALL_FULL_DATAROOTDIR='/opt/Opt/share' +CMAKE_INSTALL_FULL_DOCDIR='/opt/Opt/share/doc/Opt' +CMAKE_INSTALL_FULL_INCLUDEDIR='/opt/Opt/include' +CMAKE_INSTALL_FULL_INFODIR='/opt/Opt/info' +CMAKE_INSTALL_FULL_LIBDIR='/opt/Opt/(lib|lib64)' +CMAKE_INSTALL_FULL_LIBEXECDIR='/opt/Opt/libexec' +CMAKE_INSTALL_FULL_LOCALEDIR='/opt/Opt/share/locale' +CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var/opt/Opt' +CMAKE_INSTALL_FULL_RUNSTATEDIR='/var/run/opt/Opt' +CMAKE_INSTALL_FULL_MANDIR='/opt/Opt/man' +CMAKE_INSTALL_FULL_SBINDIR='/opt/Opt/sbin' +CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/opt/Opt/com' +CMAKE_INSTALL_FULL_SYSCONFDIR='/etc/opt/Opt'$ diff --git a/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt new file mode 100644 index 0000000..4be66bc --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/Root-FreeBSD-stderr.txt @@ -0,0 +1,30 @@ +^CMAKE_INSTALL_BINDIR='usr/bin' +CMAKE_INSTALL_DATADIR='usr/share' +CMAKE_INSTALL_DATAROOTDIR='usr/share' +CMAKE_INSTALL_DOCDIR='usr/share/doc/Root' +CMAKE_INSTALL_INCLUDEDIR='usr/include' +CMAKE_INSTALL_INFODIR='usr/info' +CMAKE_INSTALL_LIBDIR='usr/(lib|lib64)' +CMAKE_INSTALL_LIBEXECDIR='usr/libexec' +CMAKE_INSTALL_LOCALEDIR='usr/share/locale' +CMAKE_INSTALL_LOCALSTATEDIR='var' +CMAKE_INSTALL_RUNSTATEDIR='var/run' +CMAKE_INSTALL_MANDIR='usr/man' +CMAKE_INSTALL_SBINDIR='usr/sbin' +CMAKE_INSTALL_SHAREDSTATEDIR='usr/com' +CMAKE_INSTALL_SYSCONFDIR='etc' +CMAKE_INSTALL_FULL_BINDIR='/usr/bin' +CMAKE_INSTALL_FULL_DATADIR='/usr/share' +CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share' +CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Root' +CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include' +CMAKE_INSTALL_FULL_INFODIR='/usr/info' +CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64)' +CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec' +CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale' +CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var' +CMAKE_INSTALL_FULL_RUNSTATEDIR='/var/run' +CMAKE_INSTALL_FULL_MANDIR='/usr/man' +CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin' +CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com' +CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$ diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake index e00af58..d671ee0 100644 --- a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake +++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake @@ -1,7 +1,11 @@ include(RunCMake) -if(SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") - set(EXPECT_BSD 1) +if(SYSTEM_NAME STREQUAL "FreeBSD") + set(variant "-FreeBSD") +elseif(SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") + set(variant "-BSD") +else() + set(variant "") endif() foreach(case @@ -10,8 +14,6 @@ foreach(case Usr UsrLocal ) - if(EXPECT_BSD) - set(RunCMake-stderr-file ${case}-BSD-stderr.txt) - endif() + set(RunCMake-stderr-file ${case}${variant}-stderr.txt) run_cmake(${case}) endforeach() diff --git a/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt new file mode 100644 index 0000000..3d7b4c8 --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/Usr-FreeBSD-stderr.txt @@ -0,0 +1,30 @@ +^CMAKE_INSTALL_BINDIR='bin' +CMAKE_INSTALL_DATADIR='share' +CMAKE_INSTALL_DATAROOTDIR='share' +CMAKE_INSTALL_DOCDIR='share/doc/Usr' +CMAKE_INSTALL_INCLUDEDIR='include' +CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_LIBDIR='(lib|lib64|lib/arch)' +CMAKE_INSTALL_LIBEXECDIR='libexec' +CMAKE_INSTALL_LOCALEDIR='share/locale' +CMAKE_INSTALL_LOCALSTATEDIR='var' +CMAKE_INSTALL_RUNSTATEDIR='var/run' +CMAKE_INSTALL_MANDIR='man' +CMAKE_INSTALL_SBINDIR='sbin' +CMAKE_INSTALL_SHAREDSTATEDIR='com' +CMAKE_INSTALL_SYSCONFDIR='etc' +CMAKE_INSTALL_FULL_BINDIR='/usr/bin' +CMAKE_INSTALL_FULL_DATADIR='/usr/share' +CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share' +CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Usr' +CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include' +CMAKE_INSTALL_FULL_INFODIR='/usr/info' +CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64|lib/arch)' +CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec' +CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale' +CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var' +CMAKE_INSTALL_FULL_RUNSTATEDIR='/var/run' +CMAKE_INSTALL_FULL_MANDIR='/usr/man' +CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin' +CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com' +CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$ diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt b/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt new file mode 100644 index 0000000..e1425d5 --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal-FreeBSD-stderr.txt @@ -0,0 +1,30 @@ +^CMAKE_INSTALL_BINDIR='bin' +CMAKE_INSTALL_DATADIR='share' +CMAKE_INSTALL_DATAROOTDIR='share' +CMAKE_INSTALL_DOCDIR='share/doc/UsrLocal' +CMAKE_INSTALL_INCLUDEDIR='include' +CMAKE_INSTALL_INFODIR='info' +CMAKE_INSTALL_LIBDIR='(lib|lib64)' +CMAKE_INSTALL_LIBEXECDIR='libexec' +CMAKE_INSTALL_LOCALEDIR='share/locale' +CMAKE_INSTALL_LOCALSTATEDIR='var' +CMAKE_INSTALL_RUNSTATEDIR='var/run' +CMAKE_INSTALL_MANDIR='man' +CMAKE_INSTALL_SBINDIR='sbin' +CMAKE_INSTALL_SHAREDSTATEDIR='com' +CMAKE_INSTALL_SYSCONFDIR='etc' +CMAKE_INSTALL_FULL_BINDIR='/usr/local/bin' +CMAKE_INSTALL_FULL_DATADIR='/usr/local/share' +CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/local/share' +CMAKE_INSTALL_FULL_DOCDIR='/usr/local/share/doc/UsrLocal' +CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/local/include' +CMAKE_INSTALL_FULL_INFODIR='/usr/local/info' +CMAKE_INSTALL_FULL_LIBDIR='/usr/local/(lib|lib64)' +CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/local/libexec' +CMAKE_INSTALL_FULL_LOCALEDIR='/usr/local/share/locale' +CMAKE_INSTALL_FULL_LOCALSTATEDIR='/usr/local/var' +CMAKE_INSTALL_FULL_RUNSTATEDIR='/usr/local/var/run' +CMAKE_INSTALL_FULL_MANDIR='/usr/local/man' +CMAKE_INSTALL_FULL_SBINDIR='/usr/local/sbin' +CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/local/com' +CMAKE_INSTALL_FULL_SYSCONFDIR='/usr/local/etc'$ ----------------------------------------------------------------------- Summary of changes: Modules/GNUInstallDirs.cmake | 10 +++++++--- .../{Opt-stderr.txt => Opt-FreeBSD-stderr.txt} | 4 ++-- .../{Root-stderr.txt => Root-FreeBSD-stderr.txt} | 4 ++-- Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake | 12 +++++++----- .../{Usr-stderr.txt => Usr-FreeBSD-stderr.txt} | 4 ++-- .../{UsrLocal-stderr.txt => UsrLocal-FreeBSD-stderr.txt} | 4 ++-- 6 files changed, 22 insertions(+), 16 deletions(-) copy Tests/RunCMake/GNUInstallDirs/{Opt-stderr.txt => Opt-FreeBSD-stderr.txt} (93%) copy Tests/RunCMake/GNUInstallDirs/{Root-stderr.txt => Root-FreeBSD-stderr.txt} (93%) copy Tests/RunCMake/GNUInstallDirs/{Usr-stderr.txt => Usr-FreeBSD-stderr.txt} (93%) copy Tests/RunCMake/GNUInstallDirs/{UsrLocal-stderr.txt => UsrLocal-FreeBSD-stderr.txt} (93%) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 14 15:23:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 14 Nov 2018 15:23:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-445-ga786062 Message-ID: <20181114202305.2CDAB127B34@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via a786062db2bbfe375b51c200122eb3227120af2a (commit) via 254a84986471d6f3405d9bf1798bc3f9582a81e8 (commit) via b173c641c4efbb5fd3f3f4c18676be81abafb066 (commit) from 117272412e9dee1a1595718590a48e4c6750df59 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a786062db2bbfe375b51c200122eb3227120af2a commit a786062db2bbfe375b51c200122eb3227120af2a Merge: 1172724 254a849 Author: Brad King AuthorDate: Wed Nov 14 20:18:09 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 14 15:18:15 2018 -0500 Merge topic 'WIN32' 254a849864 Help: Spell out MFC b173c641c4 Help: Add links to variables Acked-by: Kitware Robot Merge-request: !2613 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=254a84986471d6f3405d9bf1798bc3f9582a81e8 commit 254a84986471d6f3405d9bf1798bc3f9582a81e8 Author: Joachim Wuttke (o) AuthorDate: Wed Nov 14 17:47:36 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Wed Nov 14 17:50:45 2018 +0100 Help: Spell out MFC And shorten text that was hard to understand and redundant. diff --git a/Help/prop_tgt/WIN32_EXECUTABLE.rst b/Help/prop_tgt/WIN32_EXECUTABLE.rst index ceda621..060d166 100644 --- a/Help/prop_tgt/WIN32_EXECUTABLE.rst +++ b/Help/prop_tgt/WIN32_EXECUTABLE.rst @@ -7,6 +7,7 @@ When this property is set to true the executable when linked on Windows will be created with a WinMain() entry point instead of just main(). This makes it a GUI executable instead of a console application. See the :variable:`CMAKE_MFC_FLAG` variable documentation to -configure use of MFC for WinMain executables. This property is -initialized by the value of the :variable:`CMAKE_WIN32_EXECUTABLE` -variable if it is set when a target is created. +configure use of the Microsoft Foundation Classes (MFC) for WinMain +executables. This property is initialized by the value of the +:variable:`CMAKE_WIN32_EXECUTABLE` variable if it is set when +a target is created. diff --git a/Help/variable/CMAKE_MFC_FLAG.rst b/Help/variable/CMAKE_MFC_FLAG.rst index 5a392bf..2c4d1c5 100644 --- a/Help/variable/CMAKE_MFC_FLAG.rst +++ b/Help/variable/CMAKE_MFC_FLAG.rst @@ -1,15 +1,16 @@ CMAKE_MFC_FLAG -------------- -Tell cmake to use MFC for an executable or dll. +Use the MFC library for an executable or dll. -This can be set in a ``CMakeLists.txt`` file and will enable MFC in the -application. It should be set to ``1`` for the static MFC library, and ``2`` -for the shared MFC library. This is used in Visual Studio -project files. The CMakeSetup dialog used MFC and the ``CMakeLists.txt`` -looks like this: +Enables the use of the Microsoft Foundation Classes (MFC). +It should be set to ``1`` for the static MFC library, and +``2`` for the shared MFC library. This is used in Visual Studio +project files. -:: +Usage example: + +.. code-block:: cmake add_definitions(-D_AFXDLL) set(CMAKE_MFC_FLAG 2) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b173c641c4efbb5fd3f3f4c18676be81abafb066 commit b173c641c4efbb5fd3f3f4c18676be81abafb066 Author: Joachim Wuttke (o) AuthorDate: Wed Nov 14 17:38:32 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Wed Nov 14 17:50:45 2018 +0100 Help: Add links to variables diff --git a/Help/prop_tgt/WIN32_EXECUTABLE.rst b/Help/prop_tgt/WIN32_EXECUTABLE.rst index 336d5f7..ceda621 100644 --- a/Help/prop_tgt/WIN32_EXECUTABLE.rst +++ b/Help/prop_tgt/WIN32_EXECUTABLE.rst @@ -5,8 +5,8 @@ Build an executable with a WinMain entry point on windows. When this property is set to true the executable when linked on Windows will be created with a WinMain() entry point instead of just -main(). This makes it a GUI executable instead of a console -application. See the CMAKE_MFC_FLAG variable documentation to +main(). This makes it a GUI executable instead of a console application. +See the :variable:`CMAKE_MFC_FLAG` variable documentation to configure use of MFC for WinMain executables. This property is -initialized by the value of the variable CMAKE_WIN32_EXECUTABLE if it -is set when a target is created. +initialized by the value of the :variable:`CMAKE_WIN32_EXECUTABLE` +variable if it is set when a target is created. ----------------------------------------------------------------------- Summary of changes: Help/prop_tgt/WIN32_EXECUTABLE.rst | 11 ++++++----- Help/variable/CMAKE_MFC_FLAG.rst | 15 ++++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 15 00:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 15 Nov 2018 00:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-446-g44a5400 Message-ID: <20181115050306.EF23E127827@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 44a5400d105b957d27780d515d0f1d51781f8de9 (commit) from a786062db2bbfe375b51c200122eb3227120af2a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=44a5400d105b957d27780d515d0f1d51781f8de9 commit 44a5400d105b957d27780d515d0f1d51781f8de9 Author: Kitware Robot AuthorDate: Thu Nov 15 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Thu Nov 15 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 82bbbb3..616e7d8 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 13) -set(CMake_VERSION_PATCH 20181114) +set(CMake_VERSION_PATCH 20181115) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 15 08:43:11 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 15 Nov 2018 08:43:11 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-460-g64df9ef Message-ID: <20181115134311.902CA125CDE@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 64df9ef33a2f4eb9ef0cb17a2844308d9c7f7034 (commit) via f21bad80a297e26b886f15f38f4d87cc5ce9687f (commit) via b3d1d6d895355ee64c74cef1ab0040db02f81894 (commit) via bd2c17d614e89b5786937565302c6fa54f121d22 (commit) via 22cca9b8100a59cd156e2ba39819171a0cf71881 (commit) via a82282a08c2ddf2eb3a89d61fbf53af1af3c4de9 (commit) via b90ae70a3b3c77109a31dfc275b778205a817d1a (commit) via bfbc5241e928203f934fd4fd83fa8beb35b0fe96 (commit) via 3e5a047f1aee1059d262b4096c5059ce2acad147 (commit) via 06cc050c1fa6141e5c376230ef7ab19ba2942a08 (commit) via e0c26406aa53b5dc4c942017eaf2410d0057aa9a (commit) via 83bbfb1d53077176af86d637f713652e3ee01198 (commit) via 01d5e5c460a2a9cb3962990f8ef278389254f30a (commit) via ca355d92d827a26d626a241535fe710600eead0d (commit) from 44a5400d105b957d27780d515d0f1d51781f8de9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=64df9ef33a2f4eb9ef0cb17a2844308d9c7f7034 commit 64df9ef33a2f4eb9ef0cb17a2844308d9c7f7034 Merge: f21bad8 e0c2640 Author: Brad King AuthorDate: Thu Nov 15 13:37:48 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 08:38:12 2018 -0500 Merge topic 'autogen_info_write' e0c26406aa Autogen: Sort tests 83bbfb1d53 Autogen: Add a definitions test to the MocOnly test 01d5e5c460 Autogen: Add and use cmQtAutoGenInitializer::InfoWriter class Acked-by: Kitware Robot Merge-request: !2610 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f21bad80a297e26b886f15f38f4d87cc5ce9687f commit f21bad80a297e26b886f15f38f4d87cc5ce9687f Merge: b3d1d6d ca355d9 Author: Brad King AuthorDate: Thu Nov 15 13:37:22 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 08:37:32 2018 -0500 Merge topic 'test-XcodeProject-timeout' ca355d92d8 Tests: Add option for custom RunCMake.XcodeProject timeout Acked-by: Kitware Robot Merge-request: !2614 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b3d1d6d895355ee64c74cef1ab0040db02f81894 commit b3d1d6d895355ee64c74cef1ab0040db02f81894 Merge: bd2c17d a82282a Author: Brad King AuthorDate: Thu Nov 15 13:36:18 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 08:36:52 2018 -0500 Merge topic 'doc-developer-to-source-guide' a82282a08c Help/dev: Factor out a CMake Documentation Guide for developing the docs bfbc5241e9 Help: Fix policy markup example in cmake-developer(7) 3e5a047f1a Help: Drop compile features section from cmake-developer(7) manual 06cc050c1f Help/dev: Drop 'size_t' preference from source code guide Acked-by: Kitware Robot Merge-request: !2615 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd2c17d614e89b5786937565302c6fa54f121d22 commit bd2c17d614e89b5786937565302c6fa54f121d22 Merge: 44a5400 22cca9b Author: Brad King AuthorDate: Thu Nov 15 13:35:54 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 08:36:02 2018 -0500 Merge topic 'macro3' 22cca9b810 Help: describe differences between macro and function. b90ae70a3b Help: in macro vs function example, use lowercase names. Acked-by: Kitware Robot Merge-request: !2616 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=22cca9b8100a59cd156e2ba39819171a0cf71881 commit 22cca9b8100a59cd156e2ba39819171a0cf71881 Author: Joachim Wuttke (l) AuthorDate: Wed Nov 14 20:50:59 2018 +0100 Commit: Joachim Wuttke (l) CommitDate: Wed Nov 14 21:56:23 2018 +0100 Help: describe differences between macro and function. diff --git a/Help/command/function.rst b/Help/command/function.rst index 7b10381..53ba754 100644 --- a/Help/command/function.rst +++ b/Help/command/function.rst @@ -23,6 +23,9 @@ details. See the :command:`cmake_policy()` command documentation for the behavior of policies inside functions. +See the :command:`macro()` command documentation for differences +between CMake functions and macros. + Invocation ^^^^^^^^^^ diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 7450929..42a99fc 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -21,6 +21,9 @@ argument of the opening ``macro`` command. See the :command:`cmake_policy()` command documentation for the behavior of policies inside macros. +See the :ref:`Macro vs Function` section below for differences +between CMake macros and :command:`functions `. + Invocation ^^^^^^^^^^ @@ -65,13 +68,36 @@ behavior. Checking that ``${ARGC}`` is greater than ``#`` is the only way to ensure that ``${ARGV#}`` was passed to the function as an extra argument. +.. _`Macro vs Function`: + +Macro vs Function +^^^^^^^^^^^^^^^^^ + +The ``macro`` command is very similar to the :command:`function` command. +Nonetheless, there are a few important differences. + +In a function, ``ARGC``, ``ARGC`` and ``ARGV0``, ``ARGV1``, ... are +true variables in the usual CMake sense. In a macro, they are not. +They are string replacements much like the C preprocessor would do +with a macro. This has a number of consequences, as explained in +the :ref:`Argument Caveats` section below. + +Another difference between macros and functions is the control flow. +A function is executed by transfering control from the calling +statement to the function body. A macro is executed as if the macro +body were pasted in place of the calling statement. This has for +consequence that a :command:`return()` in a macro body does not +just terminate execution of the macro; rather, control is returned +from the scope of the macro call. To avoid confusion, it is recommended +to avoid :command:`return()` in macros altogether. + +.. _`Argument Caveats`: + Argument Caveats ^^^^^^^^^^^^^^^^ -Note that the parameters to a macro and values such as ``ARGN`` are -not variables in the usual CMake sense. They are string -replacements much like the C preprocessor would do with a macro. -Therefore you will NOT be able to use commands like +Since ``ARGC``, ``ARGC``, ``ARGV0`` etc are not variables, +you will NOT be able to use commands like .. code-block:: cmake @@ -80,12 +106,11 @@ Therefore you will NOT be able to use commands like if(ARGC GREATER 2) # ARGC is not a variable foreach(loop_var IN LISTS ARGN) # ARGN is not a variable -In the first case, you can use ``if(${ARGV1})``. -In the second and third case, the proper way to check if an optional -variable was passed to the macro is to use ``if(${ARGC} GREATER 2)``. -In the last case, you can use ``foreach(loop_var ${ARGN})`` but this -will skip empty arguments. -If you need to include them, you can use +In the first case, you can use ``if(${ARGV1})``. In the second and +third case, the proper way to check if an optional variable was +passed to the macro is to use ``if(${ARGC} GREATER 2)``. In the +last case, you can use ``foreach(loop_var ${ARGN})`` but this will +skip empty arguments. If you need to include them, you can use .. code-block:: cmake https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a82282a08c2ddf2eb3a89d61fbf53af1af3c4de9 commit a82282a08c2ddf2eb3a89d61fbf53af1af3c4de9 Author: Brad King AuthorDate: Wed Nov 14 14:23:14 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 14:38:13 2018 -0500 Help/dev: Factor out a CMake Documentation Guide for developing the docs Remove this content from the `cmake-developer(7)` manual because it is relevant only to developers working on CMake itself. Move it to a guide in the developer documentation. diff --git a/Help/dev/README.rst b/Help/dev/README.rst index ce62abc..84da4f1 100644 --- a/Help/dev/README.rst +++ b/Help/dev/README.rst @@ -36,8 +36,10 @@ Developer Documentation CMake developer documentation is provided by the following documents: * The `CMake Source Code Guide`_. +* The `CMake Documentation Guide`_. .. _`CMake Source Code Guide`: source.rst +.. _`CMake Documentation Guide`: documentation.rst Maintainer Documentation ======================== diff --git a/Help/dev/documentation.rst b/Help/dev/documentation.rst new file mode 100644 index 0000000..1b2c942 --- /dev/null +++ b/Help/dev/documentation.rst @@ -0,0 +1,538 @@ +CMake Documentation Guide +************************* + +The following is a guide to the CMake documentation source for developers. +See documentation on `CMake Development`_ for more information. + +.. _`CMake Development`: README.rst + +Help +==== + +The ``Help`` directory contains CMake help manual source files. +They are written using the `reStructuredText`_ markup syntax and +processed by `Sphinx`_ to generate the CMake help manuals. + +.. _`reStructuredText`: http://docutils.sourceforge.net/docs/ref/rst/introduction.html +.. _`Sphinx`: http://sphinx-doc.org + +Markup Constructs +----------------- + +In addition to using Sphinx to generate the CMake help manuals, we +also use a C++-implemented document processor to print documents for +the ``--help-*`` command-line help options. It supports a subset of +reStructuredText markup. When authoring or modifying documents, +please verify that the command-line help looks good in addition to the +Sphinx-generated html and man pages. + +The command-line help processor supports the following constructs +defined by reStructuredText, Sphinx, and a CMake extension to Sphinx. + +.. + Note: This list must be kept consistent with the cmRST implementation. + +CMake Domain directives + Directives defined in the `CMake Domain`_ for defining CMake + documentation objects are printed in command-line help output as + if the lines were normal paragraph text with interpretation. + +CMake Domain interpreted text roles + Interpreted text roles defined in the `CMake Domain`_ for + cross-referencing CMake documentation objects are replaced by their + link text in command-line help output. Other roles are printed + literally and not processed. + +``code-block`` directive + Add a literal code block without interpretation. The command-line + help processor prints the block content without the leading directive + line and with common indentation replaced by one space. + +``include`` directive + Include another document source file. The command-line help + processor prints the included document inline with the referencing + document. + +literal block after ``::`` + A paragraph ending in ``::`` followed by a blank line treats + the following indented block as literal text without interpretation. + The command-line help processor prints the ``::`` literally and + prints the block content with common indentation replaced by one + space. + +``note`` directive + Call out a side note. The command-line help processor prints the + block content as if the lines were normal paragraph text with + interpretation. + +``parsed-literal`` directive + Add a literal block with markup interpretation. The command-line + help processor prints the block content without the leading + directive line and with common indentation replaced by one space. + +``productionlist`` directive + Render context-free grammar productions. The command-line help + processor prints the block content as if the lines were normal + paragraph text with interpretation. + +``replace`` directive + Define a ``|substitution|`` replacement. + The command-line help processor requires a substitution replacement + to be defined before it is referenced. + +``|substitution|`` reference + Reference a substitution replacement previously defined by + the ``replace`` directive. The command-line help processor + performs the substitution and replaces all newlines in the + replacement text with spaces. + +``toctree`` directive + Include other document sources in the Table-of-Contents + document tree. The command-line help processor prints + the referenced documents inline as part of the referencing + document. + +Inline markup constructs not listed above are printed literally in the +command-line help output. We prefer to use inline markup constructs that +look correct in source form, so avoid use of \\-escapes in favor of inline +literals when possible. + +Explicit markup blocks not matching directives listed above are removed from +command-line help output. Do not use them, except for plain ``..`` comments +that are removed by Sphinx too. + +Note that nested indentation of blocks is not recognized by the +command-line help processor. Therefore: + +* Explicit markup blocks are recognized only when not indented + inside other blocks. + +* Literal blocks after paragraphs ending in ``::`` but not + at the top indentation level may consume all indented lines + following them. + +Try to avoid these cases in practice. + +CMake Domain +------------ + +CMake adds a `Sphinx Domain`_ called ``cmake``, also called the +"CMake Domain". It defines several "object" types for CMake +documentation: + +``command`` + A CMake language command. + +``generator`` + A CMake native build system generator. + See the `cmake(1)`_ command-line tool's ``-G`` option. + +``manual`` + A CMake manual page, like the `cmake(1)`_ manual. + +``module`` + A CMake module. + See the `cmake-modules(7)`_ manual + and the `include()`_ command. + +``policy`` + A CMake policy. + See the `cmake-policies(7)`_ manual + and the `cmake_policy()`_ command. + +``prop_cache, prop_dir, prop_gbl, prop_sf, prop_inst, prop_test, prop_tgt`` + A CMake cache, directory, global, source file, installed file, test, + or target property, respectively. See the `cmake-properties(7)`_ + manual and the `set_property()`_ command. + +``variable`` + A CMake language variable. + See the `cmake-variables(7)`_ manual + and the `set()`_ command. + +Documentation objects in the CMake Domain come from two sources. +First, the CMake extension to Sphinx transforms every document named +with the form ``Help//.rst`` to a domain object with +type ````. The object name is extracted from the document title, +which is expected to be of the form:: + + + ------------- + +and to appear at or near the top of the ``.rst`` file before any other +lines starting in a letter, digit, or ``<``. If no such title appears +literally in the ``.rst`` file, the object name is the ````. +If a title does appear, it is expected that ```` is equal +to ```` with any ``<`` and ``>`` characters removed. + +Second, the CMake Domain provides directives to define objects inside +other documents: + +.. code-block:: rst + + .. command:: + + This indented block documents . + + .. variable:: + + This indented block documents . + +Object types for which no directive is available must be defined using +the first approach above. + +.. _`Sphinx Domain`: http://sphinx-doc.org/domains.html +.. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.html +.. _`cmake-modules(7)`: https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html +.. _`cmake-policies(7)`: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html +.. _`cmake-properties(7)`: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html +.. _`cmake-variables(7)`: https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html +.. _`cmake_policy()`: https://cmake.org/cmake/help/latest/command/cmake_policy.html +.. _`include()`: https://cmake.org/cmake/help/latest/command/include.html +.. _`set()`: https://cmake.org/cmake/help/latest/command/set.html +.. _`set_property()`: https://cmake.org/cmake/help/latest/command/set_property.html + +Cross-References +---------------- + +Sphinx uses reStructuredText interpreted text roles to provide +cross-reference syntax. The `CMake Domain`_ provides for each +domain object type a role of the same name to cross-reference it. +CMake Domain roles are inline markup of the forms:: + + :type:`name` + :type:`text ` + +where ``type`` is the domain object type and ``name`` is the +domain object name. In the first form the link text will be +``name`` (or ``name()`` if the type is ``command``) and in +the second form the link text will be the explicit ``text``. +For example, the code: + +.. code-block:: rst + + * The :command:`list` command. + * The :command:`list(APPEND)` sub-command. + * The :command:`list() command `. + * The :command:`list(APPEND) sub-command `. + * The :variable:`CMAKE_VERSION` variable. + * The :prop_tgt:`OUTPUT_NAME_` target property. + +produces: + +* The `list()`_ command. +* The `list(APPEND)`_ sub-command. +* The `list() command`_. +* The `list(APPEND) sub-command`_. +* The `CMAKE_VERSION`_ variable. +* The `OUTPUT_NAME_`_ target property. + +Note that CMake Domain roles differ from Sphinx and reStructuredText +convention in that the form ``a``, without a space preceding ``<``, +is interpreted as a name instead of link text with an explicit target. +This is necessary because we use ```` frequently in +object names like ``OUTPUT_NAME_``. The form ``a ``, +with a space preceding ``<``, is still interpreted as a link text +with an explicit target. + +.. _`list()`: https://cmake.org/cmake/help/latest/command/list.html +.. _`list(APPEND)`: https://cmake.org/cmake/help/latest/command/list.html +.. _`list(APPEND) sub-command`: https://cmake.org/cmake/help/latest/command/list.html +.. _`list() command`: https://cmake.org/cmake/help/latest/command/list.html +.. _`CMAKE_VERSION`: https://cmake.org/cmake/help/latest/variable/CMAKE_VERSION.html +.. _`OUTPUT_NAME_`: https://cmake.org/cmake/help/latest/prop_tgt/OUTPUT_NAME_CONFIG.html + +Style +----- + +Style: Section Headers +^^^^^^^^^^^^^^^^^^^^^^ + +When marking section titles, make the section decoration line as long as +the title text. Use only a line below the title, not above. For +example: + +.. code-block:: rst + + Title Text + ---------- + +Capitalize the first letter of each non-minor word in the title. + +The section header underline character hierarchy is + +* ``#``: Manual group (part) in the master document +* ``*``: Manual (chapter) title +* ``=``: Section within a manual +* ``-``: Subsection or `CMake Domain`_ object document title +* ``^``: Subsubsection or `CMake Domain`_ object document section +* ``"``: Paragraph or `CMake Domain`_ object document subsection + +Style: Whitespace +^^^^^^^^^^^^^^^^^ + +Use two spaces for indentation. Use two spaces between sentences in +prose. + +Style: Line Length +^^^^^^^^^^^^^^^^^^ + +Prefer to restrict the width of lines to 75-80 columns. This is not a +hard restriction, but writing new paragraphs wrapped at 75 columns +allows space for adding minor content without significant re-wrapping of +content. + +Style: Prose +^^^^^^^^^^^^ + +Use American English spellings in prose. + +Style: Starting Literal Blocks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Prefer to mark the start of literal blocks with ``::`` at the end of +the preceding paragraph. In cases where the following block gets +a ``code-block`` marker, put a single ``:`` at the end of the preceding +paragraph. + +Style: CMake Command Signatures +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Command signatures should be marked up as plain literal blocks, not as +cmake ``code-blocks``. + +Signatures are separated from preceding content by a section header. +That is, use: + +.. code-block:: rst + + ... preceding paragraph. + + Normal Libraries + ^^^^^^^^^^^^^^^^ + + :: + + add_library( ...) + + This signature is used for ... + +Signatures of commands should wrap optional parts with square brackets, +and should mark list of optional arguments with an ellipsis (``...``). +Elements of the signature which are specified by the user should be +specified with angle brackets, and may be referred to in prose using +``inline-literal`` syntax. + +Style: Boolean Constants +^^^^^^^^^^^^^^^^^^^^^^^^ + +Use "``OFF``" and "``ON``" for boolean values which can be modified by +the user, such as ``POSITION_INDEPENDENT_CODE``. Such properties +may be "enabled" and "disabled". Use "``True``" and "``False``" for +inherent values which can't be modified after being set, such as the +``IMPORTED`` property of a build target. + +Style: Inline Literals +^^^^^^^^^^^^^^^^^^^^^^ + +Mark up references to keywords in signatures, file names, and other +technical terms with ``inline-literal`` syntax, for example: + +.. code-block:: rst + + If ``WIN32`` is used with :command:`add_executable`, the + :prop_tgt:`WIN32_EXECUTABLE` target property is enabled. That command + creates the file ``.exe`` on Windows. + +Style: Cross-References +^^^^^^^^^^^^^^^^^^^^^^^ + +Mark up linkable references as links, including repeats. +An alternative, which is used by wikipedia +(``_), +is to link to a reference only once per article. That style is not used +in CMake documentation. + +Style: Referencing CMake Concepts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If referring to a concept which corresponds to a property, and that +concept is described in a high-level manual, prefer to link to the +manual section instead of the property. For example: + +.. code-block:: rst + + This command creates an :ref:`Imported Target `. + +instead of: + +.. code-block:: rst + + This command creates an :prop_tgt:`IMPORTED` target. + +The latter should be used only when referring specifically to the +property. + +References to manual sections are not automatically created by creating +a section, but code such as: + +.. code-block:: rst + + .. _`Imported Targets`: + +creates a suitable anchor. Use an anchor name which matches the name +of the corresponding section. Refer to the anchor using a +cross-reference with specified text. + +Imported Targets need the ``IMPORTED`` term marked up with care in +particular because the term may refer to a command keyword, a target +property, or a concept. + +Where a property, command or variable is related conceptually to others, +by for example, being related to the buildsystem description, generator +expressions or Qt, each relevant property, command or variable should +link to the primary manual, which provides high-level information. Only +particular information relating to the command should be in the +documentation of the command. + +Style: Referencing CMake Domain Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When referring to `CMake Domain`_ objects such as properties, variables, +commands etc, prefer to link to the target object and follow that with +the type of object it is. For example: + +.. code-block:: rst + + Set the :prop_tgt:`AUTOMOC` target property to ``ON``. + +Instead of + +.. code-block:: rst + + Set the target property :prop_tgt:`AUTOMOC` to ``ON``. + +The ``policy`` directive is an exception, and the type us usually +referred to before the link: + +.. code-block:: rst + + If policy :policy:`CMP0022` is set to ``NEW`` the behavior is ... + +However, markup self-references with ``inline-literal`` syntax. +For example, within the ``add_executable`` command documentation, use + +.. code-block:: rst + + ``add_executable`` + +not + +.. code-block:: rst + + :command:`add_executable` + +which is used elsewhere. + +Modules +======= + +The ``Modules`` directory contains CMake-language ``.cmake`` module files. + +Module Documentation +-------------------- + +To document CMake module ``Modules/.cmake``, modify +``Help/manual/cmake-modules.7.rst`` to reference the module in the +``toctree`` directive, in sorted order, as:: + + /module/ + +Then add the module document file ``Help/module/.rst`` +containing just the line:: + + .. cmake-module:: ../../Modules/.cmake + +The ``cmake-module`` directive will scan the module file to extract +reStructuredText markup from comment blocks that start in ``.rst:``. +At the top of ``Modules/.cmake``, begin with the following +license notice: + +.. code-block:: cmake + + # Distributed under the OSI-approved BSD 3-Clause License. See accompanying + # file Copyright.txt or https://cmake.org/licensing for details. + +After this notice, add a *BLANK* line. Then, add documentation using +a `Line Comment`_ block of the form: + +.. code-block:: cmake + + #.rst: + # + # ------------- + # + # + +or a `Bracket Comment`_ of the form: + +:: + + #[[.rst: + + ------------- + + + #]] + +Any number of ``=`` may be used in the opening and closing brackets +as long as they match. Content on the line containing the closing +bracket is excluded if and only if the line starts in ``#``. + +Additional such ``.rst:`` comments may appear anywhere in the module file. +All such comments must start with ``#`` in the first column. + +For example, a ``Findxxx.cmake`` module may contain: + +:: + + # Distributed under the OSI-approved BSD 3-Clause License. See accompanying + # file Copyright.txt or https://cmake.org/licensing for details. + + #.rst: + # FindXxx + # ------- + # + # This is a cool module. + # This module does really cool stuff. + # It can do even more than you think. + # + # It even needs two paragraphs to tell you about it. + # And it defines the following variables: + # + # * VAR_COOL: this is great isn't it? + # * VAR_REALLY_COOL: cool right? + + + + #[========================================[.rst: + .. command:: xxx_do_something + + This command does something for Xxx:: + + xxx_do_something(some arguments) + #]========================================] + macro(xxx_do_something) + + endmacro() + +Test the documentation formatting by running +``cmake --help-module ``, and also by enabling the +``SPHINX_HTML`` and ``SPHINX_MAN`` options to build the documentation. +Edit the comments until generated documentation looks satisfactory. To +have a .cmake file in this directory NOT show up in the modules +documentation, simply leave out the ``Help/module/.rst`` +file and the ``Help/manual/cmake-modules.7.rst`` toctree entry. + +.. _`Line Comment`: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#line-comment +.. _`Bracket Comment`: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#bracket-comment diff --git a/Help/dev/source.rst b/Help/dev/source.rst index 4a1fdc8..6697d38 100644 --- a/Help/dev/source.rst +++ b/Help/dev/source.rst @@ -49,7 +49,7 @@ The CMake source tree is organized as follows. Shell and editor integration files. * ``Help/``: - Documentation. + Documentation. See the `CMake Documentation Guide`_. * ``Help/dev/``: Developer documentation. @@ -85,4 +85,5 @@ The CMake source tree is organized as follows. * ``Utilities/Release/``: Scripts used to package CMake itself for distribution on ``cmake.org``. +.. _`CMake Documentation Guide`: documentation.rst .. _`Tests/README.rst`: ../../Tests/README.rst diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index d0174b8..b949464 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -10,532 +10,20 @@ cmake-developer(7) Introduction ============ -This manual is intended for reference by developers modifying the CMake -source tree itself, and by those authoring externally-maintained modules. +This manual is intended for reference by developers working with +:manual:`cmake-language(7)` code, whether writing their own modules, +authoring their own build systems, or working on CMake itself. See https://cmake.org/get-involved/ to get involved in development of -CMake upstream. - -Help -==== - -The ``Help`` directory contains CMake help manual source files. -They are written using the `reStructuredText`_ markup syntax and -processed by `Sphinx`_ to generate the CMake help manuals. - -.. _`reStructuredText`: http://docutils.sourceforge.net/docs/ref/rst/introduction.html -.. _`Sphinx`: http://sphinx-doc.org - -Markup Constructs ------------------ - -In addition to using Sphinx to generate the CMake help manuals, we -also use a C++-implemented document processor to print documents for -the ``--help-*`` command-line help options. It supports a subset of -reStructuredText markup. When authoring or modifying documents, -please verify that the command-line help looks good in addition to the -Sphinx-generated html and man pages. - -The command-line help processor supports the following constructs -defined by reStructuredText, Sphinx, and a CMake extension to Sphinx. - -.. - Note: This list must be kept consistent with the cmRST implementation. - -CMake Domain directives - Directives defined in the `CMake Domain`_ for defining CMake - documentation objects are printed in command-line help output as - if the lines were normal paragraph text with interpretation. - -CMake Domain interpreted text roles - Interpreted text roles defined in the `CMake Domain`_ for - cross-referencing CMake documentation objects are replaced by their - link text in command-line help output. Other roles are printed - literally and not processed. - -``code-block`` directive - Add a literal code block without interpretation. The command-line - help processor prints the block content without the leading directive - line and with common indentation replaced by one space. - -``include`` directive - Include another document source file. The command-line help - processor prints the included document inline with the referencing - document. - -literal block after ``::`` - A paragraph ending in ``::`` followed by a blank line treats - the following indented block as literal text without interpretation. - The command-line help processor prints the ``::`` literally and - prints the block content with common indentation replaced by one - space. - -``note`` directive - Call out a side note. The command-line help processor prints the - block content as if the lines were normal paragraph text with - interpretation. - -``parsed-literal`` directive - Add a literal block with markup interpretation. The command-line - help processor prints the block content without the leading - directive line and with common indentation replaced by one space. - -``productionlist`` directive - Render context-free grammar productions. The command-line help - processor prints the block content as if the lines were normal - paragraph text with interpretation. - -``replace`` directive - Define a ``|substitution|`` replacement. - The command-line help processor requires a substitution replacement - to be defined before it is referenced. - -``|substitution|`` reference - Reference a substitution replacement previously defined by - the ``replace`` directive. The command-line help processor - performs the substitution and replaces all newlines in the - replacement text with spaces. - -``toctree`` directive - Include other document sources in the Table-of-Contents - document tree. The command-line help processor prints - the referenced documents inline as part of the referencing - document. - -Inline markup constructs not listed above are printed literally in the -command-line help output. We prefer to use inline markup constructs that -look correct in source form, so avoid use of \\-escapes in favor of inline -literals when possible. - -Explicit markup blocks not matching directives listed above are removed from -command-line help output. Do not use them, except for plain ``..`` comments -that are removed by Sphinx too. - -Note that nested indentation of blocks is not recognized by the -command-line help processor. Therefore: - -* Explicit markup blocks are recognized only when not indented - inside other blocks. - -* Literal blocks after paragraphs ending in ``::`` but not - at the top indentation level may consume all indented lines - following them. - -Try to avoid these cases in practice. - -CMake Domain ------------- - -CMake adds a `Sphinx Domain`_ called ``cmake``, also called the -"CMake Domain". It defines several "object" types for CMake -documentation: - -``command`` - A CMake language command. - -``generator`` - A CMake native build system generator. - See the :manual:`cmake(1)` command-line tool's ``-G`` option. - -``manual`` - A CMake manual page, like this :manual:`cmake-developer(7)` manual. - -``module`` - A CMake module. - See the :manual:`cmake-modules(7)` manual - and the :command:`include` command. - -``policy`` - A CMake policy. - See the :manual:`cmake-policies(7)` manual - and the :command:`cmake_policy` command. - -``prop_cache, prop_dir, prop_gbl, prop_sf, prop_inst, prop_test, prop_tgt`` - A CMake cache, directory, global, source file, installed file, test, - or target property, respectively. See the :manual:`cmake-properties(7)` - manual and the :command:`set_property` command. - -``variable`` - A CMake language variable. - See the :manual:`cmake-variables(7)` manual - and the :command:`set` command. - -Documentation objects in the CMake Domain come from two sources. -First, the CMake extension to Sphinx transforms every document named -with the form ``Help//.rst`` to a domain object with -type ````. The object name is extracted from the document title, -which is expected to be of the form:: - - - ------------- - -and to appear at or near the top of the ``.rst`` file before any other -lines starting in a letter, digit, or ``<``. If no such title appears -literally in the ``.rst`` file, the object name is the ````. -If a title does appear, it is expected that ```` is equal -to ```` with any ``<`` and ``>`` characters removed. - -Second, the CMake Domain provides directives to define objects inside -other documents: - -.. code-block:: rst - - .. command:: - - This indented block documents . - - .. variable:: - - This indented block documents . - -Object types for which no directive is available must be defined using -the first approach above. - -.. _`Sphinx Domain`: http://sphinx-doc.org/domains.html - -Cross-References ----------------- - -Sphinx uses reStructuredText interpreted text roles to provide -cross-reference syntax. The `CMake Domain`_ provides for each -domain object type a role of the same name to cross-reference it. -CMake Domain roles are inline markup of the forms:: - - :type:`name` - :type:`text ` - -where ``type`` is the domain object type and ``name`` is the -domain object name. In the first form the link text will be -``name`` (or ``name()`` if the type is ``command``) and in -the second form the link text will be the explicit ``text``. -For example, the code: - -.. code-block:: rst - - * The :command:`list` command. - * The :command:`list(APPEND)` sub-command. - * The :command:`list() command `. - * The :command:`list(APPEND) sub-command `. - * The :variable:`CMAKE_VERSION` variable. - * The :prop_tgt:`OUTPUT_NAME_` target property. - -produces: - -* The :command:`list` command. -* The :command:`list(APPEND)` sub-command. -* The :command:`list() command `. -* The :command:`list(APPEND) sub-command `. -* The :variable:`CMAKE_VERSION` variable. -* The :prop_tgt:`OUTPUT_NAME_` target property. - -Note that CMake Domain roles differ from Sphinx and reStructuredText -convention in that the form ``a``, without a space preceding ``<``, -is interpreted as a name instead of link text with an explicit target. -This is necessary because we use ```` frequently in -object names like ``OUTPUT_NAME_``. The form ``a ``, -with a space preceding ``<``, is still interpreted as a link text -with an explicit target. - -Style ------ - -Style: Section Headers -^^^^^^^^^^^^^^^^^^^^^^ - -When marking section titles, make the section decoration line as long as -the title text. Use only a line below the title, not above. For -example: - -.. code-block:: rst - - Title Text - ---------- - -Capitalize the first letter of each non-minor word in the title. - -The section header underline character hierarchy is - -* ``#``: Manual group (part) in the master document -* ``*``: Manual (chapter) title -* ``=``: Section within a manual -* ``-``: Subsection or `CMake Domain`_ object document title -* ``^``: Subsubsection or `CMake Domain`_ object document section -* ``"``: Paragraph or `CMake Domain`_ object document subsection - -Style: Whitespace -^^^^^^^^^^^^^^^^^ - -Use two spaces for indentation. Use two spaces between sentences in -prose. - -Style: Line Length -^^^^^^^^^^^^^^^^^^ - -Prefer to restrict the width of lines to 75-80 columns. This is not a -hard restriction, but writing new paragraphs wrapped at 75 columns -allows space for adding minor content without significant re-wrapping of -content. - -Style: Prose -^^^^^^^^^^^^ - -Use American English spellings in prose. - -Style: Starting Literal Blocks -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Prefer to mark the start of literal blocks with ``::`` at the end of -the preceding paragraph. In cases where the following block gets -a ``code-block`` marker, put a single ``:`` at the end of the preceding -paragraph. - -Style: CMake Command Signatures -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Command signatures should be marked up as plain literal blocks, not as -cmake ``code-blocks``. - -Signatures are separated from preceding content by a section header. -That is, use: - -.. code-block:: rst - - ... preceding paragraph. - - Normal Libraries - ^^^^^^^^^^^^^^^^ - - :: - - add_library( ...) - - This signature is used for ... - -Signatures of commands should wrap optional parts with square brackets, -and should mark list of optional arguments with an ellipsis (``...``). -Elements of the signature which are specified by the user should be -specified with angle brackets, and may be referred to in prose using -``inline-literal`` syntax. - -Style: Boolean Constants -^^^^^^^^^^^^^^^^^^^^^^^^ - -Use "``OFF``" and "``ON``" for boolean values which can be modified by -the user, such as :prop_tgt:`POSITION_INDEPENDENT_CODE`. Such properties -may be "enabled" and "disabled". Use "``True``" and "``False``" for -inherent values which can't be modified after being set, such as the -:prop_tgt:`IMPORTED` property of a build target. - -Style: Inline Literals -^^^^^^^^^^^^^^^^^^^^^^ - -Mark up references to keywords in signatures, file names, and other -technical terms with ``inline-literal`` syntax, for example: - -.. code-block:: rst - - If ``WIN32`` is used with :command:`add_executable`, the - :prop_tgt:`WIN32_EXECUTABLE` target property is enabled. That command - creates the file ``.exe`` on Windows. - -Style: Cross-References -^^^^^^^^^^^^^^^^^^^^^^^ - -Mark up linkable references as links, including repeats. -An alternative, which is used by wikipedia -(``_), -is to link to a reference only once per article. That style is not used -in CMake documentation. - -Style: Referencing CMake Concepts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If referring to a concept which corresponds to a property, and that -concept is described in a high-level manual, prefer to link to the -manual section instead of the property. For example: - -.. code-block:: rst - - This command creates an :ref:`Imported Target `. - -instead of: - -.. code-block:: rst - - This command creates an :prop_tgt:`IMPORTED` target. - -The latter should be used only when referring specifically to the -property. - -References to manual sections are not automatically created by creating -a section, but code such as: - -.. code-block:: rst - - .. _`Imported Targets`: - -creates a suitable anchor. Use an anchor name which matches the name -of the corresponding section. Refer to the anchor using a -cross-reference with specified text. - -Imported Targets need the ``IMPORTED`` term marked up with care in -particular because the term may refer to a command keyword -(``IMPORTED``), a target property (:prop_tgt:`IMPORTED`), or a -concept (:ref:`Imported Targets`). - -Where a property, command or variable is related conceptually to others, -by for example, being related to the buildsystem description, generator -expressions or Qt, each relevant property, command or variable should -link to the primary manual, which provides high-level information. Only -particular information relating to the command should be in the -documentation of the command. - -Style: Referencing CMake Domain Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When referring to `CMake Domain`_ objects such as properties, variables, -commands etc, prefer to link to the target object and follow that with -the type of object it is. For example: - -.. code-block:: rst - - Set the :prop_tgt:`AUTOMOC` target property to ``ON``. - -Instead of - -.. code-block:: rst - - Set the target property :prop_tgt:`AUTOMOC` to ``ON``. - -The ``policy`` directive is an exception, and the type us usually -referred to before the link: - -.. code-block:: rst - - If policy :policy:`CMP0022` is set to ``NEW`` the behavior is ... - -However, markup self-references with ``inline-literal`` syntax. -For example, within the :command:`add_executable` command -documentation, use - -.. code-block:: rst - - ``add_executable`` - -not - -.. code-block:: rst - - :command:`add_executable` - -which is used elsewhere. - -Modules -======= - -The ``Modules`` directory contains CMake-language ``.cmake`` module files. - -Module Documentation --------------------- - -To document CMake module ``Modules/.cmake``, modify -``Help/manual/cmake-modules.7.rst`` to reference the module in the -``toctree`` directive, in sorted order, as:: - - /module/ - -Then add the module document file ``Help/module/.rst`` -containing just the line:: - - .. cmake-module:: ../../Modules/.cmake - -The ``cmake-module`` directive will scan the module file to extract -reStructuredText markup from comment blocks that start in ``.rst:``. -At the top of ``Modules/.cmake``, begin with the following -license notice: - -.. code-block:: cmake - - # Distributed under the OSI-approved BSD 3-Clause License. See accompanying - # file Copyright.txt or https://cmake.org/licensing for details. - -After this notice, add a *BLANK* line. Then, add documentation using -a :ref:`Line Comment` block of the form: - -.. code-block:: cmake - - #.rst: - # - # ------------- - # - # - -or a :ref:`Bracket Comment` of the form: - -:: - - #[[.rst: - - ------------- - - - #]] - -Any number of ``=`` may be used in the opening and closing brackets -as long as they match. Content on the line containing the closing -bracket is excluded if and only if the line starts in ``#``. - -Additional such ``.rst:`` comments may appear anywhere in the module file. -All such comments must start with ``#`` in the first column. - -For example, a ``Modules/Findxxx.cmake`` module may contain: - -:: - - # Distributed under the OSI-approved BSD 3-Clause License. See accompanying - # file Copyright.txt or https://cmake.org/licensing for details. - - #.rst: - # FindXxx - # ------- - # - # This is a cool module. - # This module does really cool stuff. - # It can do even more than you think. - # - # It even needs two paragraphs to tell you about it. - # And it defines the following variables: - # - # * VAR_COOL: this is great isn't it? - # * VAR_REALLY_COOL: cool right? - - - - #[========================================[.rst: - .. command:: xxx_do_something - - This command does something for Xxx:: - - xxx_do_something(some arguments) - #]========================================] - macro(xxx_do_something) - - endmacro() - -Test the documentation formatting by running -``cmake --help-module ``, and also by enabling the -``SPHINX_HTML`` and ``SPHINX_MAN`` options to build the documentation. -Edit the comments until generated documentation looks satisfactory. To -have a .cmake file in this directory NOT show up in the modules -documentation, simply leave out the ``Help/module/.rst`` -file and the ``Help/manual/cmake-modules.7.rst`` toctree entry. +CMake upstream. It includes links to contribution instructions, which +in turn link to developer guides for CMake itself. .. _`Find Modules`: Find Modules ------------- +============ -A "find module" is a ``Modules/Find.cmake`` file to be loaded +A "find module" is a ``Find.cmake`` file to be loaded by the :command:`find_package` command when invoked for ````. The primary task of a find module is to determine whether a package @@ -594,16 +82,11 @@ and required is up to the find module, but should be documented. For internal implementation, it is a generally accepted convention that variables starting with underscore are for temporary use only. -Like all modules, find modules should be properly documented. To add a -module to the CMake documentation, follow the steps in the `Module -Documentation`_ section above. - - .. _`CMake Developer Standard Variable Names`: Standard Variable Names -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- For a ``FindXxx.cmake`` module that takes the approach of setting variables (either instead of or in addition to creating imported @@ -710,9 +193,8 @@ Make sure you comment them as deprecated, so that no-one starts using them. - A Sample Find Module -^^^^^^^^^^^^^^^^^^^^ +-------------------- We will describe how to create a simple find module for a library ``Foo``. @@ -755,8 +237,7 @@ variables and imported targets are set by the module, such as # Foo::Foo - The Foo library If the package provides any macros, they should be listed here, but can -be documented where they are defined. See the `Module -Documentation`_ section above for more details. +be documented where they are defined. Now the actual libraries and so on have to be found. The code here will obviously vary from module to module (dealing with that, after all, is the https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b90ae70a3b3c77109a31dfc275b778205a817d1a commit b90ae70a3b3c77109a31dfc275b778205a817d1a Author: Joachim Wuttke (l) AuthorDate: Wed Nov 14 09:10:31 2018 +0100 Commit: Joachim Wuttke (l) CommitDate: Wed Nov 14 20:33:12 2018 +0100 Help: in macro vs function example, use lowercase names. Follow our own advise not to change cases. Omit the leading underscore. diff --git a/Help/command/macro.rst b/Help/command/macro.rst index e15e206..7450929 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -98,18 +98,18 @@ existing variable instead of the arguments. For example: .. code-block:: cmake - macro(_BAR) + macro(bar) foreach(arg IN LISTS ARGN) endforeach() endmacro() - function(_FOO) - _bar(x y z) + function(foo) + bar(x y z) endfunction() - _foo(a b c) + foo(a b c) -Will loop over ``a;b;c`` and not over ``x;y;z`` as one might be expecting. +Will loop over ``a;b;c`` and not over ``x;y;z`` as one might have expected. If you want true CMake variables and/or better CMake scope control you should look at the function command. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bfbc5241e928203f934fd4fd83fa8beb35b0fe96 commit bfbc5241e928203f934fd4fd83fa8beb35b0fe96 Author: Brad King AuthorDate: Wed Nov 14 09:55:20 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 14:29:13 2018 -0500 Help: Fix policy markup example in cmake-developer(7) diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index b30b705..d0174b8 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -412,7 +412,7 @@ referred to before the link: .. code-block:: rst - If policy :prop_tgt:`CMP0022` is set to ``NEW`` the behavior is ... + If policy :policy:`CMP0022` is set to ``NEW`` the behavior is ... However, markup self-references with ``inline-literal`` syntax. For example, within the :command:`add_executable` command https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3e5a047f1aee1059d262b4096c5059ce2acad147 commit 3e5a047f1aee1059d262b4096c5059ce2acad147 Author: Brad King AuthorDate: Wed Nov 14 09:33:41 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 14:29:13 2018 -0500 Help: Drop compile features section from cmake-developer(7) manual We no longer add granular compile features. Only language standard meta features like `cxx_std_##`` need to be added, and these can be done by following existing patterns. diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index c3bbf28..b30b705 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -16,53 +16,6 @@ source tree itself, and by those authoring externally-maintained modules. See https://cmake.org/get-involved/ to get involved in development of CMake upstream. -Adding Compile Features -======================= - -CMake reports an error if a compiler whose features are known does not report -support for a particular requested feature. A compiler is considered to have -known features if it reports support for at least one feature. - -When adding a new compile feature to CMake, it is therefore necessary to list -support for the feature for all CompilerIds which already have one or more -feature supported, if the new feature is available for any version of the -compiler. - -When adding the first supported feature to a particular CompilerId, it is -necessary to list support for all features known to cmake (See -:variable:`CMAKE_C_COMPILE_FEATURES` and -:variable:`CMAKE_CXX_COMPILE_FEATURES` as appropriate), where available for -the compiler. Ensure that the ``CMAKE__STANDARD_DEFAULT`` is set to -the computed internal variable ``CMAKE__STANDARD_COMPUTED_DEFAULT`` -for compiler versions which should be supported. - -It is sensible to record the features for the most recent version of a -particular CompilerId first, and then work backwards. It is sensible to -try to create a continuous range of versions of feature releases of the -compiler. Gaps in the range indicate incorrect features recorded for -intermediate releases. - -Generally, features are made available for a particular version if the -compiler vendor documents availability of the feature with that -version. Note that sometimes partially implemented features appear to -be functional in previous releases (such as ``cxx_constexpr`` in GNU 4.6, -though availability is documented in GNU 4.7), and sometimes compiler vendors -document availability of features, though supporting infrastructure is -not available (such as ``__has_feature(cxx_generic_lambdas)`` indicating -non-availability in Clang 3.4, though it is documented as available, and -fixed in Clang 3.5). Similar cases for other compilers and versions -need to be investigated when extending CMake to support them. - -When a vendor releases a new version of a known compiler which supports -a previously unsupported feature, and there are already known features for -that compiler, the feature should be listed as supported in CMake for -that version of the compiler as soon as reasonably possible. - -Standard-specific/compiler-specific variables such -``CMAKE_CXX98_COMPILE_FEATURES`` are deliberately not documented. They -only exist for the compiler-specific implementation of adding the ``-std`` -compile flag for compilers which need that. - Help ==== https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=06cc050c1fa6141e5c376230ef7ab19ba2942a08 commit 06cc050c1fa6141e5c376230ef7ab19ba2942a08 Author: Brad King AuthorDate: Wed Nov 14 09:28:34 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 14:28:57 2018 -0500 Help/dev: Drop 'size_t' preference from source code guide We now use `std::size_t` in several places and it is fully supported by C++11 compilers. Drop the recommendation to prefer plain `size_t`. diff --git a/Help/dev/source.rst b/Help/dev/source.rst index 57de818..4a1fdc8 100644 --- a/Help/dev/source.rst +++ b/Help/dev/source.rst @@ -40,13 +40,6 @@ building on older toolchains some constructs need to be handled with care: derived from non-copyable classes must also be made non-copyable explicitly with ``CM_DISABLE_COPY``. -* Use ``size_t`` instead of ``std::size_t``. - - Various implementations have differing implementation of ``size_t``. - When assigning the result of ``.size()`` on a container for example, - the result should be assigned to ``size_t`` not to ``std::size_t``, - ``unsigned int`` or similar types. - Source Tree Layout ================== https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e0c26406aa53b5dc4c942017eaf2410d0057aa9a commit e0c26406aa53b5dc4c942017eaf2410d0057aa9a Author: Sebastian Holtermann AuthorDate: Tue Nov 13 13:24:33 2018 +0100 Commit: Sebastian Holtermann CommitDate: Wed Nov 14 19:21:03 2018 +0100 Autogen: Sort tests diff --git a/Tests/Qt4Autogen/CMakeLists.txt b/Tests/Qt4Autogen/CMakeLists.txt index 818e888..68b885b 100644 --- a/Tests/Qt4Autogen/CMakeLists.txt +++ b/Tests/Qt4Autogen/CMakeLists.txt @@ -6,4 +6,4 @@ include("../QtAutogen/TestMacros.cmake") ADD_AUTOGEN_TEST(DefinesTest) # Common tests -include("../QtAutogen/CommonTests.cmake") +include("../QtAutogen/Tests.cmake") diff --git a/Tests/Qt5Autogen/CMakeLists.txt b/Tests/Qt5Autogen/CMakeLists.txt index 527e5ff..49d33cc 100644 --- a/Tests/Qt5Autogen/CMakeLists.txt +++ b/Tests/Qt5Autogen/CMakeLists.txt @@ -3,4 +3,4 @@ set(QT_TEST_VERSION 5) include("../QtAutogen/TestMacros.cmake") # Common tests -include("../QtAutogen/CommonTests.cmake") +include("../QtAutogen/Tests.cmake") diff --git a/Tests/QtAutogen/CommonTests.cmake b/Tests/QtAutogen/Tests.cmake similarity index 83% rename from Tests/QtAutogen/CommonTests.cmake rename to Tests/QtAutogen/Tests.cmake index 1cd9e7e..5025d43 100644 --- a/Tests/QtAutogen/CommonTests.cmake +++ b/Tests/QtAutogen/Tests.cmake @@ -1,52 +1,46 @@ -# Autogen tests common for Qt4 and Qt5 +# Qt4 and Qt5 tests +ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff) +ADD_AUTOGEN_TEST(AutogenOriginDependsOn) +ADD_AUTOGEN_TEST(AutogenTargetDepends) ADD_AUTOGEN_TEST(Complex QtAutogen) +ADD_AUTOGEN_TEST(GlobalAutogenTarget) ADD_AUTOGEN_TEST(LowMinimumVersion lowMinimumVersion) ADD_AUTOGEN_TEST(MocOnly mocOnly) ADD_AUTOGEN_TEST(MocOptions mocOptions) -ADD_AUTOGEN_TEST(UicOnly uicOnly) -ADD_AUTOGEN_TEST(RccOnly rccOnly) -ADD_AUTOGEN_TEST(RccEmpty rccEmpty) -ADD_AUTOGEN_TEST(RccOffMocLibrary) -ADD_AUTOGEN_TEST(GlobalAutogenTarget) -if(QT_TEST_ALLOW_QT_MACROS) - ADD_AUTOGEN_TEST(MocSkipSource) -endif() -ADD_AUTOGEN_TEST(UicSkipSource) -ADD_AUTOGEN_TEST(RccSkipSource) -if(QT_TEST_VERSION GREATER 4) - ADD_AUTOGEN_TEST(MocMacroName mocMacroName) -endif() -ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff) -ADD_AUTOGEN_TEST(AutogenOriginDependsOn) -ADD_AUTOGEN_TEST(AutogenTargetDepends) -if(QT_TEST_ALLOW_QT_MACROS) - ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) - ADD_AUTOGEN_TEST(MocIncludeRelaxed mocIncludeRelaxed) -endif() -if(QT_TEST_ALLOW_QT_MACROS) - ADD_AUTOGEN_TEST(MocCMP0071) -endif() -if(QT_TEST_VERSION GREATER 4) - ADD_AUTOGEN_TEST(MocOsMacros) -endif() -ADD_AUTOGEN_TEST(UicInclude uicInclude) -ADD_AUTOGEN_TEST(UicInterface QtAutoUicInterface) ADD_AUTOGEN_TEST(ObjectLibrary someProgram) -if(APPLE AND (QT_TEST_VERSION GREATER 4)) - ADD_AUTOGEN_TEST(MacOsFW) -endif() ADD_AUTOGEN_TEST(Parallel parallel) ADD_AUTOGEN_TEST(Parallel1 parallel1) ADD_AUTOGEN_TEST(Parallel2 parallel2) ADD_AUTOGEN_TEST(Parallel3 parallel3) ADD_AUTOGEN_TEST(Parallel4 parallel4) ADD_AUTOGEN_TEST(ParallelAUTO parallelAUTO) +ADD_AUTOGEN_TEST(RccEmpty rccEmpty) +ADD_AUTOGEN_TEST(RccOffMocLibrary) +ADD_AUTOGEN_TEST(RccOnly rccOnly) +ADD_AUTOGEN_TEST(RccSkipSource) +ADD_AUTOGEN_TEST(RerunMocBasic) +ADD_AUTOGEN_TEST(RerunRccConfigChange) +ADD_AUTOGEN_TEST(RerunRccDepends) ADD_AUTOGEN_TEST(SameName sameName) ADD_AUTOGEN_TEST(StaticLibraryCycle slc) -# Rerun tests -ADD_AUTOGEN_TEST(RerunMocBasic) +ADD_AUTOGEN_TEST(UicInclude uicInclude) +ADD_AUTOGEN_TEST(UicInterface QtAutoUicInterface) +ADD_AUTOGEN_TEST(UicOnly uicOnly) +ADD_AUTOGEN_TEST(UicSkipSource) + +if(QT_TEST_ALLOW_QT_MACROS) + ADD_AUTOGEN_TEST(MocCMP0071) + ADD_AUTOGEN_TEST(MocIncludeRelaxed mocIncludeRelaxed) + ADD_AUTOGEN_TEST(MocIncludeStrict mocIncludeStrict) + ADD_AUTOGEN_TEST(MocSkipSource) +endif() + +# Qt5 only tests if(QT_TEST_VERSION GREATER 4) + ADD_AUTOGEN_TEST(MocMacroName mocMacroName) + ADD_AUTOGEN_TEST(MocOsMacros) ADD_AUTOGEN_TEST(RerunMocPlugin) + if(APPLE) + ADD_AUTOGEN_TEST(MacOsFW) + endif() endif() -ADD_AUTOGEN_TEST(RerunRccDepends) -ADD_AUTOGEN_TEST(RerunRccConfigChange) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=83bbfb1d53077176af86d637f713652e3ee01198 commit 83bbfb1d53077176af86d637f713652e3ee01198 Author: Sebastian Holtermann AuthorDate: Tue Nov 13 13:05:09 2018 +0100 Commit: Sebastian Holtermann CommitDate: Wed Nov 14 19:21:03 2018 +0100 Autogen: Add a definitions test to the MocOnly test diff --git a/Tests/QtAutogen/MocOnly/CMakeLists.txt b/Tests/QtAutogen/MocOnly/CMakeLists.txt index a37a2ae..5377728 100644 --- a/Tests/QtAutogen/MocOnly/CMakeLists.txt +++ b/Tests/QtAutogen/MocOnly/CMakeLists.txt @@ -13,3 +13,5 @@ add_executable(mocOnly ) set_property(TARGET mocOnly PROPERTY AUTOMOC ON) target_link_libraries(mocOnly ${QT_LIBRARIES}) +# Add compile definitions with unusual characters +target_compile_definitions(mocOnly PUBLIC "TOKEN=\"hello\;\"" ) diff --git a/Tests/QtAutogen/MocOnly/main.cpp b/Tests/QtAutogen/MocOnly/main.cpp index 1611f97..b83b806 100644 --- a/Tests/QtAutogen/MocOnly/main.cpp +++ b/Tests/QtAutogen/MocOnly/main.cpp @@ -2,6 +2,7 @@ #include "IncB.hpp" #include "StyleA.hpp" #include "StyleB.hpp" +#include int main(int argv, char** args) { @@ -10,5 +11,8 @@ int main(int argv, char** args) IncA incA; IncB incB; - return 0; + // Test the TOKEN definition passed on the command line + std::string token(TOKEN); + std::cout << "std::string(TOKEN): \"" << token << "\"\n"; + return (token == "hello;") ? 0 : -1; } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=01d5e5c460a2a9cb3962990f8ef278389254f30a commit 01d5e5c460a2a9cb3962990f8ef278389254f30a Author: Sebastian Holtermann AuthorDate: Tue Nov 13 11:47:15 2018 +0100 Commit: Sebastian Holtermann CommitDate: Wed Nov 14 19:21:03 2018 +0100 Autogen: Add and use cmQtAutoGenInitializer::InfoWriter class The new ``cmQtAutoGenInitializer::InfoWriter`` class provides an interface to write strings/vectors/sets/maps in CMake format into a file. Its use replaces various `cmJoin` calls that failed to address escaping of semicolons in list elements. Closes #18554 diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 793c0b2..e71feac 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -9,7 +9,6 @@ #include "cmCustomCommandLines.h" #include "cmDuration.h" #include "cmFilePathChecksum.h" -#include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" @@ -175,6 +174,103 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, return cycle; } +cmQtAutoGenInitializer::InfoWriter::InfoWriter(std::string const& filename) +{ + Ofs_.SetCopyIfDifferent(true); + Ofs_.Open(filename, false, true); +} + +template +std::string cmQtAutoGenInitializer::InfoWriter::ListJoin(IT it_begin, + IT it_end) +{ + std::string res; + for (IT it = it_begin; it != it_end; ++it) { + if (it != it_begin) { + res += ';'; + } + for (const char* c = it->c_str(); *c; ++c) { + if (*c == '"') { + // Escape the double quote to avoid ending the argument. + res += "\\\""; + } else if (*c == '$') { + // Escape the dollar to avoid expanding variables. + res += "\\$"; + } else if (*c == '\\') { + // Escape the backslash to avoid other escapes. + res += "\\\\"; + } else if (*c == ';') { + // Escape the semicolon to avoid list expansion. + res += "\\;"; + } else { + // Other characters will be parsed correctly. + res += *c; + } + } + } + return res; +} + +std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey( + const char* key, std::string const& config) +{ + std::string ckey = key; + ckey += '_'; + ckey += config; + return ckey; +} + +void cmQtAutoGenInitializer::InfoWriter::Write(const char* key, + std::string const& value) +{ + Ofs_ << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) + << ")\n"; +}; + +void cmQtAutoGenInitializer::InfoWriter::WriteUInt(const char* key, + unsigned int value) +{ + Ofs_ << "set(" << key << " " << value << ")\n"; +}; + +template +void cmQtAutoGenInitializer::InfoWriter::WriteStrings(const char* key, + C const& container) +{ + Ofs_ << "set(" << key << " \"" + << ListJoin(container.begin(), container.end()) << "\")\n"; +} + +void cmQtAutoGenInitializer::InfoWriter::WriteConfig( + const char* key, std::map const& map) +{ + for (auto const& item : map) { + Write(ConfigKey(key, item.first).c_str(), item.second); + } +}; + +template +void cmQtAutoGenInitializer::InfoWriter::WriteConfigStrings( + const char* key, std::map const& map) +{ + for (auto const& item : map) { + WriteStrings(ConfigKey(key, item.first).c_str(), item.second); + } +} + +void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists( + const char* key, std::vector> const& lists) +{ + std::vector seplist; + for (const std::vector& list : lists) { + std::string blist = "{"; + blist += ListJoin(list.begin(), list.end()); + blist += "}"; + seplist.push_back(std::move(blist)); + } + Write(key, cmJoin(seplist, cmQtAutoGen::ListSep)); +}; + cmQtAutoGenInitializer::cmQtAutoGenInitializer( cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target, IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled, @@ -395,14 +491,15 @@ bool cmQtAutoGenInitializer::InitMoc() { bool const appendImplicit = (this->QtVersion.Major == 5); auto GetIncludeDirs = - [this, localGen, appendImplicit](std::string const& cfg) -> std::string { + [this, localGen, + appendImplicit](std::string const& cfg) -> std::vector { // Get the include dirs for this target, without stripping the implicit // include dirs off, see // https://gitlab.kitware.com/cmake/cmake/issues/13667 std::vector dirs; localGen->GetIncludeDirectories(dirs, this->Target, "CXX", cfg, false, appendImplicit); - return cmJoin(dirs, ";"); + return dirs; }; // Default configuration include directories @@ -410,7 +507,7 @@ bool cmQtAutoGenInitializer::InitMoc() // Other configuration settings if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { - std::string dirs = GetIncludeDirs(cfg); + std::vector dirs = GetIncludeDirs(cfg); if (dirs != this->Moc.Includes) { this->Moc.ConfigIncludes[cfg] = std::move(dirs); } @@ -421,10 +518,10 @@ bool cmQtAutoGenInitializer::InitMoc() // Moc compile definitions { auto GetCompileDefinitions = - [this, localGen](std::string const& cfg) -> std::string { + [this, localGen](std::string const& cfg) -> std::set { std::set defines; localGen->GetTargetDefines(this->Target, cfg, "CXX", defines); - return cmJoin(defines, ";"); + return defines; }; // Default configuration defines @@ -432,7 +529,7 @@ bool cmQtAutoGenInitializer::InitMoc() // Other configuration defines if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { - std::string defines = GetCompileDefinitions(cfg); + std::set defines = GetCompileDefinitions(cfg); if (defines != this->Moc.Defines) { this->Moc.ConfigDefines[cfg] = std::move(defines); } @@ -466,10 +563,11 @@ bool cmQtAutoGenInitializer::InitUic() } // Uic target options { - auto UicGetOpts = [this](std::string const& cfg) -> std::string { + auto UicGetOpts = + [this](std::string const& cfg) -> std::vector { std::vector opts; this->Target->GetAutoUicOptions(opts, cfg); - return cmJoin(opts, ";"); + return opts; }; // Default settings @@ -478,7 +576,7 @@ bool cmQtAutoGenInitializer::InitUic() // Configuration specific settings if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { - std::string options = UicGetOpts(cfg); + std::vector options = UicGetOpts(cfg); if (options != this->Uic.Options) { this->Uic.ConfigOptions[cfg] = std::move(options); } @@ -1108,104 +1206,72 @@ bool cmQtAutoGenInitializer::SetupCustomTargets() bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - - cmGeneratedFileStream ofs; - ofs.SetCopyIfDifferent(true); - ofs.Open(this->AutogenTarget.InfoFile, false, true); + InfoWriter ofs(this->AutogenTarget.InfoFile); if (ofs) { // Utility lambdas - auto CWrite = [&ofs](const char* key, std::string const& value) { - ofs << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) - << ")\n"; - }; - auto CWriteUInt = [&ofs](const char* key, unsigned int value) { - ofs << "set(" << key << " " << value << ")\n"; - }; - auto CWriteList = [&CWrite](const char* key, - std::vector const& list) { - CWrite(key, cmJoin(list, ";")); - }; - auto CWriteNestedLists = - [&CWrite](const char* key, - std::vector> const& lists) { - std::vector seplist; - for (const std::vector& list : lists) { - std::string blist = "{"; - blist += cmJoin(list, ";"); - blist += "}"; - seplist.push_back(std::move(blist)); - } - CWrite(key, cmJoin(seplist, cmQtAutoGen::ListSep)); - }; - auto CWriteSet = [&CWrite](const char* key, - std::set const& list) { - CWrite(key, cmJoin(list, ";")); - }; - auto CWriteMap = [&ofs](const char* key, - std::map const& map) { - for (auto const& item : map) { - ofs << "set(" << key << "_" << item.first << " " - << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; - } - }; + cmMakefile* makefile = this->Target->Target->GetMakefile(); auto MfDef = [makefile](const char* key) { return makefile->GetSafeDefinition(key); }; - // Write - ofs << "# Meta\n"; - CWrite("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); - CWrite("AM_PARALLEL", this->AutogenTarget.Parallel); - CWrite("AM_VERBOSITY", this->Verbosity); - - ofs << "# Directories\n"; - CWrite("AM_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR")); - CWrite("AM_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR")); - CWrite("AM_CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR")); - CWrite("AM_CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR")); - CWrite("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", - MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")); - CWrite("AM_BUILD_DIR", this->Dir.Build); - CWrite("AM_INCLUDE_DIR", this->Dir.Include); - CWriteMap("AM_INCLUDE_DIR", this->Dir.ConfigInclude); - - ofs << "# Files\n"; - CWriteList("AM_SOURCES", this->AutogenTarget.Sources); - CWriteList("AM_HEADERS", this->AutogenTarget.Headers); - CWrite("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile); - CWriteMap("AM_SETTINGS_FILE", this->AutogenTarget.ConfigSettingsFile); - - ofs << "# Qt\n"; - CWriteUInt("AM_QT_VERSION_MAJOR", this->QtVersion.Major); - CWrite("AM_QT_MOC_EXECUTABLE", this->Moc.Executable); - CWrite("AM_QT_UIC_EXECUTABLE", this->Uic.Executable); - + // Write common settings + ofs.Write("# Meta\n"); + ofs.Write("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); + ofs.Write("AM_PARALLEL", this->AutogenTarget.Parallel); + ofs.Write("AM_VERBOSITY", this->Verbosity); + + ofs.Write("# Directories\n"); + ofs.Write("AM_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR")); + ofs.Write("AM_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR")); + ofs.Write("AM_CMAKE_CURRENT_SOURCE_DIR", + MfDef("CMAKE_CURRENT_SOURCE_DIR")); + ofs.Write("AM_CMAKE_CURRENT_BINARY_DIR", + MfDef("CMAKE_CURRENT_BINARY_DIR")); + ofs.Write("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", + MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")); + ofs.Write("AM_BUILD_DIR", this->Dir.Build); + ofs.Write("AM_INCLUDE_DIR", this->Dir.Include); + ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude); + + ofs.Write("# Files\n"); + ofs.WriteStrings("AM_SOURCES", this->AutogenTarget.Sources); + ofs.WriteStrings("AM_HEADERS", this->AutogenTarget.Headers); + ofs.Write("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile); + ofs.WriteConfig("AM_SETTINGS_FILE", + this->AutogenTarget.ConfigSettingsFile); + + ofs.Write("# Qt\n"); + ofs.WriteUInt("AM_QT_VERSION_MAJOR", this->QtVersion.Major); + ofs.Write("AM_QT_MOC_EXECUTABLE", this->Moc.Executable); + ofs.Write("AM_QT_UIC_EXECUTABLE", this->Uic.Executable); + + // Write moc settings if (this->Moc.Enabled) { - ofs << "# MOC settings\n"; - CWriteSet("AM_MOC_SKIP", this->Moc.Skip); - CWrite("AM_MOC_DEFINITIONS", this->Moc.Defines); - CWriteMap("AM_MOC_DEFINITIONS", this->Moc.ConfigDefines); - CWrite("AM_MOC_INCLUDES", this->Moc.Includes); - CWriteMap("AM_MOC_INCLUDES", this->Moc.ConfigIncludes); - CWrite("AM_MOC_OPTIONS", - this->Target->GetSafeProperty("AUTOMOC_MOC_OPTIONS")); - CWrite("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE")); - CWrite("AM_MOC_MACRO_NAMES", - this->Target->GetSafeProperty("AUTOMOC_MACRO_NAMES")); - CWrite("AM_MOC_DEPEND_FILTERS", - this->Target->GetSafeProperty("AUTOMOC_DEPEND_FILTERS")); - CWrite("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd); - } - + ofs.Write("# MOC settings\n"); + ofs.WriteStrings("AM_MOC_SKIP", this->Moc.Skip); + ofs.WriteStrings("AM_MOC_DEFINITIONS", this->Moc.Defines); + ofs.WriteConfigStrings("AM_MOC_DEFINITIONS", this->Moc.ConfigDefines); + ofs.WriteStrings("AM_MOC_INCLUDES", this->Moc.Includes); + ofs.WriteConfigStrings("AM_MOC_INCLUDES", this->Moc.ConfigIncludes); + ofs.Write("AM_MOC_OPTIONS", + this->Target->GetSafeProperty("AUTOMOC_MOC_OPTIONS")); + ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE")); + ofs.Write("AM_MOC_MACRO_NAMES", + this->Target->GetSafeProperty("AUTOMOC_MACRO_NAMES")); + ofs.Write("AM_MOC_DEPEND_FILTERS", + this->Target->GetSafeProperty("AUTOMOC_DEPEND_FILTERS")); + ofs.Write("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd); + } + + // Write uic settings if (this->Uic.Enabled) { - ofs << "# UIC settings\n"; - CWriteSet("AM_UIC_SKIP", this->Uic.Skip); - CWrite("AM_UIC_TARGET_OPTIONS", this->Uic.Options); - CWriteMap("AM_UIC_TARGET_OPTIONS", this->Uic.ConfigOptions); - CWriteList("AM_UIC_OPTIONS_FILES", this->Uic.FileFiles); - CWriteNestedLists("AM_UIC_OPTIONS_OPTIONS", this->Uic.FileOptions); - CWriteList("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths); + ofs.Write("# UIC settings\n"); + ofs.WriteStrings("AM_UIC_SKIP", this->Uic.Skip); + ofs.WriteStrings("AM_UIC_TARGET_OPTIONS", this->Uic.Options); + ofs.WriteConfigStrings("AM_UIC_TARGET_OPTIONS", this->Uic.ConfigOptions); + ofs.WriteStrings("AM_UIC_OPTIONS_FILES", this->Uic.FileFiles); + ofs.WriteNestedLists("AM_UIC_OPTIONS_OPTIONS", this->Uic.FileOptions); + ofs.WriteStrings("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths); } } else { std::string err = "AutoGen: Could not write file "; @@ -1220,47 +1286,33 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() bool cmQtAutoGenInitializer::SetupWriteRccInfo() { for (Qrc const& qrc : this->Rcc.Qrcs) { - cmGeneratedFileStream ofs; - ofs.SetCopyIfDifferent(true); - ofs.Open(qrc.InfoFile, false, true); + InfoWriter ofs(qrc.InfoFile); if (ofs) { - // Utility lambdas - auto CWrite = [&ofs](const char* key, std::string const& value) { - ofs << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) - << ")\n"; - }; - auto CWriteMap = [&ofs](const char* key, - std::map const& map) { - for (auto const& item : map) { - ofs << "set(" << key << "_" << item.first << " " - << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; - } - }; - // Write - ofs << "# Configurations\n"; - CWrite("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); - CWrite("ARCC_VERBOSITY", this->Verbosity); - ofs << "# Settings file\n"; - CWrite("ARCC_SETTINGS_FILE", qrc.SettingsFile); - CWriteMap("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile); - - ofs << "# Directories\n"; - CWrite("ARCC_BUILD_DIR", this->Dir.Build); - CWrite("ARCC_INCLUDE_DIR", this->Dir.Include); - CWriteMap("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude); - - ofs << "# Rcc executable\n"; - CWrite("ARCC_RCC_EXECUTABLE", this->Rcc.Executable); - CWrite("ARCC_RCC_LIST_OPTIONS", cmJoin(this->Rcc.ListOptions, ";")); - - ofs << "# Rcc job\n"; - CWrite("ARCC_LOCK_FILE", qrc.LockFile); - CWrite("ARCC_SOURCE", qrc.QrcFile); - CWrite("ARCC_OUTPUT_CHECKSUM", qrc.PathChecksum); - CWrite("ARCC_OUTPUT_NAME", cmSystemTools::GetFilenameName(qrc.RccFile)); - CWrite("ARCC_OPTIONS", cmJoin(qrc.Options, ";")); - CWrite("ARCC_INPUTS", cmJoin(qrc.Resources, ";")); + ofs.Write("# Configurations\n"); + ofs.Write("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); + ofs.Write("ARCC_VERBOSITY", this->Verbosity); + ofs.Write("# Settings file\n"); + ofs.Write("ARCC_SETTINGS_FILE", qrc.SettingsFile); + ofs.WriteConfig("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile); + + ofs.Write("# Directories\n"); + ofs.Write("ARCC_BUILD_DIR", this->Dir.Build); + ofs.Write("ARCC_INCLUDE_DIR", this->Dir.Include); + ofs.WriteConfig("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude); + + ofs.Write("# Rcc executable\n"); + ofs.Write("ARCC_RCC_EXECUTABLE", this->Rcc.Executable); + ofs.WriteStrings("ARCC_RCC_LIST_OPTIONS", this->Rcc.ListOptions); + + ofs.Write("# Rcc job\n"); + ofs.Write("ARCC_LOCK_FILE", qrc.LockFile); + ofs.Write("ARCC_SOURCE", qrc.QrcFile); + ofs.Write("ARCC_OUTPUT_CHECKSUM", qrc.PathChecksum); + ofs.Write("ARCC_OUTPUT_NAME", + cmSystemTools::GetFilenameName(qrc.RccFile)); + ofs.WriteStrings("ARCC_OPTIONS", qrc.Options); + ofs.WriteStrings("ARCC_INPUTS", qrc.Resources); } else { std::string err = "AutoRcc: Could not write file "; err += qrc.InfoFile; diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 53ad571..903ec85 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -4,9 +4,11 @@ #define cmQtAutoGenInitializer_h #include "cmConfigure.h" // IWYU pragma: keep +#include "cmGeneratedFileStream.h" #include "cmQtAutoGen.h" #include +#include #include #include #include @@ -44,6 +46,39 @@ public: std::vector Resources; }; + /// @brief Writes a CMake info file + class InfoWriter + { + public: + /// @brief Open the given file + InfoWriter(std::string const& filename); + + /// @return True if the file is open + operator bool() const { return static_cast(Ofs_); } + + void Write(const char* text) { Ofs_ << text; } + void Write(const char* key, std::string const& value); + void WriteUInt(const char* key, unsigned int value); + + template + void WriteStrings(const char* key, C const& container); + void WriteConfig(const char* key, + std::map const& map); + template + void WriteConfigStrings(const char* key, + std::map const& map); + void WriteNestedLists(const char* key, + std::vector> const& lists); + + private: + template + static std::string ListJoin(IT it_begin, IT it_end); + static std::string ConfigKey(const char* key, std::string const& config); + + private: + cmGeneratedFileStream Ofs_; + }; + public: static IntegerVersion GetQtVersion(cmGeneratorTarget const* target); @@ -129,10 +164,10 @@ private: std::string Executable; std::string PredefsCmd; std::set Skip; - std::string Includes; - std::map ConfigIncludes; - std::string Defines; - std::map ConfigDefines; + std::vector Includes; + std::map> ConfigIncludes; + std::set Defines; + std::map> ConfigDefines; std::string MocsCompilation; } Moc; @@ -143,8 +178,8 @@ private: std::string Executable; std::set Skip; std::vector SearchPaths; - std::string Options; - std::map ConfigOptions; + std::vector Options; + std::map> ConfigOptions; std::vector FileFiles; std::vector> FileOptions; } Uic; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ca355d92d827a26d626a241535fe710600eead0d commit ca355d92d827a26d626a241535fe710600eead0d Author: Brad King AuthorDate: Wed Nov 14 11:50:36 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 11:50:36 2018 -0500 Tests: Add option for custom RunCMake.XcodeProject timeout The test has many cases and can take a long time on busy machines. diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index b6b6519..2df15ee 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -335,6 +335,13 @@ endif() if(XCODE_VERSION) add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION}) + + # This test can take a very long time due to lots of combinations. + # Use a long default timeout and provide an option to customize it. + if(NOT DEFINED CMake_TEST_XcodeProject_TIMEOUT) + set(CMake_TEST_XcodeProject_TIMEOUT 2000) + endif() + set_property(TEST RunCMake.XcodeProject PROPERTY TIMEOUT ${CMake_TEST_XcodeProject_TIMEOUT}) endif() if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" ----------------------------------------------------------------------- Summary of changes: Help/command/function.rst | 3 + Help/command/macro.rst | 55 +- Help/dev/README.rst | 2 + Help/dev/documentation.rst | 538 +++++++++++++++++++ Help/dev/source.rst | 10 +- Help/manual/cmake-developer.7.rst | 586 +-------------------- Source/cmQtAutoGenInitializer.cxx | 330 +++++++----- Source/cmQtAutoGenInitializer.h | 47 +- Tests/Qt4Autogen/CMakeLists.txt | 2 +- Tests/Qt5Autogen/CMakeLists.txt | 2 +- Tests/QtAutogen/MocOnly/CMakeLists.txt | 2 + Tests/QtAutogen/MocOnly/main.cpp | 6 +- Tests/QtAutogen/{CommonTests.cmake => Tests.cmake} | 66 ++- Tests/RunCMake/CMakeLists.txt | 7 + 14 files changed, 873 insertions(+), 783 deletions(-) create mode 100644 Help/dev/documentation.rst rename Tests/QtAutogen/{CommonTests.cmake => Tests.cmake} (83%) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 15 10:43:09 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 15 Nov 2018 10:43:09 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-467-g1763f04 Message-ID: <20181115154309.5E1FE111BE3@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 1763f0428193cd6e28af4e49131516299acdf3b7 (commit) via 20aab1a4e7e42ac400a34143403a00c0ac0ec947 (commit) via 59fc717c252fb6613b35ff3a7d2cf01e91ab6a69 (commit) via 0f5c1b404b0f9cbe652cf306e9dca0c25c70876f (commit) via f3a381115fcd9046d754697a67b65a22e05554b5 (commit) via 0dbcc1afbf9c85ac938f533fd7756f0dec9bef70 (commit) via 6199637e9540627b03d9018ff53a14f005274607 (commit) from 64df9ef33a2f4eb9ef0cb17a2844308d9c7f7034 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1763f0428193cd6e28af4e49131516299acdf3b7 commit 1763f0428193cd6e28af4e49131516299acdf3b7 Merge: 20aab1a f3a3811 Author: Brad King AuthorDate: Thu Nov 15 15:40:56 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 10:41:07 2018 -0500 Merge topic 'test-WriteBasicConfigVersionFile' f3a381115f Tests: Simplify RunCMake.WriteBasicConfigVersionFile 0dbcc1afbf Tests: Factor out RunCMake.WriteBasicConfigVersionFile test Acked-by: Kitware Robot Merge-request: !2612 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=20aab1a4e7e42ac400a34143403a00c0ac0ec947 commit 20aab1a4e7e42ac400a34143403a00c0ac0ec947 Merge: 59fc717 6199637 Author: Brad King AuthorDate: Thu Nov 15 15:40:12 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 10:40:33 2018 -0500 Merge topic 'configure_file-canonical-deps' 6199637e95 configure_file: canonicalize input and output path in dependencies Acked-by: Kitware Robot Merge-request: !2586 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=59fc717c252fb6613b35ff3a7d2cf01e91ab6a69 commit 59fc717c252fb6613b35ff3a7d2cf01e91ab6a69 Merge: 64df9ef 0f5c1b4 Author: Brad King AuthorDate: Thu Nov 15 15:39:48 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 10:39:55 2018 -0500 Merge topic 'deprecate-findqt' 0f5c1b404b find_package(): Add policy to remove the FindQt module Acked-by: Kitware Robot Acked-by: noo mook Merge-request: !2554 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0f5c1b404b0f9cbe652cf306e9dca0c25c70876f commit 0f5c1b404b0f9cbe652cf306e9dca0c25c70876f Author: Kyle Edwards AuthorDate: Wed Oct 31 13:26:04 2018 -0400 Commit: Brad King CommitDate: Wed Nov 14 15:05:06 2018 -0500 find_package(): Add policy to remove the FindQt module Removing FindQt.cmake gives Qt upstream a path forward to export its own QtConfig.cmake files which can be found by find_package() without having to explicitly specify CONFIG. Projects that still want to use Qt3/4 can call find_package(Qt[34]), include(FindQt), or add FindQt.cmake to their CMAKE_MODULE_PATH. diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 95744df..68bbc12 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -225,7 +225,6 @@ They are normally called through the :command:`find_package` command. /module/FindPython3 /module/FindQt3 /module/FindQt4 - /module/FindQt /module/FindQuickTime /module/FindRTI /module/FindRuby @@ -283,6 +282,7 @@ Deprecated Find Modules /module/FindCUDA /module/FindPythonInterp /module/FindPythonLibs + /module/FindQt /module/FindwxWindows Legacy CPack Modules diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 98279ef..7c0fe6d 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14 .. toctree:: :maxdepth: 1 + CMP0084: The FindQt module does not exist for find_package(). CMP0083: Add PIE options when linking executable. CMP0082: Install rules from add_subdirectory() are interleaved with those in caller. diff --git a/Help/policy/CMP0084.rst b/Help/policy/CMP0084.rst new file mode 100644 index 0000000..713d295 --- /dev/null +++ b/Help/policy/CMP0084.rst @@ -0,0 +1,26 @@ +CMP0084 +------- + +The :module:`FindQt` module does not exist for :command:`find_package`. + +The existence of :module:`FindQt` means that for Qt upstream to provide +package config files that can be found by ``find_package(Qt)``, the consuming +project has to explicitly specify ``find_package(Qt CONFIG)``. Removing this +module gives Qt a path forward for exporting its own config files which can +easily be found by consuming projects. + +This policy pretends that CMake's internal :module:`FindQt` module does not +exist for :command:`find_package`. If a project really wants to use Qt 3 or 4, +it can call ``find_package(Qt[34])``, ``include(FindQt)``, or add +:module:`FindQt` to their :variable:`CMAKE_MODULE_PATH`. + +The ``OLD`` behavior of this policy is for :module:`FindQt` to exist for +:command:`find_package`. The ``NEW`` behavior is to pretend that it doesn't +exist for :command:`find_package`. + +This policy was introduced in CMake version 3.14. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/deprecate-findqt.rst b/Help/release/dev/deprecate-findqt.rst new file mode 100644 index 0000000..4171c65 --- /dev/null +++ b/Help/release/dev/deprecate-findqt.rst @@ -0,0 +1,8 @@ +deprecate-findqt +---------------- + +* The :module:`FindQt` module is no longer used by the :command:`find_package` + command as a find module. This allows the Qt Project upstream to optionally + provide its own ``QtConfig.cmake`` package configuration file and have + applications use it via ``find_package(Qt)`` rather than + ``find_package(Qt CONFIG)``. See policy :policy:`CMP0084`. diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake index 083d6a6..d6a0662 100644 --- a/Modules/FindQt.cmake +++ b/Modules/FindQt.cmake @@ -10,6 +10,9 @@ Searches for all installed versions of Qt3 or Qt4. This module cannot handle Qt5 or any later versions. For those, see :manual:`cmake-qt(7)`. +This module exists for the :command:`find_package` command only if +policy :policy:`CMP0084` is not set to ``NEW``. + This module should only be used if your project can work with multiple versions of Qt. If not, you should just directly use FindQt4 or FindQt3. If multiple versions of Qt are found on the machine, then @@ -34,6 +37,11 @@ then the FindQt3 or FindQt4 module is included. QT3_INSTALLED is set to TRUE if qt3 is found. #]=======================================================================] +if(_findqt_testing) + set(_findqt_included TRUE) + return() +endif() + # look for signs of qt3 installations file(GLOB GLOB_TEMP_VAR /usr/lib*/qt-3*/bin/qmake /usr/lib*/qt3*/bin/qmake) if(GLOB_TEMP_VAR) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 97c1d7d..bf928fc 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -111,6 +111,8 @@ cmFindPackageCommand::cmFindPackageCommand() this->SortOrder = None; this->SortDirection = Asc; this->AppendSearchPathGroups(); + + this->DeprecatedFindModules["Qt"] = cmPolicies::CMP0084; } void cmFindPackageCommand::AppendSearchPathGroups() @@ -653,8 +655,31 @@ bool cmFindPackageCommand::FindModule(bool& found) std::string module = "Find"; module += this->Name; module += ".cmake"; - std::string mfile = this->Makefile->GetModulesFile(module.c_str()); + bool system = false; + std::string mfile = this->Makefile->GetModulesFile(module.c_str(), system); if (!mfile.empty()) { + if (system) { + auto it = this->DeprecatedFindModules.find(this->Name); + if (it != this->DeprecatedFindModules.end()) { + cmPolicies::PolicyStatus status = + this->Makefile->GetPolicyStatus(it->second); + switch (status) { + case cmPolicies::WARN: { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(it->second) << "\n"; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + CM_FALLTHROUGH; + } + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + return true; + } + } + } + // Load the module we found, and set "_FIND_MODULE" to true // while inside it. found = true; diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 48f17ef..05bad49 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -4,6 +4,7 @@ #define cmFindPackageCommand_h #include "cmConfigure.h" // IWYU pragma: keep +#include "cmPolicies.h" #include "cm_kwiml.h" #include @@ -148,6 +149,8 @@ private: }; std::map OriginalDefs; + std::map DeprecatedFindModules; + std::string Name; std::string Variable; std::string Version; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 0d42fb0..790f6e0 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3500,7 +3500,8 @@ void cmMakefile::DisplayStatus(const char* message, float s) const cm->UpdateProgress(message, s); } -std::string cmMakefile::GetModulesFile(const char* filename) const +std::string cmMakefile::GetModulesFile(const char* filename, + bool& system) const { std::string result; @@ -3547,8 +3548,10 @@ std::string cmMakefile::GetModulesFile(const char* filename) const // Normally, prefer the files found in CMAKE_MODULE_PATH. Only when the file // from which we are being called is located itself in CMAKE_ROOT, then // prefer results from CMAKE_ROOT depending on the policy setting. + system = false; result = moduleInCMakeModulePath; if (result.empty()) { + system = true; result = moduleInCMakeRoot; } @@ -3571,11 +3574,13 @@ std::string cmMakefile::GetModulesFile(const char* filename) const CM_FALLTHROUGH; } case cmPolicies::OLD: + system = false; result = moduleInCMakeModulePath; break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: + system = true; result = moduleInCMakeRoot; break; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index d8176d9..aa94054 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -689,7 +689,13 @@ public: /** * Return a location of a file in cmake or custom modules directory */ - std::string GetModulesFile(const char* name) const; + std::string GetModulesFile(const char* name) const + { + bool system; + return this->GetModulesFile(name, system); + } + + std::string GetModulesFile(const char* name, bool& system) const; ///! Set/Get a property of this directory void SetProperty(const std::string& prop, const char* value); diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 52ef470..6b1314f 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -246,7 +246,10 @@ class cmMakefile; "in caller.", \ 3, 14, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0083, "Add PIE options when linking executable.", 3, 14, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0084, \ + "The FindQt module does not exist for find_package().", 3, 14, 0, \ + cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Tests/RunCMake/find_package/CMP0084-NEW-stderr.txt b/Tests/RunCMake/find_package/CMP0084-NEW-stderr.txt new file mode 100644 index 0000000..280ff8c --- /dev/null +++ b/Tests/RunCMake/find_package/CMP0084-NEW-stderr.txt @@ -0,0 +1,20 @@ +^CMake Warning at CMP0084-NEW\.cmake:[0-9]+ \(find_package\): + No "FindQt\.cmake" found in CMAKE_MODULE_PATH\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\) ++ +CMake Warning \(dev\) at CMP0084-NEW\.cmake:[0-9]+ \(find_package\): + FindQt\.cmake must either be part of this project itself, in this case + adjust CMAKE_MODULE_PATH so that it points to the correct location inside + its source tree\. + + Or it must be installed by a package which has already been found via + find_package\(\)\. In this case make sure that package has indeed been found + and adjust CMAKE_MODULE_PATH to contain the location where that package has + installed FindQt\.cmake\. This must be a location provided by that package\. + This error in general means that the buildsystem of this project is relying + on a Find-module without ensuring that it is actually available\. + +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/find_package/CMP0084-NEW.cmake b/Tests/RunCMake/find_package/CMP0084-NEW.cmake new file mode 100644 index 0000000..68fd6cf --- /dev/null +++ b/Tests/RunCMake/find_package/CMP0084-NEW.cmake @@ -0,0 +1,7 @@ +cmake_policy(SET CMP0084 NEW) +set(_findqt_testing TRUE) +find_package(Qt MODULE) + +if(_findqt_included) + message(FATAL_ERROR "FindQt.cmake erroneously included") +endif() diff --git a/Tests/RunCMake/find_package/CMP0084-OLD.cmake b/Tests/RunCMake/find_package/CMP0084-OLD.cmake new file mode 100644 index 0000000..7bd4726 --- /dev/null +++ b/Tests/RunCMake/find_package/CMP0084-OLD.cmake @@ -0,0 +1,7 @@ +cmake_policy(SET CMP0084 OLD) +set(_findqt_testing TRUE) +find_package(Qt MODULE) + +if(NOT _findqt_included) + message(FATAL_ERROR "FindQt.cmake not included") +endif() diff --git a/Tests/RunCMake/find_package/CMP0084-WARN-stderr.txt b/Tests/RunCMake/find_package/CMP0084-WARN-stderr.txt new file mode 100644 index 0000000..9ecebd3 --- /dev/null +++ b/Tests/RunCMake/find_package/CMP0084-WARN-stderr.txt @@ -0,0 +1,8 @@ +^CMake Warning \(dev\) at CMP0084-WARN\.cmake:[0-9]+ \(find_package\): + Policy CMP0084 is not set: The FindQt module does not exist for + find_package\(\)\. Run "cmake --help-policy CMP0084" for policy details\. Use + the cmake_policy command to set the policy and suppress this warning\. + +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/find_package/CMP0084-WARN.cmake b/Tests/RunCMake/find_package/CMP0084-WARN.cmake new file mode 100644 index 0000000..4ea22cb --- /dev/null +++ b/Tests/RunCMake/find_package/CMP0084-WARN.cmake @@ -0,0 +1,6 @@ +set(_findqt_testing TRUE) +find_package(Qt MODULE) + +if(NOT _findqt_included) + message(FATAL_ERROR "FindQt.cmake not included") +endif() diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index c068402..e9f3558 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -23,3 +23,6 @@ run_cmake(PolicyPop) run_cmake(SetFoundFALSE) run_cmake(WrongVersion) run_cmake(WrongVersionConfig) +run_cmake(CMP0084-OLD) +run_cmake(CMP0084-WARN) +run_cmake(CMP0084-NEW) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f3a381115fcd9046d754697a67b65a22e05554b5 commit f3a381115fcd9046d754697a67b65a22e05554b5 Author: Brad King AuthorDate: Wed Nov 14 10:45:53 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 10:46:39 2018 -0500 Tests: Simplify RunCMake.WriteBasicConfigVersionFile diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt b/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt deleted file mode 100644 index 9c558e3..0000000 --- a/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -. diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake index 6ff1550..4253652 100644 --- a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake @@ -72,31 +72,11 @@ function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE _version_installed _expected_compatible_SameMinorVersion _expected_compatible_ExactVersion) set(PACKAGE_FIND_VERSION ${_version_requested}) - if("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_3}") - set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_4}") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_3}") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" STREQUAL "") - set(PACKAGE_FIND_VERSION_MAJOR "") - set(PACKAGE_FIND_VERSION_MINOR "") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") + if("${PACKAGE_FIND_VERSION}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_8}") else() message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") endif() @@ -122,21 +102,21 @@ function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE _version_installed # Test "normal" version set(_expected_unsuitable 0) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ + message(STATUS "TEST write_basic_config_version_file(VERSION ${_version_installed} \ COMPATIBILITY ${_compat}) vs. ${_version_requested} \ (expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") test_write_basic_config_version_file_check("${_filename}") # test empty CMAKE_SIZEOF_VOID_P version: set(_expected_unsuitable 0) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ + message(STATUS "TEST write_basic_config_version_file(VERSION ${_version_installed} \ COMPATIBILITY ${_compat}) vs. ${_version_requested} (no CMAKE_SIZEOF_VOID_P) \ (expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") test_write_basic_config_version_file_check("${_filename_novoid}") # test different CMAKE_SIZEOF_VOID_P version: set(_expected_unsuitable 1) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ + message(STATUS "TEST write_basic_config_version_file(VERSION ${_version_installed} \ COMPATIBILITY ${_compat}) vs. ${_version_requested} (different CMAKE_SIZEOF_VOID_P) \ (expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") test_write_basic_config_version_file_check("${_filename_diffvoid}") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0dbcc1afbf9c85ac938f533fd7756f0dec9bef70 commit 0dbcc1afbf9c85ac938f533fd7756f0dec9bef70 Author: Brad King AuthorDate: Wed Nov 14 10:23:51 2018 -0500 Commit: Brad King CommitDate: Wed Nov 14 10:46:08 2018 -0500 Tests: Factor out RunCMake.WriteBasicConfigVersionFile test The `WriteBasicConfigVersionFile` section of the `FindPackageTest` is independent of the rest. diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 3fd5541..6a80df5 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -461,912 +461,6 @@ if(Relocatable_FOUND) endif() -#----------------------------------------------------------------------------- -# Test write_basic_config_version_file(). - -include(WriteBasicConfigVersionFile) - -set(_compatibilities AnyNewerVersion - SameMajorVersion - SameMinorVersion - ExactVersion) - -function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE_PREPARE _version_installed) - set(_same_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) - set(_no_CMAKE_SIZEOF_VOID_P "") - math(EXPR _diff_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P} + 1") - foreach(_compat ${_compatibilities}) - set(_pkg ${_compat}${_version_installed}) - string(REPLACE "." "" _pkg ${_pkg}) - set(_filename "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}ConfigVersion.cmake") - set(_filename_novoid "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}NoVoidConfigVersion.cmake") - set(_filename_diffvoid "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}DiffVoidConfigVersion.cmake") - - set(CMAKE_SIZEOF_VOID_P ${_same_CMAKE_SIZEOF_VOID_P}) - write_basic_config_version_file("${_filename}" - VERSION ${_version_installed} - COMPATIBILITY ${_compat}) - - # Test that an empty CMAKE_SIZEOF_VOID_P is accepted: - set(CMAKE_SIZEOF_VOID_P ${_no_CMAKE_SIZEOF_VOID_P}) - write_basic_config_version_file("${_filename_novoid}" - VERSION ${_version_installed} - COMPATIBILITY ${_compat}) - - # Test that a different CMAKE_SIZEOF_VOID_P results in - # PACKAGE_VERSION_UNSUITABLE - set(CMAKE_SIZEOF_VOID_P ${_diff_CMAKE_SIZEOF_VOID_P}) - write_basic_config_version_file("${_filename_diffvoid}" - VERSION ${_version_installed} - COMPATIBILITY ${_compat}) - endforeach() -endfunction() - -macro(TEST_WRITE_BASIC_CONFIG_VERSION_FILE_CHECK _filename) - include("${_filename}") - - if(_expected_compatible AND NOT PACKAGE_VERSION_COMPATIBLE) - message(SEND_ERROR "Did not find package with version ${_version_installed} (${_version_requested} was requested)!") - elseif(NOT _expected_compatible AND PACKAGE_VERSION_COMPATIBLE) - message(SEND_ERROR "Found package with version ${_version_installed}, but ${_version_requested} was requested!") - endif() - - if(${_expected_exact} AND NOT PACKAGE_VERSION_EXACT) - message(SEND_ERROR "PACKAGE_VERSION_EXACT not set, although it should be!") - elseif(NOT ${_expected_exact} AND PACKAGE_VERSION_EXACT) - message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be!") - endif() - - if(${_expected_unsuitable} AND NOT PACKAGE_VERSION_UNSUITABLE) - message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, although it should not be!") - elseif(NOT ${_expected_unsuitable} AND PACKAGE_VERSION_UNSUITABLE) - message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE not set, although it should be!") - endif() - - unset(PACKAGE_VERSION_COMPATIBLE) - unset(PACKAGE_VERSION_EXACT) - unset(PACKAGE_VERSION_UNSUITABLE) -endmacro() - -function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE _version_installed - _version_requested - _expected_compatible_AnyNewerVersion - _expected_compatible_SameMajorVersion - _expected_compatible_SameMinorVersion - _expected_compatible_ExactVersion) - set(PACKAGE_FIND_VERSION ${_version_requested}) - if("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_3}") - set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_4}") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_3}") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+)$") - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(PACKAGE_FIND_VERSION_MINOR "") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") - elseif("${PACKAGE_FIND_VERSION}" STREQUAL "") - set(PACKAGE_FIND_VERSION_MAJOR "") - set(PACKAGE_FIND_VERSION_MINOR "") - set(PACKAGE_FIND_VERSION_PATCH "") - set(PACKAGE_FIND_VERSION_TWEAK "") - else() - message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") - endif() - - if ("${_version_installed}" STREQUAL "${_version_requested}") - set(_expected_exact 1) - else() - set(_expected_exact 0) - endif() - - unset(PACKAGE_VERSION_COMPATIBLE) - unset(PACKAGE_VERSION_EXACT) - unset(PACKAGE_VERSION_UNSUITABLE) - - foreach(_compat ${_compatibilities}) - set(_pkg ${_compat}${_version_installed}) - string(REPLACE "." "" _pkg ${_pkg}) - set(_filename "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}ConfigVersion.cmake") - set(_filename_novoid "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}NoVoidConfigVersion.cmake") - set(_filename_diffvoid "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}DiffVoidConfigVersion.cmake") - - set(_expected_compatible ${_expected_compatible_${_compat}}) - - # Test "normal" version - set(_expected_unsuitable 0) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ -COMPATIBILITY ${_compat}) vs. ${_version_requested} \ -(expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") - test_write_basic_config_version_file_check("${_filename}") - - # test empty CMAKE_SIZEOF_VOID_P version: - set(_expected_unsuitable 0) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ -COMPATIBILITY ${_compat}) vs. ${_version_requested} (no CMAKE_SIZEOF_VOID_P) \ -(expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") - test_write_basic_config_version_file_check("${_filename_novoid}") - - # test different CMAKE_SIZEOF_VOID_P version: - set(_expected_unsuitable 1) - message("TEST write_basic_config_version_file(VERSION ${_version_installed} \ -COMPATIBILITY ${_compat}) vs. ${_version_requested} (different CMAKE_SIZEOF_VOID_P) \ -(expected compatible = ${_expected_compatible}, exact = ${_expected_exact}, unsuitable = ${_expected_unsuitable})") - test_write_basic_config_version_file_check("${_filename_diffvoid}") - - endforeach() -endfunction() - - -test_write_basic_config_version_file_prepare(4) -test_write_basic_config_version_file_prepare(4.5) -test_write_basic_config_version_file_prepare(4.5.6) -test_write_basic_config_version_file_prepare(4.5.6.7) - -# AnyNewerVersion -# | SameMajorVersion -# | | SameMinorVersion -# | | | ExactVersion -# | | | | -test_write_basic_config_version_file(4 0 1 0 0 0) # Request 0 -test_write_basic_config_version_file(4 2 1 0 0 0) # Request [older major] -test_write_basic_config_version_file(4 4 1 1 1 1) # Request [same major] -test_write_basic_config_version_file(4 9 0 0 0 0) # Request [newer major] - -test_write_basic_config_version_file(4 0.0 1 0 0 0) # Request 0.0 -test_write_basic_config_version_file(4 0.9 1 0 0 0) # Request 0.[newer minor] -test_write_basic_config_version_file(4 2.0 1 0 0 0) # Request [older major].0 -test_write_basic_config_version_file(4 2.9 1 0 0 0) # Request [older major].[newer minor] -test_write_basic_config_version_file(4 4.0 1 1 0 0) # Request [same major].0 -test_write_basic_config_version_file(4 4.9 0 0 0 0) # Request [same major].[newer minor] -test_write_basic_config_version_file(4 9.0 0 0 0 0) # Request [newer major].0 -test_write_basic_config_version_file(4 9.9 0 0 0 0) # Request [newer major].[newer minor] - -test_write_basic_config_version_file(4 0.0.0 1 0 0 0) # Request 0.0.0 -test_write_basic_config_version_file(4 0.0.9 1 0 0 0) # Request 0.0.[newer patch] -test_write_basic_config_version_file(4 0.9.0 1 0 0 0) # Request 0.[newer minor].0 -test_write_basic_config_version_file(4 0.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch] -test_write_basic_config_version_file(4 2.0.0 1 0 0 0) # Request [older major].0.0 -test_write_basic_config_version_file(4 2.0.9 1 0 0 0) # Request [older major].0.[newer patch] -test_write_basic_config_version_file(4 2.9.0 1 0 0 0) # Request [older major].[newer minor].0 -test_write_basic_config_version_file(4 2.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch] -test_write_basic_config_version_file(4 4.0.0 1 1 0 0) # Request [same major].0.0 -test_write_basic_config_version_file(4 4.0.9 0 0 0 0) # Request [same major].0.[newer patch] -test_write_basic_config_version_file(4 4.9.0 0 0 0 0) # Request [same major].[newer minor].0 -test_write_basic_config_version_file(4 4.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch] -test_write_basic_config_version_file(4 9.0.0 0 0 0 0) # Request [newer major].0.0 -test_write_basic_config_version_file(4 9.0.9 0 0 0 0) # Request [newer major].0.[newer patch] -test_write_basic_config_version_file(4 9.9.0 0 0 0 0) # Request [newer major].[newer minor].0 -test_write_basic_config_version_file(4 9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch] - -test_write_basic_config_version_file(4 0.0.0.0 1 0 0 0) # Request 0.0.0.0 -test_write_basic_config_version_file(4 0.0.0.9 1 0 0 0) # Request 0.0.0.[newer tweak] -test_write_basic_config_version_file(4 0.0.9.0 1 0 0 0) # Request 0.0.[newer patch].0 -test_write_basic_config_version_file(4 0.0.9.9 1 0 0 0) # Request 0.0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4 0.9.0.0 1 0 0 0) # Request 0.[newer minor].0.0 -test_write_basic_config_version_file(4 0.9.0.9 1 0 0 0) # Request 0.[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4 0.9.9.0 1 0 0 0) # Request 0.[newer minor].[newer patch].0 -test_write_basic_config_version_file(4 0.9.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4 2.0.0.0 1 0 0 0) # Request [older major].0.0.0 -test_write_basic_config_version_file(4 2.0.0.9 1 0 0 0) # Request [older major].0.0.[newer tweak] -test_write_basic_config_version_file(4 2.0.9.0 1 0 0 0) # Request [older major].0.[newer patch].0 -test_write_basic_config_version_file(4 2.0.9.9 1 0 0 0) # Request [older major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4 2.9.0.0 1 0 0 0) # Request [older major].[newer minor].0.0 -test_write_basic_config_version_file(4 2.9.0.9 1 0 0 0) # Request [older major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4 2.9.9.0 1 0 0 0) # Request [older major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4 2.9.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4 4.0.0.0 1 1 0 0) # Request [same major].0.0.0 -test_write_basic_config_version_file(4 4.0.0.9 0 0 0 0) # Request [same major].0.0.[newer tweak] -test_write_basic_config_version_file(4 4.0.9.0 0 0 0 0) # Request [same major].0.[newer patch].0 -test_write_basic_config_version_file(4 4.0.9.9 0 0 0 0) # Request [same major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4 4.9.0.0 0 0 0 0) # Request [same major].[newer minor].0.0 -test_write_basic_config_version_file(4 4.9.0.9 0 0 0 0) # Request [same major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4 4.9.9.0 0 0 0 0) # Request [same major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4 4.9.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4 9.0.0.0 0 0 0 0) # Request [newer major].0.0.0 -test_write_basic_config_version_file(4 9.0.0.9 0 0 0 0) # Request [newer major].0.0.[newer tweak] -test_write_basic_config_version_file(4 9.0.9.0 0 0 0 0) # Request [newer major].0.[newer patch].0 -test_write_basic_config_version_file(4 9.0.9.9 0 0 0 0) # Request [newer major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4 9.9.0.0 0 0 0 0) # Request [newer major].[newer minor].0.0 -test_write_basic_config_version_file(4 9.9.0.9 0 0 0 0) # Request [newer major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4 9.9.9.0 0 0 0 0) # Request [newer major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] - - - -test_write_basic_config_version_file(4.5 0 1 0 0 0) # Request 0 -test_write_basic_config_version_file(4.5 2 1 0 0 0) # Request [older major] -test_write_basic_config_version_file(4.5 4 1 1 0 0) # Request [same major] -test_write_basic_config_version_file(4.5 9 0 0 0 0) # Request [newer major] - -test_write_basic_config_version_file(4.5 0.0 1 0 0 0) # Request 0.0 -test_write_basic_config_version_file(4.5 0.2 1 0 0 0) # Request 0.[older minor] -test_write_basic_config_version_file(4.5 0.5 1 0 0 0) # Request 0.[same minor] -test_write_basic_config_version_file(4.5 0.9 1 0 0 0) # Request 0.[newer minor] -test_write_basic_config_version_file(4.5 2.0 1 0 0 0) # Request [older major].0 -test_write_basic_config_version_file(4.5 2.2 1 0 0 0) # Request [older major].[older minor] -test_write_basic_config_version_file(4.5 2.5 1 0 0 0) # Request [older major].[same minor] -test_write_basic_config_version_file(4.5 2.9 1 0 0 0) # Request [older major].[newer minor] -test_write_basic_config_version_file(4.5 4.0 1 1 0 0) # Request [same major].0 -test_write_basic_config_version_file(4.5 4.2 1 1 0 0) # Request [same major].[older minor] -test_write_basic_config_version_file(4.5 4.5 1 1 1 1) # Request [same major].[same minor] -test_write_basic_config_version_file(4.5 4.9 0 0 0 0) # Request [same major].[newer minor] -test_write_basic_config_version_file(4.5 9.0 0 0 0 0) # Request [newer major].0 -test_write_basic_config_version_file(4.5 9.1 0 0 0 0) # Request [newer major].[older minor] -test_write_basic_config_version_file(4.5 9.5 0 0 0 0) # Request [newer major].[same minor] -test_write_basic_config_version_file(4.5 9.9 0 0 0 0) # Request [newer major].[newer minor] - -test_write_basic_config_version_file(4.5 0.0.0 1 0 0 0) # Request 0.0.0 -test_write_basic_config_version_file(4.5 0.0.9 1 0 0 0) # Request 0.0.[newer patch] -test_write_basic_config_version_file(4.5 0.2.0 1 0 0 0) # Request 0.[older minor].0 -test_write_basic_config_version_file(4.5 0.2.9 1 0 0 0) # Request 0.[older minor].[newer patch] -test_write_basic_config_version_file(4.5 0.5.0 1 0 0 0) # Request 0.[same minor].0 -test_write_basic_config_version_file(4.5 0.5.9 1 0 0 0) # Request 0.[same minor].[newer patch] -test_write_basic_config_version_file(4.5 0.9.0 1 0 0 0) # Request 0.[newer minor].0 -test_write_basic_config_version_file(4.5 0.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch] -test_write_basic_config_version_file(4.5 2.0.0 1 0 0 0) # Request [older major].0.0 -test_write_basic_config_version_file(4.5 2.0.9 1 0 0 0) # Request [older major].0.[newer patch] -test_write_basic_config_version_file(4.5 2.2.0 1 0 0 0) # Request [older major].[older minor].0 -test_write_basic_config_version_file(4.5 2.2.9 1 0 0 0) # Request [older major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5 2.5.0 1 0 0 0) # Request [older major].[same minor].0 -test_write_basic_config_version_file(4.5 2.5.9 1 0 0 0) # Request [older major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5 2.9.0 1 0 0 0) # Request [older major].[newer minor].0 -test_write_basic_config_version_file(4.5 2.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5 4.0.0 1 1 0 0) # Request [same major].0.0 -test_write_basic_config_version_file(4.5 4.0.9 1 1 0 0) # Request [same major].0.[newer patch] -test_write_basic_config_version_file(4.5 4.2.0 1 1 0 0) # Request [same major].[older minor].0 -test_write_basic_config_version_file(4.5 4.2.9 1 1 0 0) # Request [same major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5 4.5.0 1 1 1 0) # Request [same major].[same minor].0 -test_write_basic_config_version_file(4.5 4.5.9 0 0 0 0) # Request [same major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5 4.9.0 0 0 0 0) # Request [same major].[newer minor].0 -test_write_basic_config_version_file(4.5 4.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5 9.0.0 0 0 0 0) # Request [newer major].0.0 -test_write_basic_config_version_file(4.5 9.0.9 0 0 0 0) # Request [newer major].0.[newer patch] -test_write_basic_config_version_file(4.5 9.2.0 0 0 0 0) # Request [newer major].[older minor].0 -test_write_basic_config_version_file(4.5 9.2.9 0 0 0 0) # Request [newer major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5 9.5.0 0 0 0 0) # Request [newer major].[same minor].0 -test_write_basic_config_version_file(4.5 9.5.9 0 0 0 0) # Request [newer major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5 9.9.0 0 0 0 0) # Request [newer major].[newer minor].0 -test_write_basic_config_version_file(4.5 9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch] - -test_write_basic_config_version_file(4.5 0.0.0.0 1 0 0 0) # Request 0.0.0.0 -test_write_basic_config_version_file(4.5 0.0.0.9 1 0 0 0) # Request 0.0.0.[newer tweak] -test_write_basic_config_version_file(4.5 0.0.9.0 1 0 0 0) # Request 0.0.[newer patch].0 -test_write_basic_config_version_file(4.5 0.0.9.9 1 0 0 0) # Request 0.0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 0.2.0.0 1 0 0 0) # Request 0.[older minor].0.0 -test_write_basic_config_version_file(4.5 0.2.0.9 1 0 0 0) # Request 0.[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 0.2.9.0 1 0 0 0) # Request 0.[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5 0.2.9.9 1 0 0 0) # Request 0.[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 0.5.0.0 1 0 0 0) # Request 0.[same minor].0.0 -test_write_basic_config_version_file(4.5 0.5.0.9 1 0 0 0) # Request 0.[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 0.5.9.0 1 0 0 0) # Request 0.[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5 0.5.9.9 1 0 0 0) # Request 0.[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 0.9.0.0 1 0 0 0) # Request 0.[newer minor].0.0 -test_write_basic_config_version_file(4.5 0.9.0.9 1 0 0 0) # Request 0.[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 0.9.9.0 1 0 0 0) # Request 0.[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5 0.9.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 2.0.0.0 1 0 0 0) # Request [older major].0.0.0 -test_write_basic_config_version_file(4.5 2.0.0.9 1 0 0 0) # Request [older major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5 2.0.9.0 1 0 0 0) # Request [older major].0.[newer patch].0 -test_write_basic_config_version_file(4.5 2.0.9.9 1 0 0 0) # Request [older major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 2.2.0.0 1 0 0 0) # Request [older major].[older minor].0.0 -test_write_basic_config_version_file(4.5 2.2.0.9 1 0 0 0) # Request [older major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 2.2.9.0 1 0 0 0) # Request [older major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5 2.2.9.9 1 0 0 0) # Request [older major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 2.5.0.0 1 0 0 0) # Request [older major].[same minor].0.0 -test_write_basic_config_version_file(4.5 2.5.0.9 1 0 0 0) # Request [older major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 2.5.9.0 1 0 0 0) # Request [older major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5 2.5.9.9 1 0 0 0) # Request [older major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 2.9.0.0 1 0 0 0) # Request [older major].[newer minor].0.0 -test_write_basic_config_version_file(4.5 2.9.0.9 1 0 0 0) # Request [older major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 2.9.9.0 1 0 0 0) # Request [older major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5 2.9.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 4.0.0.0 1 1 0 0) # Request [same major].0.0.0 -test_write_basic_config_version_file(4.5 4.0.0.9 1 1 0 0) # Request [same major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5 4.0.9.0 1 1 0 0) # Request [same major].0.[newer patch].0 -test_write_basic_config_version_file(4.5 4.0.9.9 1 1 0 0) # Request [same major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 4.2.0.0 1 1 0 0) # Request [same major].[older minor].0.0 -test_write_basic_config_version_file(4.5 4.2.0.9 1 1 0 0) # Request [same major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 4.2.9.0 1 1 0 0) # Request [same major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5 4.2.9.9 1 1 0 0) # Request [same major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 4.5.0.0 1 1 1 0) # Request [same major].[same minor].0.0 -test_write_basic_config_version_file(4.5 4.5.0.9 0 0 0 0) # Request [same major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 4.5.9.0 0 0 0 0) # Request [same major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5 4.5.9.9 0 0 0 0) # Request [same major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 4.9.0.0 0 0 0 0) # Request [same major].[newer minor].0.0 -test_write_basic_config_version_file(4.5 4.9.0.9 0 0 0 0) # Request [same major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 4.9.9.0 0 0 0 0) # Request [same major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5 4.9.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 9.0.0.0 0 0 0 0) # Request [newer major].0.0.0 -test_write_basic_config_version_file(4.5 9.0.0.9 0 0 0 0) # Request [newer major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5 9.0.9.0 0 0 0 0) # Request [newer major].0.[newer patch].0 -test_write_basic_config_version_file(4.5 9.0.9.9 0 0 0 0) # Request [newer major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 9.2.0.0 0 0 0 0) # Request [newer major].[older minor].0.0 -test_write_basic_config_version_file(4.5 9.2.0.9 0 0 0 0) # Request [newer major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 9.2.9.0 0 0 0 0) # Request [newer major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5 9.2.9.9 0 0 0 0) # Request [newer major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 9.5.0.0 0 0 0 0) # Request [newer major].[same minor].0.0 -test_write_basic_config_version_file(4.5 9.5.0.9 0 0 0 0) # Request [newer major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 9.5.9.0 0 0 0 0) # Request [newer major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5 9.5.9.9 0 0 0 0) # Request [newer major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5 9.9.0.0 0 0 0 0) # Request [newer major].[newer minor].0.0 -test_write_basic_config_version_file(4.5 9.9.0.9 0 0 0 0) # Request [newer major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5 9.9.9.0 0 0 0 0) # Request [newer major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] - - -test_write_basic_config_version_file(4.5.6 0 1 0 0 0) # Request 0 -test_write_basic_config_version_file(4.5.6 2 1 0 0 0) # Request [older major] -test_write_basic_config_version_file(4.5.6 4 1 1 0 0) # Request [same major] -test_write_basic_config_version_file(4.5.6 9 0 0 0 0) # Request [newer major] - -test_write_basic_config_version_file(4.5.6 0.0 1 0 0 0) # Request 0.0 -test_write_basic_config_version_file(4.5.6 0.2 1 0 0 0) # Request 0.[older minor] -test_write_basic_config_version_file(4.5.6 0.5 1 0 0 0) # Request 0.[same minor] -test_write_basic_config_version_file(4.5.6 0.9 1 0 0 0) # Request 0.[newer minor] -test_write_basic_config_version_file(4.5.6 2.0 1 0 0 0) # Request [older major].0 -test_write_basic_config_version_file(4.5.6 2.2 1 0 0 0) # Request [older major].[older minor] -test_write_basic_config_version_file(4.5.6 2.5 1 0 0 0) # Request [older major].[same minor] -test_write_basic_config_version_file(4.5.6 2.9 1 0 0 0) # Request [older major].[newer minor] -test_write_basic_config_version_file(4.5.6 4.0 1 1 0 0) # Request [same major].0 -test_write_basic_config_version_file(4.5.6 4.2 1 1 0 0) # Request [same major].[older minor] -test_write_basic_config_version_file(4.5.6 4.5 1 1 1 0) # Request [same major].[same minor] -test_write_basic_config_version_file(4.5.6 4.9 0 0 0 0) # Request [same major].[newer minor] -test_write_basic_config_version_file(4.5.6 9.0 0 0 0 0) # Request [newer major].0 -test_write_basic_config_version_file(4.5.6 9.1 0 0 0 0) # Request [newer major].[older minor] -test_write_basic_config_version_file(4.5.6 9.5 0 0 0 0) # Request [newer major].[same minor] -test_write_basic_config_version_file(4.5.6 9.9 0 0 0 0) # Request [newer major].[newer minor] - -test_write_basic_config_version_file(4.5.6 0.0.0 1 0 0 0) # Request 0.0.0 -test_write_basic_config_version_file(4.5.6 0.0.2 1 0 0 0) # Request 0.0.[older patch] -test_write_basic_config_version_file(4.5.6 0.0.6 1 0 0 0) # Request 0.0.[same patch] -test_write_basic_config_version_file(4.5.6 0.0.9 1 0 0 0) # Request 0.0.[newer patch] -test_write_basic_config_version_file(4.5.6 0.2.0 1 0 0 0) # Request 0.[older minor].0 -test_write_basic_config_version_file(4.5.6 0.2.2 1 0 0 0) # Request 0.[older minor].[older patch] -test_write_basic_config_version_file(4.5.6 0.2.6 1 0 0 0) # Request 0.[older minor].[same patch] -test_write_basic_config_version_file(4.5.6 0.2.9 1 0 0 0) # Request 0.[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6 0.5.0 1 0 0 0) # Request 0.[same minor].0 -test_write_basic_config_version_file(4.5.6 0.5.2 1 0 0 0) # Request 0.[same minor].[older patch] -test_write_basic_config_version_file(4.5.6 0.5.6 1 0 0 0) # Request 0.[same minor].[same patch] -test_write_basic_config_version_file(4.5.6 0.5.9 1 0 0 0) # Request 0.[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6 0.9.0 1 0 0 0) # Request 0.[newer minor].0 -test_write_basic_config_version_file(4.5.6 0.9.2 1 0 0 0) # Request 0.[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6 0.9.6 1 0 0 0) # Request 0.[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6 0.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6 2.0.0 1 0 0 0) # Request [older major].0.0 -test_write_basic_config_version_file(4.5.6 2.0.2 1 0 0 0) # Request [older major].0.[older patch] -test_write_basic_config_version_file(4.5.6 2.0.6 1 0 0 0) # Request [older major].0.[same patch] -test_write_basic_config_version_file(4.5.6 2.0.9 1 0 0 0) # Request [older major].0.[newer patch] -test_write_basic_config_version_file(4.5.6 2.2.0 1 0 0 0) # Request [older major].[older minor].0 -test_write_basic_config_version_file(4.5.6 2.2.2 1 0 0 0) # Request [older major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6 2.2.6 1 0 0 0) # Request [older major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6 2.2.9 1 0 0 0) # Request [older major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6 2.5.0 1 0 0 0) # Request [older major].[same minor].0 -test_write_basic_config_version_file(4.5.6 2.5.2 1 0 0 0) # Request [older major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6 2.5.6 1 0 0 0) # Request [older major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6 2.5.9 1 0 0 0) # Request [older major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6 2.9.0 1 0 0 0) # Request [older major].[newer minor].0 -test_write_basic_config_version_file(4.5.6 2.9.2 1 0 0 0) # Request [older major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6 2.9.6 1 0 0 0) # Request [older major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6 2.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6 4.0.0 1 1 0 0) # Request [same major].0.0 -test_write_basic_config_version_file(4.5.6 4.0.2 1 1 0 0) # Request [same major].0.[older patch] -test_write_basic_config_version_file(4.5.6 4.0.6 1 1 0 0) # Request [same major].0.[same patch] -test_write_basic_config_version_file(4.5.6 4.0.9 1 1 0 0) # Request [same major].0.[newer patch] -test_write_basic_config_version_file(4.5.6 4.2.0 1 1 0 0) # Request [same major].[older minor].0 -test_write_basic_config_version_file(4.5.6 4.2.2 1 1 0 0) # Request [same major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6 4.2.6 1 1 0 0) # Request [same major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6 4.2.9 1 1 0 0) # Request [same major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6 4.5.0 1 1 1 0) # Request [same major].[same minor].0 -test_write_basic_config_version_file(4.5.6 4.5.2 1 1 1 0) # Request [same major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6 4.5.6 1 1 1 1) # Request [same major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6 4.5.9 0 0 0 0) # Request [same major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6 4.9.0 0 0 0 0) # Request [same major].[newer minor].0 -test_write_basic_config_version_file(4.5.6 4.9.2 0 0 0 0) # Request [same major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6 4.9.6 0 0 0 0) # Request [same major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6 4.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6 9.0.0 0 0 0 0) # Request [newer major].0.0 -test_write_basic_config_version_file(4.5.6 9.0.2 0 0 0 0) # Request [newer major].0.[older patch] -test_write_basic_config_version_file(4.5.6 9.0.6 0 0 0 0) # Request [newer major].0.[same patch] -test_write_basic_config_version_file(4.5.6 9.0.9 0 0 0 0) # Request [newer major].0.[newer patch] -test_write_basic_config_version_file(4.5.6 9.2.0 0 0 0 0) # Request [newer major].[older minor].0 -test_write_basic_config_version_file(4.5.6 9.2.2 0 0 0 0) # Request [newer major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6 9.2.6 0 0 0 0) # Request [newer major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6 9.2.9 0 0 0 0) # Request [newer major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6 9.5.0 0 0 0 0) # Request [newer major].[same minor].0 -test_write_basic_config_version_file(4.5.6 9.5.2 0 0 0 0) # Request [newer major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6 9.5.6 0 0 0 0) # Request [newer major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6 9.5.9 0 0 0 0) # Request [newer major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6 9.9.0 0 0 0 0) # Request [newer major].[newer minor].0 -test_write_basic_config_version_file(4.5.6 9.9.2 0 0 0 0) # Request [newer major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6 9.9.6 0 0 0 0) # Request [newer major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6 9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch] - -test_write_basic_config_version_file(4.5.6 0.0.0.0 1 0 0 0) # Request 0.0.0.0 -test_write_basic_config_version_file(4.5.6 0.0.0.9 1 0 0 0) # Request 0.0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6 0.0.2.0 1 0 0 0) # Request 0.0.[older patch].0 -test_write_basic_config_version_file(4.5.6 0.0.2.9 1 0 0 0) # Request 0.0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.0.6.0 1 0 0 0) # Request 0.0.[same patch].0 -test_write_basic_config_version_file(4.5.6 0.0.6.9 1 0 0 0) # Request 0.0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.0.9.0 1 0 0 0) # Request 0.0.[newer patch].0 -test_write_basic_config_version_file(4.5.6 0.0.9.9 1 0 0 0) # Request 0.0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.2.0.0 1 0 0 0) # Request 0.[older minor].0.0 -test_write_basic_config_version_file(4.5.6 0.2.0.9 1 0 0 0) # Request 0.[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 0.2.2.0 1 0 0 0) # Request 0.[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 0.2.2.9 1 0 0 0) # Request 0.[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.2.6.0 1 0 0 0) # Request 0.[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 0.2.6.9 1 0 0 0) # Request 0.[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.2.9.0 1 0 0 0) # Request 0.[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 0.2.9.9 1 0 0 0) # Request 0.[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.5.0.0 1 0 0 0) # Request 0.[same minor].0.0 -test_write_basic_config_version_file(4.5.6 0.5.0.9 1 0 0 0) # Request 0.[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 0.5.2.0 1 0 0 0) # Request 0.[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 0.5.2.9 1 0 0 0) # Request 0.[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.5.6.0 1 0 0 0) # Request 0.[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 0.5.6.9 1 0 0 0) # Request 0.[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.5.9.0 1 0 0 0) # Request 0.[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 0.5.9.9 1 0 0 0) # Request 0.[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.9.0.0 1 0 0 0) # Request 0.[newer minor].0.0 -test_write_basic_config_version_file(4.5.6 0.9.0.9 1 0 0 0) # Request 0.[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 0.9.2.0 1 0 0 0) # Request 0.[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 0.9.2.9 1 0 0 0) # Request 0.[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.9.6.0 1 0 0 0) # Request 0.[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 0.9.6.9 1 0 0 0) # Request 0.[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 0.9.9.0 1 0 0 0) # Request 0.[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 0.9.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.0.0.0 1 0 0 0) # Request [older major].0.0.0 -test_write_basic_config_version_file(4.5.6 2.0.0.9 1 0 0 0) # Request [older major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6 2.0.2.0 1 0 0 0) # Request [older major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6 2.0.2.9 1 0 0 0) # Request [older major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.0.6.0 1 0 0 0) # Request [older major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6 2.0.6.9 1 0 0 0) # Request [older major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.0.9.0 1 0 0 0) # Request [older major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6 2.0.9.9 1 0 0 0) # Request [older major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.2.0.0 1 0 0 0) # Request [older major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6 2.2.0.9 1 0 0 0) # Request [older major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 2.2.2.0 1 0 0 0) # Request [older major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 2.2.2.9 1 0 0 0) # Request [older major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.2.6.0 1 0 0 0) # Request [older major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 2.2.6.9 1 0 0 0) # Request [older major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.2.9.0 1 0 0 0) # Request [older major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 2.2.9.9 1 0 0 0) # Request [older major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.5.0.0 1 0 0 0) # Request [older major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6 2.5.0.9 1 0 0 0) # Request [older major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 2.5.2.0 1 0 0 0) # Request [older major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 2.5.2.9 1 0 0 0) # Request [older major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.5.6.0 1 0 0 0) # Request [older major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 2.5.6.9 1 0 0 0) # Request [older major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.5.9.0 1 0 0 0) # Request [older major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 2.5.9.9 1 0 0 0) # Request [older major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.9.0.0 1 0 0 0) # Request [older major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6 2.9.0.9 1 0 0 0) # Request [older major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 2.9.2.0 1 0 0 0) # Request [older major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 2.9.2.9 1 0 0 0) # Request [older major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.9.6.0 1 0 0 0) # Request [older major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 2.9.6.9 1 0 0 0) # Request [older major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 2.9.9.0 1 0 0 0) # Request [older major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 2.9.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.0.0.0 1 1 0 0) # Request [same major].0.0.0 -test_write_basic_config_version_file(4.5.6 4.0.0.9 1 1 0 0) # Request [same major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6 4.0.2.0 1 1 0 0) # Request [same major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6 4.0.2.9 1 1 0 0) # Request [same major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.0.6.0 1 1 0 0) # Request [same major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6 4.0.6.9 1 1 0 0) # Request [same major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.0.9.0 1 1 0 0) # Request [same major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6 4.0.9.9 1 1 0 0) # Request [same major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.2.0.0 1 1 0 0) # Request [same major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6 4.2.0.9 1 1 0 0) # Request [same major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 4.2.2.0 1 1 0 0) # Request [same major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 4.2.2.9 1 1 0 0) # Request [same major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.2.6.0 1 1 0 0) # Request [same major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 4.2.6.9 1 1 0 0) # Request [same major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.2.9.0 1 1 0 0) # Request [same major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 4.2.9.9 1 1 0 0) # Request [same major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.5.0.0 1 1 1 0) # Request [same major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6 4.5.0.9 1 1 1 0) # Request [same major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 4.5.2.0 1 1 1 0) # Request [same major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 4.5.2.9 1 1 1 0) # Request [same major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.5.6.0 1 1 1 1) # Request [same major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 4.5.6.9 0 0 0 1) # Request [same major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.5.9.0 0 0 0 0) # Request [same major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 4.5.9.9 0 0 0 0) # Request [same major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.9.0.0 0 0 0 0) # Request [same major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6 4.9.0.9 0 0 0 0) # Request [same major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 4.9.2.0 0 0 0 0) # Request [same major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 4.9.2.9 0 0 0 0) # Request [same major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.9.6.0 0 0 0 0) # Request [same major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 4.9.6.9 0 0 0 0) # Request [same major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 4.9.9.0 0 0 0 0) # Request [same major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 4.9.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.0.0.0 0 0 0 0) # Request [newer major].0.0.0 -test_write_basic_config_version_file(4.5.6 9.0.0.9 0 0 0 0) # Request [newer major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6 9.0.2.0 0 0 0 0) # Request [newer major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6 9.0.2.9 0 0 0 0) # Request [newer major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.0.6.0 0 0 0 0) # Request [newer major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6 9.0.6.9 0 0 0 0) # Request [newer major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.0.9.0 0 0 0 0) # Request [newer major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6 9.0.9.9 0 0 0 0) # Request [newer major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.2.0.0 0 0 0 0) # Request [newer major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6 9.2.0.9 0 0 0 0) # Request [newer major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 9.2.2.0 0 0 0 0) # Request [newer major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 9.2.2.9 0 0 0 0) # Request [newer major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.2.6.0 0 0 0 0) # Request [newer major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 9.2.6.9 0 0 0 0) # Request [newer major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.2.9.0 0 0 0 0) # Request [newer major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 9.2.9.9 0 0 0 0) # Request [newer major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.5.0.0 0 0 0 0) # Request [newer major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6 9.5.0.9 0 0 0 0) # Request [newer major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 9.5.2.0 0 0 0 0) # Request [newer major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 9.5.2.9 0 0 0 0) # Request [newer major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.5.6.0 0 0 0 0) # Request [newer major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 9.5.6.9 0 0 0 0) # Request [newer major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.5.9.0 0 0 0 0) # Request [newer major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 9.5.9.9 0 0 0 0) # Request [newer major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.9.0.0 0 0 0 0) # Request [newer major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6 9.9.0.9 0 0 0 0) # Request [newer major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6 9.9.2.0 0 0 0 0) # Request [newer major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6 9.9.2.9 0 0 0 0) # Request [newer major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.9.6.0 0 0 0 0) # Request [newer major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6 9.9.6.9 0 0 0 0) # Request [newer major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6 9.9.9.0 0 0 0 0) # Request [newer major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] - - -test_write_basic_config_version_file(4.5.6.7 0 1 0 0 0) # Request 0 -test_write_basic_config_version_file(4.5.6.7 2 1 0 0 0) # Request [older major] -test_write_basic_config_version_file(4.5.6.7 4 1 1 0 0) # Request [same major] -test_write_basic_config_version_file(4.5.6.7 9 0 0 0 0) # Request [newer major] - -test_write_basic_config_version_file(4.5.6.7 0.0 1 0 0 0) # Request 0.0 -test_write_basic_config_version_file(4.5.6.7 0.2 1 0 0 0) # Request 0.[older minor] -test_write_basic_config_version_file(4.5.6.7 0.5 1 0 0 0) # Request 0.[same minor] -test_write_basic_config_version_file(4.5.6.7 0.9 1 0 0 0) # Request 0.[newer minor] -test_write_basic_config_version_file(4.5.6.7 2.0 1 0 0 0) # Request [older major].0 -test_write_basic_config_version_file(4.5.6.7 2.2 1 0 0 0) # Request [older major].[older minor] -test_write_basic_config_version_file(4.5.6.7 2.5 1 0 0 0) # Request [older major].[same minor] -test_write_basic_config_version_file(4.5.6.7 2.9 1 0 0 0) # Request [older major].[newer minor] -test_write_basic_config_version_file(4.5.6.7 4.0 1 1 0 0) # Request [same major].0 -test_write_basic_config_version_file(4.5.6.7 4.2 1 1 0 0) # Request [same major].[older minor] -test_write_basic_config_version_file(4.5.6.7 4.5 1 1 1 0) # Request [same major].[same minor] -test_write_basic_config_version_file(4.5.6.7 4.9 0 0 0 0) # Request [same major].[newer minor] -test_write_basic_config_version_file(4.5.6.7 9.0 0 0 0 0) # Request [newer major].0 -test_write_basic_config_version_file(4.5.6.7 9.1 0 0 0 0) # Request [newer major].[older minor] -test_write_basic_config_version_file(4.5.6.7 9.5 0 0 0 0) # Request [newer major].[same minor] -test_write_basic_config_version_file(4.5.6.7 9.9 0 0 0 0) # Request [newer major].[newer minor] - -test_write_basic_config_version_file(4.5.6.7 0.0.0 1 0 0 0) # Request 0.0.0 -test_write_basic_config_version_file(4.5.6.7 0.0.2 1 0 0 0) # Request 0.0.[older patch] -test_write_basic_config_version_file(4.5.6.7 0.0.6 1 0 0 0) # Request 0.0.[same patch] -test_write_basic_config_version_file(4.5.6.7 0.0.9 1 0 0 0) # Request 0.0.[newer patch] -test_write_basic_config_version_file(4.5.6.7 0.2.0 1 0 0 0) # Request 0.[older minor].0 -test_write_basic_config_version_file(4.5.6.7 0.2.2 1 0 0 0) # Request 0.[older minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 0.2.6 1 0 0 0) # Request 0.[older minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 0.2.9 1 0 0 0) # Request 0.[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 0.5.0 1 0 0 0) # Request 0.[same minor].0 -test_write_basic_config_version_file(4.5.6.7 0.5.2 1 0 0 0) # Request 0.[same minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 0.5.6 1 0 0 0) # Request 0.[same minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 0.5.9 1 0 0 0) # Request 0.[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 0.9.0 1 0 0 0) # Request 0.[newer minor].0 -test_write_basic_config_version_file(4.5.6.7 0.9.2 1 0 0 0) # Request 0.[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 0.9.6 1 0 0 0) # Request 0.[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 0.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 2.0.0 1 0 0 0) # Request [older major].0.0 -test_write_basic_config_version_file(4.5.6.7 2.0.2 1 0 0 0) # Request [older major].0.[older patch] -test_write_basic_config_version_file(4.5.6.7 2.0.6 1 0 0 0) # Request [older major].0.[same patch] -test_write_basic_config_version_file(4.5.6.7 2.0.9 1 0 0 0) # Request [older major].0.[newer patch] -test_write_basic_config_version_file(4.5.6.7 2.2.0 1 0 0 0) # Request [older major].[older minor].0 -test_write_basic_config_version_file(4.5.6.7 2.2.2 1 0 0 0) # Request [older major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 2.2.6 1 0 0 0) # Request [older major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 2.2.9 1 0 0 0) # Request [older major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 2.5.0 1 0 0 0) # Request [older major].[same minor].0 -test_write_basic_config_version_file(4.5.6.7 2.5.2 1 0 0 0) # Request [older major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 2.5.6 1 0 0 0) # Request [older major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 2.5.9 1 0 0 0) # Request [older major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 2.9.0 1 0 0 0) # Request [older major].[newer minor].0 -test_write_basic_config_version_file(4.5.6.7 2.9.2 1 0 0 0) # Request [older major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 2.9.6 1 0 0 0) # Request [older major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 2.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 4.0.0 1 1 0 0) # Request [same major].0.0 -test_write_basic_config_version_file(4.5.6.7 4.0.2 1 1 0 0) # Request [same major].0.[older patch] -test_write_basic_config_version_file(4.5.6.7 4.0.6 1 1 0 0) # Request [same major].0.[same patch] -test_write_basic_config_version_file(4.5.6.7 4.0.9 1 1 0 0) # Request [same major].0.[newer patch] -test_write_basic_config_version_file(4.5.6.7 4.2.0 1 1 0 0) # Request [same major].[older minor].0 -test_write_basic_config_version_file(4.5.6.7 4.2.2 1 1 0 0) # Request [same major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 4.2.6 1 1 0 0) # Request [same major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 4.2.9 1 1 0 0) # Request [same major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 4.5.0 1 1 1 0) # Request [same major].[same minor].0 -test_write_basic_config_version_file(4.5.6.7 4.5.2 1 1 1 0) # Request [same major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 4.5.6 1 1 1 1) # Request [same major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 4.5.9 0 0 0 0) # Request [same major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 4.9.0 0 0 0 0) # Request [same major].[newer minor].0 -test_write_basic_config_version_file(4.5.6.7 4.9.2 0 0 0 0) # Request [same major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 4.9.6 0 0 0 0) # Request [same major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 4.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 9.0.0 0 0 0 0) # Request [newer major].0.0 -test_write_basic_config_version_file(4.5.6.7 9.0.2 0 0 0 0) # Request [newer major].0.[older patch] -test_write_basic_config_version_file(4.5.6.7 9.0.6 0 0 0 0) # Request [newer major].0.[same patch] -test_write_basic_config_version_file(4.5.6.7 9.0.9 0 0 0 0) # Request [newer major].0.[newer patch] -test_write_basic_config_version_file(4.5.6.7 9.2.0 0 0 0 0) # Request [newer major].[older minor].0 -test_write_basic_config_version_file(4.5.6.7 9.2.2 0 0 0 0) # Request [newer major].[older minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 9.2.6 0 0 0 0) # Request [newer major].[older minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 9.2.9 0 0 0 0) # Request [newer major].[older minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 9.5.0 0 0 0 0) # Request [newer major].[same minor].0 -test_write_basic_config_version_file(4.5.6.7 9.5.2 0 0 0 0) # Request [newer major].[same minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 9.5.6 0 0 0 0) # Request [newer major].[same minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 9.5.9 0 0 0 0) # Request [newer major].[same minor].[newer patch] -test_write_basic_config_version_file(4.5.6.7 9.9.0 0 0 0 0) # Request [newer major].[newer minor].0 -test_write_basic_config_version_file(4.5.6.7 9.9.2 0 0 0 0) # Request [newer major].[newer minor].[older patch] -test_write_basic_config_version_file(4.5.6.7 9.9.6 0 0 0 0) # Request [newer major].[newer minor].[same patch] -test_write_basic_config_version_file(4.5.6.7 9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch] - -test_write_basic_config_version_file(4.5.6.7 0.0.0.0 1 0 0 0) # Request 0.0.0.0 -test_write_basic_config_version_file(4.5.6.7 0.0.0.2 1 0 0 0) # Request 0.0.0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.0.7 1 0 0 0) # Request 0.0.0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.0.9 1 0 0 0) # Request 0.0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.2.0 1 0 0 0) # Request 0.0.[older patch].0 -test_write_basic_config_version_file(4.5.6.7 0.0.2.2 1 0 0 0) # Request 0.0.[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.2.7 1 0 0 0) # Request 0.0.[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.2.9 1 0 0 0) # Request 0.0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.6.0 1 0 0 0) # Request 0.0.[same patch].0 -test_write_basic_config_version_file(4.5.6.7 0.0.6.2 1 0 0 0) # Request 0.0.[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.6.7 1 0 0 0) # Request 0.0.[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.6.9 1 0 0 0) # Request 0.0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.9.0 1 0 0 0) # Request 0.0.[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 0.0.9.2 1 0 0 0) # Request 0.0.[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.9.7 1 0 0 0) # Request 0.0.[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.0.9.9 1 0 0 0) # Request 0.0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.0.0 1 0 0 0) # Request 0.[older minor].0.0 -test_write_basic_config_version_file(4.5.6.7 0.2.0.2 1 0 0 0) # Request 0.[older minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.0.7 1 0 0 0) # Request 0.[older minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.0.9 1 0 0 0) # Request 0.[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.2.0 1 0 0 0) # Request 0.[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 0.2.2.2 1 0 0 0) # Request 0.[older minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.2.7 1 0 0 0) # Request 0.[older minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.2.9 1 0 0 0) # Request 0.[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.6.0 1 0 0 0) # Request 0.[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 0.2.6.2 1 0 0 0) # Request 0.[older minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.6.7 1 0 0 0) # Request 0.[older minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.6.9 1 0 0 0) # Request 0.[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.9.0 1 0 0 0) # Request 0.[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 0.2.9.2 1 0 0 0) # Request 0.[older minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.9.7 1 0 0 0) # Request 0.[older minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.2.9.9 1 0 0 0) # Request 0.[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.0.0 1 0 0 0) # Request 0.[same minor].0.0 -test_write_basic_config_version_file(4.5.6.7 0.5.0.2 1 0 0 0) # Request 0.[same minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.0.7 1 0 0 0) # Request 0.[same minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.0.9 1 0 0 0) # Request 0.[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.2.0 1 0 0 0) # Request 0.[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 0.5.2.2 1 0 0 0) # Request 0.[same minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.2.7 1 0 0 0) # Request 0.[same minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.2.9 1 0 0 0) # Request 0.[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.6.0 1 0 0 0) # Request 0.[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 0.5.6.2 1 0 0 0) # Request 0.[same minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.6.7 1 0 0 0) # Request 0.[same minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.6.9 1 0 0 0) # Request 0.[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.9.0 1 0 0 0) # Request 0.[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 0.5.9.2 1 0 0 0) # Request 0.[same minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.9.7 1 0 0 0) # Request 0.[same minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.5.9.9 1 0 0 0) # Request 0.[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.0.0 1 0 0 0) # Request 0.[newer minor].0.0 -test_write_basic_config_version_file(4.5.6.7 0.9.0.2 1 0 0 0) # Request 0.[newer minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.0.7 1 0 0 0) # Request 0.[newer minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.0.9 1 0 0 0) # Request 0.[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.2.0 1 0 0 0) # Request 0.[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 0.9.2.2 1 0 0 0) # Request 0.[newer minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.2.7 1 0 0 0) # Request 0.[newer minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.2.9 1 0 0 0) # Request 0.[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.6.0 1 0 0 0) # Request 0.[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 0.9.6.2 1 0 0 0) # Request 0.[newer minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.6.7 1 0 0 0) # Request 0.[newer minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.6.9 1 0 0 0) # Request 0.[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.9.0 1 0 0 0) # Request 0.[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 0.9.9.2 1 0 0 0) # Request 0.[newer minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.9.7 1 0 0 0) # Request 0.[newer minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 0.9.9.9 1 0 0 0) # Request 0.[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.0.0 1 0 0 0) # Request [older major].0.0.0 -test_write_basic_config_version_file(4.5.6.7 2.0.0.2 1 0 0 0) # Request [older major].0.0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.0.7 1 0 0 0) # Request [older major].0.0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.0.9 1 0 0 0) # Request [older major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.2.0 1 0 0 0) # Request [older major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6.7 2.0.2.2 1 0 0 0) # Request [older major].0.[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.2.7 1 0 0 0) # Request [older major].0.[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.2.9 1 0 0 0) # Request [older major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.6.0 1 0 0 0) # Request [older major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6.7 2.0.6.2 1 0 0 0) # Request [older major].0.[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.6.7 1 0 0 0) # Request [older major].0.[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.6.9 1 0 0 0) # Request [older major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.9.0 1 0 0 0) # Request [older major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 2.0.9.2 1 0 0 0) # Request [older major].0.[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.9.7 1 0 0 0) # Request [older major].0.[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.0.9.9 1 0 0 0) # Request [older major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.0.0 1 0 0 0) # Request [older major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6.7 2.2.0.2 1 0 0 0) # Request [older major].[older minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.0.7 1 0 0 0) # Request [older major].[older minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.0.9 1 0 0 0) # Request [older major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.2.0 1 0 0 0) # Request [older major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 2.2.2.2 1 0 0 0) # Request [older major].[older minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.2.7 1 0 0 0) # Request [older major].[older minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.2.9 1 0 0 0) # Request [older major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.6.0 1 0 0 0) # Request [older major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 2.2.6.2 1 0 0 0) # Request [older major].[older minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.6.7 1 0 0 0) # Request [older major].[older minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.6.9 1 0 0 0) # Request [older major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.9.0 1 0 0 0) # Request [older major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 2.2.9.2 1 0 0 0) # Request [older major].[older minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.9.7 1 0 0 0) # Request [older major].[older minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.2.9.9 1 0 0 0) # Request [older major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.0.0 1 0 0 0) # Request [older major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6.7 2.5.0.2 1 0 0 0) # Request [older major].[same minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.0.7 1 0 0 0) # Request [older major].[same minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.0.9 1 0 0 0) # Request [older major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.2.0 1 0 0 0) # Request [older major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 2.5.2.2 1 0 0 0) # Request [older major].[same minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.2.7 1 0 0 0) # Request [older major].[same minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.2.9 1 0 0 0) # Request [older major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.6.0 1 0 0 0) # Request [older major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 2.5.6.2 1 0 0 0) # Request [older major].[same minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.6.7 1 0 0 0) # Request [older major].[same minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.6.9 1 0 0 0) # Request [older major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.9.0 1 0 0 0) # Request [older major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 2.5.9.2 1 0 0 0) # Request [older major].[same minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.9.7 1 0 0 0) # Request [older major].[same minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.5.9.9 1 0 0 0) # Request [older major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.0.0 1 0 0 0) # Request [older major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6.7 2.9.0.2 1 0 0 0) # Request [older major].[newer minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.0.7 1 0 0 0) # Request [older major].[newer minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.0.9 1 0 0 0) # Request [older major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.2.0 1 0 0 0) # Request [older major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 2.9.2.2 1 0 0 0) # Request [older major].[newer minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.2.7 1 0 0 0) # Request [older major].[newer minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.2.9 1 0 0 0) # Request [older major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.6.0 1 0 0 0) # Request [older major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 2.9.6.2 1 0 0 0) # Request [older major].[newer minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.6.7 1 0 0 0) # Request [older major].[newer minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.6.9 1 0 0 0) # Request [older major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.9.0 1 0 0 0) # Request [older major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 2.9.9.2 1 0 0 0) # Request [older major].[newer minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.9.7 1 0 0 0) # Request [older major].[newer minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 2.9.9.9 1 0 0 0) # Request [older major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.0.0 1 1 0 0) # Request [same major].0.0.0 -test_write_basic_config_version_file(4.5.6.7 4.0.0.2 1 1 0 0) # Request [same major].0.0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.0.7 1 1 0 0) # Request [same major].0.0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.0.9 1 1 0 0) # Request [same major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.2.0 1 1 0 0) # Request [same major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6.7 4.0.2.2 1 1 0 0) # Request [same major].0.[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.2.7 1 1 0 0) # Request [same major].0.[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.2.9 1 1 0 0) # Request [same major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.6.0 1 1 0 0) # Request [same major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6.7 4.0.6.2 1 1 0 0) # Request [same major].0.[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.6.7 1 1 0 0) # Request [same major].0.[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.6.9 1 1 0 0) # Request [same major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.9.0 1 1 0 0) # Request [same major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 4.0.9.2 1 1 0 0) # Request [same major].0.[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.9.7 1 1 0 0) # Request [same major].0.[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.0.9.9 1 1 0 0) # Request [same major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.0.0 1 1 0 0) # Request [same major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6.7 4.2.0.2 1 1 0 0) # Request [same major].[older minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.0.7 1 1 0 0) # Request [same major].[older minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.0.9 1 1 0 0) # Request [same major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.2.0 1 1 0 0) # Request [same major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 4.2.2.2 1 1 0 0) # Request [same major].[older minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.2.7 1 1 0 0) # Request [same major].[older minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.2.9 1 1 0 0) # Request [same major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.6.0 1 1 0 0) # Request [same major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 4.2.6.2 1 1 0 0) # Request [same major].[older minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.6.7 1 1 0 0) # Request [same major].[older minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.6.9 1 1 0 0) # Request [same major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.9.0 1 1 0 0) # Request [same major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 4.2.9.2 1 1 0 0) # Request [same major].[older minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.9.7 1 1 0 0) # Request [same major].[older minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.2.9.9 1 1 0 0) # Request [same major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.0.0 1 1 1 0) # Request [same major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6.7 4.5.0.2 1 1 1 0) # Request [same major].[same minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.0.7 1 1 1 0) # Request [same major].[same minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.0.9 1 1 1 0) # Request [same major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.2.0 1 1 1 0) # Request [same major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 4.5.2.2 1 1 1 0) # Request [same major].[same minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.2.7 1 1 1 0) # Request [same major].[same minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.2.9 1 1 1 0) # Request [same major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.6.0 1 1 1 1) # Request [same major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 4.5.6.2 1 1 1 1) # Request [same major].[same minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.6.7 1 1 1 1) # Request [same major].[same minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.6.9 0 0 0 1) # Request [same major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.9.0 0 0 0 0) # Request [same major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 4.5.9.2 0 0 0 0) # Request [same major].[same minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.9.7 0 0 0 0) # Request [same major].[same minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.5.9.9 0 0 0 0) # Request [same major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.0.0 0 0 0 0) # Request [same major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6.7 4.9.0.2 0 0 0 0) # Request [same major].[newer minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.0.7 0 0 0 0) # Request [same major].[newer minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.0.9 0 0 0 0) # Request [same major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.2.0 0 0 0 0) # Request [same major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 4.9.2.2 0 0 0 0) # Request [same major].[newer minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.2.7 0 0 0 0) # Request [same major].[newer minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.2.9 0 0 0 0) # Request [same major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.6.0 0 0 0 0) # Request [same major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 4.9.6.2 0 0 0 0) # Request [same major].[newer minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.6.7 0 0 0 0) # Request [same major].[newer minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.6.9 0 0 0 0) # Request [same major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.9.0 0 0 0 0) # Request [same major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 4.9.9.2 0 0 0 0) # Request [same major].[newer minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.9.7 0 0 0 0) # Request [same major].[newer minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 4.9.9.9 0 0 0 0) # Request [same major].[newer minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.0.0 0 0 0 0) # Request [newer major].0.0.0 -test_write_basic_config_version_file(4.5.6.7 9.0.0.2 0 0 0 0) # Request [newer major].0.0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.0.7 0 0 0 0) # Request [newer major].0.0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.0.9 0 0 0 0) # Request [newer major].0.0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.2.0 0 0 0 0) # Request [newer major].0.[older patch].0 -test_write_basic_config_version_file(4.5.6.7 9.0.2.2 0 0 0 0) # Request [newer major].0.[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.2.7 0 0 0 0) # Request [newer major].0.[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.2.9 0 0 0 0) # Request [newer major].0.[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.6.0 0 0 0 0) # Request [newer major].0.[same patch].0 -test_write_basic_config_version_file(4.5.6.7 9.0.6.2 0 0 0 0) # Request [newer major].0.[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.6.7 0 0 0 0) # Request [newer major].0.[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.6.9 0 0 0 0) # Request [newer major].0.[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.9.0 0 0 0 0) # Request [newer major].0.[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 9.0.9.2 0 0 0 0) # Request [newer major].0.[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.9.7 0 0 0 0) # Request [newer major].0.[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.0.9.9 0 0 0 0) # Request [newer major].0.[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.0.0 0 0 0 0) # Request [newer major].[older minor].0.0 -test_write_basic_config_version_file(4.5.6.7 9.2.0.2 0 0 0 0) # Request [newer major].[older minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.0.7 0 0 0 0) # Request [newer major].[older minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.0.9 0 0 0 0) # Request [newer major].[older minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.2.0 0 0 0 0) # Request [newer major].[older minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 9.2.2.2 0 0 0 0) # Request [newer major].[older minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.2.7 0 0 0 0) # Request [newer major].[older minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.2.9 0 0 0 0) # Request [newer major].[older minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.6.0 0 0 0 0) # Request [newer major].[older minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 9.2.6.2 0 0 0 0) # Request [newer major].[older minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.6.7 0 0 0 0) # Request [newer major].[older minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.6.9 0 0 0 0) # Request [newer major].[older minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.9.0 0 0 0 0) # Request [newer major].[older minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 9.2.9.2 0 0 0 0) # Request [newer major].[older minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.9.7 0 0 0 0) # Request [newer major].[older minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.2.9.9 0 0 0 0) # Request [newer major].[older minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.0.0 0 0 0 0) # Request [newer major].[same minor].0.0 -test_write_basic_config_version_file(4.5.6.7 9.5.0.2 0 0 0 0) # Request [newer major].[same minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.0.7 0 0 0 0) # Request [newer major].[same minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.0.9 0 0 0 0) # Request [newer major].[same minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.2.0 0 0 0 0) # Request [newer major].[same minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 9.5.2.2 0 0 0 0) # Request [newer major].[same minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.2.7 0 0 0 0) # Request [newer major].[same minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.2.9 0 0 0 0) # Request [newer major].[same minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.6.0 0 0 0 0) # Request [newer major].[same minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 9.5.6.2 0 0 0 0) # Request [newer major].[same minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.6.7 0 0 0 0) # Request [newer major].[same minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.6.9 0 0 0 0) # Request [newer major].[same minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.9.0 0 0 0 0) # Request [newer major].[same minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 9.5.9.2 0 0 0 0) # Request [newer major].[same minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.9.7 0 0 0 0) # Request [newer major].[same minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.5.9.9 0 0 0 0) # Request [newer major].[same minor].[newer patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.0.0 0 0 0 0) # Request [newer major].[newer minor].0.0 -test_write_basic_config_version_file(4.5.6.7 9.9.0.2 0 0 0 0) # Request [newer major].[newer minor].0.[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.0.7 0 0 0 0) # Request [newer major].[newer minor].0.[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.0.9 0 0 0 0) # Request [newer major].[newer minor].0.[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.2.0 0 0 0 0) # Request [newer major].[newer minor].[older patch].0 -test_write_basic_config_version_file(4.5.6.7 9.9.2.2 0 0 0 0) # Request [newer major].[newer minor].[older patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.2.7 0 0 0 0) # Request [newer major].[newer minor].[older patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.2.9 0 0 0 0) # Request [newer major].[newer minor].[older patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.6.0 0 0 0 0) # Request [newer major].[newer minor].[same patch].0 -test_write_basic_config_version_file(4.5.6.7 9.9.6.2 0 0 0 0) # Request [newer major].[newer minor].[same patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.6.7 0 0 0 0) # Request [newer major].[newer minor].[same patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.6.9 0 0 0 0) # Request [newer major].[newer minor].[same patch].[newer tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.9.0 0 0 0 0) # Request [newer major].[newer minor].[newer patch].0 -test_write_basic_config_version_file(4.5.6.7 9.9.9.2 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[older tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.9.7 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[same tweak] -test_write_basic_config_version_file(4.5.6.7 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] - - ############################################################################ ##Test FIND_PACKAGE using sorting set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index b6b6519..5f95eb3 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -187,6 +187,7 @@ add_RunCMake_test(find_dependency) add_RunCMake_test(CompileDefinitions) add_RunCMake_test(CompileFeatures) add_RunCMake_test(PolicyScope) +add_RunCMake_test(WriteBasicConfigVersionFile) add_RunCMake_test(WriteCompilerDetectionHeader) add_RunCMake_test(SourceProperties) if(NOT WIN32) diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt b/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt new file mode 100644 index 0000000..9c558e3 --- /dev/null +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/All-stderr.txt @@ -0,0 +1 @@ +. diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake similarity index 82% copy from Tests/FindPackageTest/CMakeLists.txt copy to Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake index 3fd5541..6ff1550 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake @@ -1,468 +1,5 @@ -cmake_minimum_required (VERSION 2.6) -project(FindPackageTest) - -# Protect tests from running inside the default install prefix. -set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix") - -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) - -# Look for a package which uses FindPackageHandleStandardArgs.cmake with the -# new (as of cmake 2.8.3) syntax. This works only if CMP0017 is set to NEW, -# because otherwise FindPackageHandleStandardArgs.cmake from the current -# directory is included (via CMAKE_MODULE_PATH). -cmake_policy(SET CMP0017 NEW) -find_package(ZLIB QUIET) - -# Look for a package that has a find module and may be found. -find_package(OpenGL QUIET) - -# Look for a package that has no find module and will not be found. -find_package(NotAPackage QUIET) - -# Look for a package that has an advanced find module. -find_package(VTK QUIET) - -add_executable(FindPackageTest FindPackageTest.cxx) - -# test behaviour of cmFindBase wrt. the CMAKE_PREFIX_PATH variable -# foo.h should be found in ${CMAKE_CURRENT_SOURCE_DIR}/include: - -set(CMAKE_PREFIX_PATH /blub /blah "${CMAKE_CURRENT_SOURCE_DIR}") -find_path(FOO_DIR foo.h) - -if(NOT FOO_DIR) - message(FATAL_ERROR "Did not find foo.h which is in ${CMAKE_CURRENT_SOURCE_DIR}/include - CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") -endif() - -find_package(VersionTestA 1) -find_package(VersionTestB 1.2) -find_package(VersionTestC 1.2.3) -find_package(VersionTestD 1.2.3.4) - - -find_package(LotsOfComponents COMPONENTS AComp OPTIONAL_COMPONENTS BComp CComp) -if(NOT LOTSOFCOMPONENTS_FOUND) - message(SEND_ERROR "LotsOfComponents not found !") -endif() - -find_package(SomePackage) -if(NOT SomePackage_FOUND) - message(SEND_ERROR "SomePackage not found !") -endif() -if(NOT SOMEPACKAGE_FOUND) - message(SEND_ERROR "SomePackage compatibility name SOMEPACKAGE_FOUND not set!") -endif() - -find_package(UpperCasePackage) -if(NOT UpperCasePackage_FOUND) - message(SEND_ERROR "UpperCasePackage not found!") -endif() -if(NOT UPPERCASEPACKAGE_FOUND) - message(SEND_ERROR "SomePackage compatibility name SOMEPACKAGE_FOUND not set!") -endif() - -#----------------------------------------------------------------------------- -# Test system package registry if possible. -set(CMakeTestSystemPackage "") -if(WIN32 AND NOT CYGWIN) - # Try writing a value to the system package registry. - set(_data "${FindPackageTest_SOURCE_DIR}/SystemPackage") - set(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage") - set(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data") - file(WRITE ${_file} "${_data}\n") - execute_process( - COMMAND ${CMAKE_COMMAND} -E md5sum ${_file} - OUTPUT_VARIABLE _output ERROR_VARIABLE _error RESULT_VARIABLE _failed - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE " .*" "" _value "${_output}") - if(NOT _failed AND _value) - execute_process( - COMMAND reg add "${_key}" /v "${_value}" /t REG_SZ /d "${_data}" /f - OUTPUT_VARIABLE _output ERROR_VARIABLE _output RESULT_VARIABLE _failed - ) - endif() - # If the above worked, add the rest of the test and a rule to - # cleanup the value. - if(NOT _failed) - message(STATUS "HKLM is writable: enabling CMakeTestSystemPackage") - set(CMakeTestSystemPackage_CLEANUP reg delete "${_key}" /v "${_value}" /f) - set(CMakeTestSystemPackage CMakeTestSystemPackage) - else() - message(STATUS "HKLM is readonly: disabling CMakeTestSystemPackage") - endif() -endif() - -#----------------------------------------------------------------------------- - -#set(CMAKE_FIND_DEBUG_MODE 1) - -# For purposes of the test wipe out previous find results. -set(PACKAGES - foo Foo Bar Blub TFramework Tframework TApp Tapp Special - VersionedA VersionedB VersionedC VersionedD VersionedE - VersionedF VersionedG VersionedH - WrongA WrongB WrongC WrongD - wibbleA wibbleB - RecursiveA RecursiveB RecursiveC - ArchA ArchB ArchC ArchD - EnvA EnvB - SetFoundTRUE SetFoundFALSE - ${CMakeTestSystemPackage} - ) -foreach(p ${PACKAGES}) - set(${p}_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) -endforeach() - -# Enable framework and bundle searching. Make sure bundles are found -# before unix-syle packages. -set(CMAKE_FIND_FRAMEWORK LAST) -set(CMAKE_FIND_APPBUNDLE FIRST) - -# Set the wrong answer for a find to make sure it re-finds. -set(VersionedA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/cmake/zot-4.0) - -# Test that CMAKE_IGNORE_PATH can ignore the purposely bad package -# files in the lib/cmake/zot-3.1 directory. -set(CMAKE_IGNORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib/cmake/zot-3.1) - -# Look for packages with new-style signatures. -find_package(foo NO_MODULE) -find_package(Foo CONFIGS FooConfig.cmake) -find_package(Bar) -set(CMAKE_DISABLE_FIND_PACKAGE_Blub TRUE) -find_package(Blub NO_MODULE) -find_package(TFramework CONFIGS TFrameworkConfig.cmake) -find_package(Tframework) -find_package(TApp) -find_package(Tapp CONFIGS tapp-config.cmake) -find_package(Special NAMES Suffix SuffixTest PATH_SUFFIXES test) -find_package(VersionedA 2 NAMES zot) -find_package(VersionedB 3.1 EXACT NAMES zot) -find_package(VersionedC 4.0 EXACT NAMES zot) -find_package(VersionedD 1.1 EXACT NAMES Baz) -find_package(VersionedE 1.2 EXACT NAMES Baz) -find_package(VersionedF 1.3 EXACT NAMES Baz) -find_package(VersionedG 2.0 EXACT NAMES Baz) -find_package(VersionedH 2.1 EXACT NAMES Baz) - - -# Test Config files which set Xyz_FOUND themselves: -find_package(SetFoundTRUE NO_MODULE) -find_package(SetFoundFALSE NO_MODULE) - -# Test wrong initial path when result is present. -set(WrongA_DIR "${VersionedD_DIR}") -find_package(WrongA 1.2 EXACT NAMES Baz) - -# Test wrong initial cache entry of UNINITIALIZED type when result is present. -set(WrongB_DIR "${VersionedD_DIR}" CACHE UNINITIALIZED "Wrong Value" FORCE) -get_property(type CACHE WrongB_DIR PROPERTY TYPE) -find_package(WrongB 1.2 EXACT NAMES Baz) - -# Test wrong initial path when result is missing. -set(WrongC_DIR "${VersionedD_DIR}") -find_package(WrongC 1.4 EXACT QUIET NAMES Baz) - -# Test wrong initial cache entry of UNINITIALIZED type when result is missing. -set(WrongD_DIR "${VersionedD_DIR}" CACHE UNINITIALIZED "Wrong Value" FORCE) -get_property(type CACHE WrongD_DIR PROPERTY TYPE) -find_package(WrongD 1.4 EXACT QUIET NAMES Baz) - -# HINTS should override the system but PATHS should not -list(INSERT CMAKE_SYSTEM_PREFIX_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/A") -find_package(wibbleA NAMES wibble PATHS B) -find_package(wibbleB NAMES wibble HINTS B) - -# Look for package with recursive find-modules. -find_package(RecursiveA COMPONENTS A) -find_package(RecursiveB 2) -find_package(RecursiveC 3.1 EXACT) - -# Test architecture-specific search directories. -set(CMAKE_LIBRARY_ARCHITECTURE arch) -find_package(ArchA NAMES Bar) -find_package(ArchB NAMES Foo CONFIGS FooConfig.cmake) -find_package(ArchC 3.1 EXACT NAMES zot) -find_package(ArchD 4.0 EXACT NAMES zot) -unset(CMAKE_LIBRARY_ARCHITECTURE) - -# Test _DIR environment variable. -# We erase the main prefix path to ensure the env var is used. -set(CMAKE_PREFIX_PATH) -set(ENV{EnvA_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/lib/zot-3.1") -find_package(EnvA 3.1 EXACT QUIET NAMES zot) # Should Work -find_package(EnvB 3.1 EXACT QUIET NAMES zot) # Should Fail - -# Test system package registry if available. -if(CMakeTestSystemPackage) - find_package(CMakeTestSystemPackage) - execute_process(COMMAND ${CMakeTestSystemPackage_CLEANUP} - OUTPUT_VARIABLE _output ERROR_VARIABLE _error) -endif() - -# Expected locations at which packages should be found. -set(foo_EXPECTED "lib/foo-1.2/foo-config.cmake") -set(Foo_EXPECTED "lib/foo-1.2/CMake/FooConfig.cmake") -set(Bar_EXPECTED "lib/Bar/BarConfig.cmake") -set(Blub_MISSING "") -set(Special_EXPECTED "lib/suffix/test/SuffixTestConfig.cmake") -set(TFramework_EXPECTED - "TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake") -set(Tframework_EXPECTED - "TFramework.framework/Versions/A/Resources/tframework-config.cmake") -set(TApp_EXPECTED - "TApp.app/Contents/Resources/TAppConfig.cmake") -set(Tapp_EXPECTED - "TApp.app/Contents/Resources/cmake/tapp-config.cmake") -set(VersionedA_EXPECTED "lib/zot-2.0/zot-config.cmake") -set(VersionedB_EXPECTED "lib/zot-3.1/zot-config.cmake") -set(VersionedC_EXPECTED "lib/cmake/zot-4.0/zot-config.cmake") -set(VersionedD_EXPECTED "Baz 1.1/BazConfig.cmake") -set(VersionedE_EXPECTED "Baz 1.2/CMake/BazConfig.cmake") -set(VersionedF_EXPECTED "Baz 1.3/lib/cmake/Baz/BazConfig.cmake") -set(VersionedG_EXPECTED "Baz 2.0/share/Baz 2/BazConfig.cmake") -set(VersionedH_EXPECTED "Baz 2.1/lib/Baz 2/cmake/BazConfig.cmake") -set(WrongA_EXPECTED "${VersionedE_EXPECTED}") -set(WrongB_EXPECTED "${VersionedE_EXPECTED}") -set(WrongC_MISSING "WrongC_DIR-NOTFOUND") -set(WrongD_MISSING "WrongD_DIR-NOTFOUND") -set(wibbleA_EXPECTED "A/wibble-config.cmake") -set(wibbleB_EXPECTED "B/wibble-config.cmake") -set(RecursiveA_EXPECTED "lib/RecursiveA/recursivea-config.cmake") -set(RecursiveB_EXPECTED "lib/zot-2.0/zot-config.cmake") -set(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake") -set(ArchA_EXPECTED "lib/arch/Bar/BarConfig.cmake") -set(ArchB_EXPECTED "lib/arch/foo-1.2/CMake/FooConfig.cmake") -set(ArchC_EXPECTED "lib/arch/zot-3.1/zot-config.cmake") -set(ArchD_EXPECTED "lib/arch/cmake/zot-4.0/zot-config.cmake") -set(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake") -set(EnvB_MISSING "EnvB_DIR-NOTFOUND") -set(SetFoundTRUE_EXPECTED "cmake/SetFoundTRUEConfig.cmake") -set(SetFoundFALSE_MISSING "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set(CMakeTestSystemPackage_EXPECTED "SystemPackage/CMakeTestSystemPackageConfig.cmake") - -# Check the results. -foreach(p ${PACKAGES}) - if(DEFINED ${p}_MISSING) - # Check and report failure. - if(NOT "${${p}_DIR}" STREQUAL "${${p}_MISSING}") - message(SEND_ERROR - "Package ${p} should have been [${${p}_MISSING}] but " - "was [${${p}_DIR}]") - endif() - if(${p}_FOUND) - message(SEND_ERROR - "Package ${p} should not have been found, but ${p}_FOUND is set to " - "\"${${p}_FOUND}\"") - endif() - elseif(${p}_FOUND) - # Convert to relative path for comparison to expected location. - file(RELATIVE_PATH REL_${p}_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}" - "${${p}_CONFIG}") - - # Debugging output. - if(CMAKE_FIND_DEBUG_MODE) - message("Package ${p} found [${REL_${p}_CONFIG}]") - endif() - - # Check and report failure. - if(NOT "${REL_${p}_CONFIG}" STREQUAL "${${p}_EXPECTED}") - message(SEND_ERROR - "Package ${p} should have been [${${p}_EXPECTED}] but " - "was [${REL_${p}_CONFIG}]") - endif() - else() - message(SEND_ERROR "Package ${p} not found!") - endif() -endforeach() - -# Check that version information was extracted. -if(NOT "${VersionedA_VERSION}" STREQUAL "2.0") - message(SEND_ERROR - "Package VersionedA is version [${VersionedA_VERSION}], not [2.0]") -endif() -if(NOT "${VersionedA_VERSION_MAJOR}" STREQUAL "2") - message(SEND_ERROR - "Package VersionedA is major version [${VersionedA_VERSION_MAJOR}], not [2]") -endif() -if(NOT "${VersionedA_VERSION_MINOR}" STREQUAL "0") - message(SEND_ERROR - "Package VersionedA is minor version [${VersionedA_VERSION_MINOR}], not [0]") -endif() - -if(NOT "${VersionedB_VERSION}" STREQUAL "3.1") - message(SEND_ERROR - "Package VersionedB is version [${VersionedB_VERSION}], not [3.1]") -endif() -if(NOT "${VersionedB_VERSION_MAJOR}" STREQUAL "3") - message(SEND_ERROR - "Package VersionedB is major version [${VersionedB_VERSION_MAJOR}], not [3]") -endif() -if(NOT "${VersionedB_VERSION_MINOR}" STREQUAL "1") - message(SEND_ERROR - "Package VersionedB is minor version [${VersionedB_VERSION_MINOR}], not [1]") -endif() - -if(NOT "${Special_VERSION}" STREQUAL "1.2") - message(SEND_ERROR - "Package Special is version [${Special_VERSION}], not [1.2]") -endif() -if(NOT "${Special_VERSION_MAJOR}" STREQUAL "1") - message(SEND_ERROR - "Package Special is major version [${Special_VERSION_MAJOR}], not [1]") -endif() -if(NOT "${Special_VERSION_MINOR}" STREQUAL "2") - message(SEND_ERROR - "Package Special is minor version [${Special_VERSION_MINOR}], not [2]") -endif() - -# Test version number comparison. -if(NOT "1.2.3.4" VERSION_LESS "1.2.3.5") - message(SEND_ERROR "1.2.3.4 VERSION_LESS 1.2.3.5 is not true!") -endif() -if(NOT "1.2" VERSION_LESS "1.10") - message(SEND_ERROR "1.2 VERSION_LESS 1.10 is not true!") -endif() -if(NOT "1.02" VERSION_GREATER "1.1") - message(SEND_ERROR "1.02 VERSION_GREATER 1.1 is not true!") -endif() -if("1.2.3" VERSION_GREATER "1.2.3.4") - message(SEND_ERROR "1.2.3 VERSION_GREATER 1.2.3.4 is not false!") -endif() -if(NOT "1.2" VERSION_EQUAL "1.2.0.0") - message(SEND_ERROR "1.2 VERSION_EQUAL 1.2.0.0 is not true!") -endif() - -#----------------------------------------------------------------------------- -# Test export(PACKAGE) with find_package. - -# Choose a unique version. -string(REGEX REPLACE "-.*$" "" version ${CMAKE_VERSION}) -string(RANDOM LENGTH 4 ALPHABET "0123456789" v) -string(APPEND version ".${v}") - -message(STATUS "Preparing export(PACKAGE) test project") -try_compile(EXPORTER_COMPILED - ${FindPackageTest_BINARY_DIR}/Exporter-build - ${FindPackageTest_SOURCE_DIR}/Exporter - CMakeTestExportPackage dummy - CMAKE_FLAGS "-UCMAKE_EXPORT_NO_PACKAGE_REGISTRY" - -Dversion=${version} - OUTPUT_VARIABLE output) -message(STATUS "Searching for export(PACKAGE) test project") -set(CMakeTestExportPackage_DIR "" CACHE FILEPATH - "Wipe out find results for testing." FORCE) -find_package(CMakeTestExportPackage 1.${version} EXACT REQUIRED) - -message(STATUS "Searching for export(PACKAGE) test project with CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=TRUE") -set(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY TRUE) -set(CMakeTestExportPackage_DIR "" CACHE FILEPATH - "Wipe out find results for testing." FORCE) -find_package(CMakeTestExportPackage 1.${version} EXACT QUIET) -if(CMakeTestExportPackage_FOUND) - message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!") -endif() -unset(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY) - -message(STATUS "Remove export(PACKAGE) test project") -file(REMOVE_RECURSE ${FindPackageTest_BINARY_DIR}/Exporter-build) -set(CMakeTestExportPackage_DIR "" CACHE FILEPATH - "Wipe out find results for testing." FORCE) -find_package(CMakeTestExportPackage QUIET) # Should clean the user package cache -# -message(STATUS "Preparing export(PACKAGE) test project with CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE") -try_compile(EXPORTER_COMPILED - ${FindPackageTest_BINARY_DIR}/Exporter-build - ${FindPackageTest_SOURCE_DIR}/Exporter - CMakeTestExportPackage dummy - CMAKE_FLAGS "-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY:BOOL=TRUE" - -Dversion=${version} - OUTPUT_VARIABLE output) -message(STATUS "Searching for export(PACKAGE) test project") -find_package(CMakeTestExportPackage 1.${version} EXACT QUIET) -if(CMakeTestExportPackage_FOUND) - message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!") -endif() - -#----------------------------------------------------------------------------- -# Test configure_package_config_file(). - -include(CMakePackageConfigHelpers) - -# Generate a config file ready to be installed. -set(INCLUDE_INSTALL_DIR include ) -set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/" ) -set(CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ) - -configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}" - PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR - ) - -set(Relocatable_FIND_COMPONENTS AComp BComp CComp) -set(Relocatable_FIND_REQUIRED_BComp 1) -include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake") - -if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include") - message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")") -endif() - -if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/") - message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")") -endif() - -if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")") -endif() - -if(NOT DEFINED Relocatable_FOUND) - message(SEND_ERROR "Relocatable_FOUND not defined !") -endif() - -if(Relocatable_FOUND) - message(SEND_ERROR "Relocatable_FOUND set to TRUE !") -endif() - -# Generate a config file for the build tree. -set(INCLUDE_INSTALL_DIR include ) -set(SHARE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/share/" ) -set(CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ) - -configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake" - INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" - PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR - INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}" - ) - -set(Relocatable_FIND_COMPONENTS AComp BComp CComp) -set(Relocatable_FIND_REQUIRED_BComp 1) -include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake") - -if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include") - message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")") -endif() - -if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/") - message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")") -endif() - -if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")") -endif() - -if(NOT DEFINED Relocatable_FOUND) - message(SEND_ERROR "Relocatable_FOUND not defined !") -endif() - -if(Relocatable_FOUND) - message(SEND_ERROR "Relocatable_FOUND set to TRUE !") -endif() - - -#----------------------------------------------------------------------------- -# Test write_basic_config_version_file(). +# Hard-code architecture for test without a real compiler. +set(CMAKE_SIZEOF_VOID_P 4) include(WriteBasicConfigVersionFile) @@ -1365,33 +902,3 @@ test_write_basic_config_version_file(4.5.6.7 9.9.9.0 0 0 0 0) # Request [ne test_write_basic_config_version_file(4.5.6.7 9.9.9.2 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[older tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.7 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[same tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] - - -############################################################################ -##Test FIND_PACKAGE using sorting -set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME) -SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC) - -set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) -FIND_PACKAGE(SortLib CONFIG) -IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1") - message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}") -endif() -unset(SortLib_VERSION) - - -set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) -SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) -SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC) -FIND_PACKAGE(SortLib CONFIG) -IF (NOT "${SortLib_VERSION}" STREQUAL "3.10.1") - message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Natural! Dec ${SortLib_VERSION}") -endif() -set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) -unset(SortLib_VERSION) - - -unset(CMAKE_FIND_PACKAGE_SORT_ORDER) -unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION) -set(CMAKE_PREFIX_PATH ) diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/CMakeLists.txt b/Tests/RunCMake/WriteBasicConfigVersionFile/CMakeLists.txt new file mode 100644 index 0000000..44025d3 --- /dev/null +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.12) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/RunCMakeTest.cmake b/Tests/RunCMake/WriteBasicConfigVersionFile/RunCMakeTest.cmake new file mode 100644 index 0000000..e956f4f --- /dev/null +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(All) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6199637e9540627b03d9018ff53a14f005274607 commit 6199637e9540627b03d9018ff53a14f005274607 Author: Frank Benkstein AuthorDate: Fri Nov 9 19:14:58 2018 +0100 Commit: Brad King CommitDate: Tue Nov 13 15:01:17 2018 -0500 configure_file: canonicalize input and output path in dependencies Represent the input file path internally in canonical form. Otherwise multiple `configure_file` calls that share the same input file but specify it relative to different directories (e.g. via `../`) result in multiple copies of the dependency on the rule to re-run CMake. This causes the Ninja generator to emit duplicate phony build statements for these dependencies, which generates an error with `-w dupbuild=err`, which will be default in Ninja 1.9. Also canonicalize the output path for consistency. Add a test case. Fixes: #18584 diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index b5a639a..305262d 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -20,11 +20,8 @@ bool cmConfigureFileCommand::InitialPass(std::vector const& args, } std::string const& inFile = args[0]; - if (!cmSystemTools::FileIsFullPath(inFile)) { - this->InputFile = this->Makefile->GetCurrentSourceDirectory(); - this->InputFile += "/"; - } - this->InputFile += inFile; + this->InputFile = cmSystemTools::CollapseFullPath( + inFile, this->Makefile->GetCurrentSourceDirectory()); // If the input location is a directory, error out. if (cmSystemTools::FileIsDirectory(this->InputFile)) { @@ -39,11 +36,8 @@ bool cmConfigureFileCommand::InitialPass(std::vector const& args, } std::string const& outFile = args[1]; - if (!cmSystemTools::FileIsFullPath(outFile)) { - this->OutputFile = this->Makefile->GetCurrentBinaryDirectory(); - this->OutputFile += "/"; - } - this->OutputFile += outFile; + this->OutputFile = cmSystemTools::CollapseFullPath( + outFile, this->Makefile->GetCurrentBinaryDirectory()); // If the output location is already a directory put the file in it. if (cmSystemTools::FileIsDirectory(this->OutputFile)) { diff --git a/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake b/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake new file mode 100644 index 0000000..505f750 --- /dev/null +++ b/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.12) +project(Test LANGUAGES C) + +configure_file(PreventConfigureFileDupBuildRule.cmake PreventTargetAliasesDupBuildRule.cmake @ONLY) +add_subdirectory(SubDirConfigureFileDup) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 4b366a8..9e1e9a5 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -286,3 +286,10 @@ function (run_PreventTargetAliasesDupBuildRule) run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err) endfunction () run_PreventTargetAliasesDupBuildRule() + +function (run_PreventConfigureFileDupBuildRule) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PreventConfigureFileDupBuildRule-build) + run_cmake(PreventConfigureFileDupBuildRule) + run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err) +endfunction() +run_PreventConfigureFileDupBuildRule() diff --git a/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt b/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt new file mode 100644 index 0000000..433f77b --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt @@ -0,0 +1 @@ +configure_file(../PreventConfigureFileDupBuildRule.cmake PreventTargetAliasesDupBuildRule.cmake @ONLY) diff --git a/Tests/RunCMake/configure_file/DirInput-stderr.txt b/Tests/RunCMake/configure_file/DirInput-stderr.txt index 2e0cd14..165ad80 100644 --- a/Tests/RunCMake/configure_file/DirInput-stderr.txt +++ b/Tests/RunCMake/configure_file/DirInput-stderr.txt @@ -1,7 +1,7 @@ CMake Error at DirInput.cmake:[0-9]+ \(configure_file\): configure_file input location - .*/Tests/RunCMake/configure_file/. + .*/Tests/RunCMake/configure_file is a directory but a file was expected. Call Stack \(most recent call first\): ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-modules.7.rst | 2 +- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0084.rst | 26 + Help/release/dev/deprecate-findqt.rst | 8 + Modules/FindQt.cmake | 8 + Source/cmConfigureFileCommand.cxx | 14 +- Source/cmFindPackageCommand.cxx | 27 +- Source/cmFindPackageCommand.h | 3 + Source/cmMakefile.cxx | 7 +- Source/cmMakefile.h | 8 +- Source/cmPolicies.h | 5 +- Tests/FindPackageTest/CMakeLists.txt | 906 --------------------- Tests/RunCMake/CMakeLists.txt | 1 + .../Ninja/PreventConfigureFileDupBuildRule.cmake | 5 + Tests/RunCMake/Ninja/RunCMakeTest.cmake | 7 + .../Ninja/SubDirConfigureFileDup/CMakeLists.txt | 1 + .../WriteBasicConfigVersionFile/All.cmake} | 533 +----------- .../CMakeLists.txt | 2 +- .../WriteBasicConfigVersionFile/RunCMakeTest.cmake | 3 + Tests/RunCMake/configure_file/DirInput-stderr.txt | 2 +- Tests/RunCMake/find_package/CMP0084-NEW-stderr.txt | 20 + Tests/RunCMake/find_package/CMP0084-NEW.cmake | 7 + Tests/RunCMake/find_package/CMP0084-OLD.cmake | 7 + .../RunCMake/find_package/CMP0084-WARN-stderr.txt | 8 + Tests/RunCMake/find_package/CMP0084-WARN.cmake | 6 + Tests/RunCMake/find_package/RunCMakeTest.cmake | 3 + 26 files changed, 174 insertions(+), 1446 deletions(-) create mode 100644 Help/policy/CMP0084.rst create mode 100644 Help/release/dev/deprecate-findqt.rst create mode 100644 Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake create mode 100644 Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt copy Tests/{FindPackageTest/CMakeLists.txt => RunCMake/WriteBasicConfigVersionFile/All.cmake} (80%) copy Tests/RunCMake/{option => WriteBasicConfigVersionFile}/CMakeLists.txt (69%) create mode 100644 Tests/RunCMake/WriteBasicConfigVersionFile/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/find_package/CMP0084-NEW-stderr.txt create mode 100644 Tests/RunCMake/find_package/CMP0084-NEW.cmake create mode 100644 Tests/RunCMake/find_package/CMP0084-OLD.cmake create mode 100644 Tests/RunCMake/find_package/CMP0084-WARN-stderr.txt create mode 100644 Tests/RunCMake/find_package/CMP0084-WARN.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 15 13:53:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 15 Nov 2018 13:53:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-469-gb324743 Message-ID: <20181115185306.9C4C9127964@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via b32474322907fcd2658ad964847fc62b02659517 (commit) via a26ac919ef0a098b88c3764d5471f5852071f239 (commit) from 1763f0428193cd6e28af4e49131516299acdf3b7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b32474322907fcd2658ad964847fc62b02659517 commit b32474322907fcd2658ad964847fc62b02659517 Merge: 1763f04 a26ac91 Author: Brad King AuthorDate: Thu Nov 15 18:49:51 2018 +0000 Commit: Kitware Robot CommitDate: Thu Nov 15 13:49:58 2018 -0500 Merge topic 'cpack' a26ac919ef Help: Explain interaction of cpack(1) and CPack. Acked-by: Kitware Robot Merge-request: !2617 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a26ac919ef0a098b88c3764d5471f5852071f239 commit a26ac919ef0a098b88c3764d5471f5852071f239 Author: Joachim Wuttke (l) AuthorDate: Wed Nov 14 23:35:22 2018 +0100 Commit: Joachim Wuttke (o) CommitDate: Thu Nov 15 16:50:52 2018 +0100 Help: Explain interaction of cpack(1) and CPack. In particular, make clear that package/installer generators are not the makefile generators of the cmake command. Also insert sections in CPack doc, and capitalize section titles. diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst index 6159d7b..9ddab1e 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst @@ -13,12 +13,29 @@ Synopsis Description =========== -The ``cpack`` executable is the CMake packaging program. -CMake projects use :command:`install` commands to define the contents of -packages which can be generated in various formats by this tool. -The :module:`CPack` module greatly simplifies the creation of the input file -used by ``cpack``, allowing most aspects of the packaging configuration to be -controlled directly from the CMake project's own ``CMakeLists.txt`` files. +The ``cpack`` executable is the CMake packaging program. It generates +installers and source packages in a variety of formats. + +For each installer or package format, ``cpack`` has a specific backend, +called "generator". A generator is responsible for generating the required +inputs and invoking the specific package creation tools. These installer +or package generators are not to be confused with the makefile generators +of the :manual:`cmake ` command. + +All supported generators are specified in the :manual:`cpack-generators +` manual. The command ``cpack --help`` prints a +list of generators supported for the target platform. Which of them are +to be used can be selected through the :variable:`CPACK_GENERATOR` variable +or through the command-line option ``-G``. + +The ``cpack`` program is steered by a configuration file written in the +:manual:`CMake language `. Unless chosen differently +through the command-line option ``--config``, the file ``CPackConfig.cmake`` +in the current directory is used. + +In the standard CMake workflow, the file ``CPackConfig.cmake`` is generated +by the :manual:`cmake ` executable, provided the :module:`CPack` +module is included by the project's ``CMakeLists.txt`` file. Options ======= @@ -27,14 +44,9 @@ Options ```` is a :ref:`semicolon-separated list ` of generator names. ``cpack`` will iterate through this list and produce package(s) in that generator's format according to the details provided in - the ``CPackConfig.cmake`` configuration file. A generator is responsible for - generating the required inputs for a particular package system and invoking - that system's package creation tools. All supported generators are specified - in the :manual:`Generators ` section of the manual and - the ``--help`` option lists the generators supported for the target platform. - - If this option is not given, the :variable:`CPACK_GENERATOR` variable - determines the default set of generators that will be used. + the ``CPackConfig.cmake`` configuration file. If this option is not given, + the :variable:`CPACK_GENERATOR` variable determines the default set of + generators that will be used. ``-C `` Specify the project configuration to be packaged (e.g. ``Debug``, diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index ebce851..c9008db 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -10,20 +10,23 @@ Build binary and source package installers. Introduction ^^^^^^^^^^^^ -The CPack module generates binary and source installers in a variety of -formats using the cpack program. Inclusion of the CPack module adds -two new build targets, ``package`` and ``package_source``, which build -the binary and source installers respectively. The generated binary -installers contain everything installed via CMake's :command:`install` -command (and the deprecated :command:`install_files`, -:command:`install_programs` and :command:`install_targets` commands). +The CPack module generates a file ``CPackConfig.cmake`` intended for +use in a subsequent run of the :manual:`cpack ` program +where it steers the generation of installers or/and source packages. + +Inclusion of the CPack module adds two new build targets, ``package`` +and ``package_source``, which build the binary and source installers +respectively. The generated binary installers contain everything +installed via CMake's :command:`install` command (and the deprecated +commands :command:`install_files`, :command:`install_programs`, and +:command:`install_targets`). For certain kinds of binary installers (including the graphical installers on macOS and Windows), CPack generates installers that allow users to select individual application components to install. See :module:`CPackComponent` module for further details. -CPack generators +CPack Generators ^^^^^^^^^^^^^^^^ The :variable:`CPACK_GENERATOR` variable has different meanings in different @@ -60,7 +63,7 @@ This is the key: For each generator listed in :variable:`CPACK_GENERATOR` in internally to *the one currently being used* and then include the :variable:`CPACK_PROJECT_CONFIG_FILE`. -Variables common to all CPack generators +Variables common to all CPack Generators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Before including this CPack module in your ``CMakeLists.txt`` file, there @@ -250,6 +253,9 @@ installers. The most commonly-used variables are: received by the cpack program. Defaults to ``FALSE`` for backwards compatibility. +Variables for Source Package Generators +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The following CPack variables are specific to source packages, and will not affect binary packages: @@ -284,6 +290,9 @@ will not affect binary packages: must be properly escaped), e.g., ``/CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*`` +Variables for Advanced Use +^^^^^^^^^^^^^^^^^^^^^^^^^^ + The following variables are for advanced uses of CPack: .. variable:: CPACK_CMAKE_GENERATOR ----------------------------------------------------------------------- Summary of changes: Help/manual/cpack.1.rst | 40 ++++++++++++++++++++++++++-------------- Modules/CPack.cmake | 27 ++++++++++++++++++--------- 2 files changed, 44 insertions(+), 23 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 16 00:03:07 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 16 Nov 2018 00:03:07 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-470-g7aa4109 Message-ID: <20181116050307.2CBFC1276F2@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 7aa41095fd23d31a4572966ba53ad85f61f5bc99 (commit) from b32474322907fcd2658ad964847fc62b02659517 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7aa41095fd23d31a4572966ba53ad85f61f5bc99 commit 7aa41095fd23d31a4572966ba53ad85f61f5bc99 Author: Kitware Robot AuthorDate: Fri Nov 16 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Fri Nov 16 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 616e7d8..94e60fc 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 13) -set(CMake_VERSION_PATCH 20181115) +set(CMake_VERSION_PATCH 20181116) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sat Nov 17 00:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sat, 17 Nov 2018 00:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-471-gbe9ad82 Message-ID: <20181117050306.88CC7127AED@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via be9ad8279a29893943b342cc5ffdbf9868fb1b4c (commit) from 7aa41095fd23d31a4572966ba53ad85f61f5bc99 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=be9ad8279a29893943b342cc5ffdbf9868fb1b4c commit be9ad8279a29893943b342cc5ffdbf9868fb1b4c Author: Kitware Robot AuthorDate: Sat Nov 17 00:01:03 2018 -0500 Commit: Kitware Robot CommitDate: Sat Nov 17 00:01:03 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 94e60fc..3ec922c 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 13) -set(CMake_VERSION_PATCH 20181116) +set(CMake_VERSION_PATCH 20181117) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 18 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 18 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-472-g6f5cdc0 Message-ID: <20181118050305.12AA7127B48@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 6f5cdc0c83d9c2413c8ff76868df0ce7d1f49bcc (commit) from be9ad8279a29893943b342cc5ffdbf9868fb1b4c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6f5cdc0c83d9c2413c8ff76868df0ce7d1f49bcc commit 6f5cdc0c83d9c2413c8ff76868df0ce7d1f49bcc Author: Kitware Robot AuthorDate: Sun Nov 18 00:01:11 2018 -0500 Commit: Kitware Robot CommitDate: Sun Nov 18 00:01:11 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3ec922c..fdd6e83 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 13) -set(CMake_VERSION_PATCH 20181117) +set(CMake_VERSION_PATCH 20181118) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 19 00:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 19 Nov 2018 00:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-473-g61e3ced Message-ID: <20181119050304.C48EF127FBC@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 61e3ceda21800949f1a4411f27efefcda789bd4d (commit) from 6f5cdc0c83d9c2413c8ff76868df0ce7d1f49bcc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=61e3ceda21800949f1a4411f27efefcda789bd4d commit 61e3ceda21800949f1a4411f27efefcda789bd4d Author: Kitware Robot AuthorDate: Mon Nov 19 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Mon Nov 19 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index fdd6e83..eec8d1a 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 13) -set(CMake_VERSION_PATCH 20181118) +set(CMake_VERSION_PATCH 20181119) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 19 09:53:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 19 Nov 2018 09:53:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-476-g95a7351 Message-ID: <20181119145305.315E512748C@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 95a735116f51285f78acb04d1bdc7863122fd94a (commit) via 86e8315482fd8f0bba85af6f4f8363ead6a0818d (commit) via bdec3bd896b6faabab1c7cae79d8e75e8d0f0e41 (commit) from 61e3ceda21800949f1a4411f27efefcda789bd4d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=95a735116f51285f78acb04d1bdc7863122fd94a commit 95a735116f51285f78acb04d1bdc7863122fd94a Merge: 61e3ced 86e8315 Author: Brad King AuthorDate: Mon Nov 19 14:51:57 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 19 09:52:07 2018 -0500 Merge topic 'ctest-stdin' 86e8315482 CTest: Restore inheritance of stdin by test processes bdec3bd896 Tests: Teach RunCMake infrastructure to optionally provide stdin Acked-by: Kitware Robot Merge-request: !2618 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=86e8315482fd8f0bba85af6f4f8363ead6a0818d commit 86e8315482fd8f0bba85af6f4f8363ead6a0818d Author: Brad King AuthorDate: Thu Nov 15 08:03:57 2018 -0500 Commit: Brad King CommitDate: Thu Nov 15 08:08:56 2018 -0500 CTest: Restore inheritance of stdin by test processes Since commit v3.11.0-rc1~117^2 (CTest: Re-implement test process handling using libuv, 2017-12-10) we do not give the child test processes any stdin. Prior to that change we let the child test processes inherit stdin from ctest itself. Tests that run serially might be able to use the real stdin meaningfully, so restore that behavior and add a test case. Fixes: #18591 diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 39cea87..c4cf046 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -127,7 +127,8 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector* affinity) uv_pipe_open(pipe_writer, fds[1]); uv_stdio_container_t stdio[3]; - stdio[0].flags = UV_IGNORE; + stdio[0].flags = UV_INHERIT_FD; + stdio[0].data.fd = 0; stdio[1].flags = UV_INHERIT_STREAM; stdio[1].data.stream = pipe_writer; stdio[2] = stdio[1]; diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index ecd4441..99f4ae7 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -368,7 +368,8 @@ add_RunCMake_test(FetchContent) if(NOT CMake_TEST_EXTERNAL_CMAKE) set(CTestCommandLine_ARGS -DTEST_AFFINITY=$) endif() -add_RunCMake_test(CTestCommandLine) +add_executable(print_stdin print_stdin.c) +add_RunCMake_test(CTestCommandLine -DTEST_PRINT_STDIN=$) add_RunCMake_test(CacheNewline) # Only run this test on unix platforms that support # symbolic links diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index 9e8d050..750ae50 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -161,3 +161,15 @@ endfunction() if(TEST_AFFINITY) run_TestAffinity() endif() + +function(run_TestStdin) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestStdin) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" " + add_test(TestStdin \"${TEST_PRINT_STDIN}\") + ") + run_cmake_command(TestStdin ${CMAKE_CTEST_COMMAND} -V) +endfunction() +run_TestStdin() diff --git a/Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt b/Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt new file mode 100644 index 0000000..d83b50a --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt @@ -0,0 +1 @@ +Content for TestStdin diff --git a/Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt b/Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt new file mode 100644 index 0000000..d83b50a --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt @@ -0,0 +1 @@ +Content for TestStdin diff --git a/Tests/RunCMake/print_stdin.c b/Tests/RunCMake/print_stdin.c new file mode 100644 index 0000000..e083e62 --- /dev/null +++ b/Tests/RunCMake/print_stdin.c @@ -0,0 +1,18 @@ +#include + +int main() +{ + char buf[1024]; + size_t nIn = sizeof(buf); + while (nIn == sizeof(buf)) { + nIn = fread(buf, 1, sizeof(buf), stdin); + if (nIn > 0) { + size_t nOut; + nOut = fwrite(buf, 1, nIn, stdout); + if (nOut != nIn) { + return 1; + } + } + } + return 0; +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bdec3bd896b6faabab1c7cae79d8e75e8d0f0e41 commit bdec3bd896b6faabab1c7cae79d8e75e8d0f0e41 Author: Brad King AuthorDate: Thu Nov 15 08:03:12 2018 -0500 Commit: Brad King CommitDate: Thu Nov 15 08:08:56 2018 -0500 Tests: Teach RunCMake infrastructure to optionally provide stdin diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 69c96cc..c076ad9 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -65,6 +65,13 @@ function(run_cmake test) else() set(maybe_timeout "") endif() + if(RunCMake-stdin-file AND EXISTS ${top_src}/${RunCMake-stdin-file}) + set(maybe_input_file INPUT_FILE ${top_src}/${RunCMake-stdin-file}) + elseif(EXISTS ${top_src}/${test}-stdin.txt) + set(maybe_input_file INPUT_FILE ${top_src}/${test}-stdin.txt) + else() + set(maybe_input_file "") + endif() if(RunCMake_TEST_COMMAND) execute_process( COMMAND ${RunCMake_TEST_COMMAND} @@ -74,6 +81,7 @@ function(run_cmake test) RESULT_VARIABLE actual_result ENCODING UTF8 ${maybe_timeout} + ${maybe_input_file} ) else() if(RunCMake_GENERATOR_INSTANCE) @@ -96,6 +104,7 @@ function(run_cmake test) RESULT_VARIABLE actual_result ENCODING UTF8 ${maybe_timeout} + ${maybe_input_file} ) endif() set(msg "") ----------------------------------------------------------------------- Summary of changes: Source/CTest/cmProcess.cxx | 3 ++- Tests/RunCMake/CMakeLists.txt | 3 ++- Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake | 12 ++++++++++++ Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt | 1 + Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt | 1 + Tests/RunCMake/RunCMake.cmake | 9 +++++++++ Tests/RunCMake/print_stdin.c | 18 ++++++++++++++++++ 7 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt create mode 100644 Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt create mode 100644 Tests/RunCMake/print_stdin.c hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 19 10:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 19 Nov 2018 10:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-490-g8866f63 Message-ID: <20181119150306.5AB6C126BDA@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 8866f63f60a46f947fb9a6658944988da84867c4 (commit) via b7b2ce56a7f215574144da390b803611b9e5eca1 (commit) via d9d8816f39d625f7f5e6f87ec831badcff4f3f5d (commit) via b10f7ac534ef611fcdd6f09e830be6b9c4e28e11 (commit) via b82526c6542afbaea7e315cc4628cacdfe90ebae (commit) via bced9d5e568604509db43b16d8baa7f1c7b4e714 (commit) via a7d2ffb2325478e4d242e3b7338f8ca1c1898ff7 (commit) via 40b3dba52995e2c0275ae1712a169173aed6fcbf (commit) via cc96249e2eee63e90999b1d6cb87dd355696a355 (commit) via 99489d9f10ac23da29c0ed2ed9bd371946df0991 (commit) via b8b598061a3968bcf3998040a3ca76a085592c83 (commit) via 6079a0d00f38a27e17c9d07465e108d9e1f34960 (commit) via 3c54955d0d6c994e36cd128ee7b7b286b0425148 (commit) via 1217ff41388e53003424e2f58265ed4321e2030b (commit) from 95a735116f51285f78acb04d1bdc7863122fd94a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8866f63f60a46f947fb9a6658944988da84867c4 commit 8866f63f60a46f947fb9a6658944988da84867c4 Merge: b7b2ce5 b82526c Author: Brad King AuthorDate: Mon Nov 19 14:58:55 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 19 09:59:02 2018 -0500 Merge topic 'macro_doc_cleanups' b82526c654 Help: Minor grammar and typo corrections for macro command docs Acked-by: Kitware Robot Merge-request: !2622 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b7b2ce56a7f215574144da390b803611b9e5eca1 commit b7b2ce56a7f215574144da390b803611b9e5eca1 Merge: d9d8816 bced9d5 Author: Brad King AuthorDate: Mon Nov 19 14:57:17 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 19 09:57:46 2018 -0500 Merge topic 'findx11-imported-targets' bced9d5e56 Tests/FindX11: add a test a7d2ffb232 FindX11: add imported targets 40b3dba529 FindX11: require Freetype and Fontconfig for Xft cc96249e2e FindX11: remove local variable from the advanced list 99489d9f10 FindX11: find Xext.h b8b598061a FindX11: match variables with library names 6079a0d00f FindX11: fix some formatting in the documentation 3c54955d0d FindX11: use `list(APPEND)` for clearer code ... Acked-by: Kitware Robot Merge-request: !2604 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d9d8816f39d625f7f5e6f87ec831badcff4f3f5d commit d9d8816f39d625f7f5e6f87ec831badcff4f3f5d Merge: 95a7351 b10f7ac Author: Brad King AuthorDate: Mon Nov 19 14:57:06 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 19 09:57:13 2018 -0500 Merge topic 'pie-link-options' b10f7ac534 CMP0083: fix warning message on try_compile Acked-by: Kitware Robot Merge-request: !2619 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b10f7ac534ef611fcdd6f09e830be6b9c4e28e11 commit b10f7ac534ef611fcdd6f09e830be6b9c4e28e11 Author: Marc Chevrier AuthorDate: Thu Nov 15 16:46:02 2018 +0100 Commit: Marc Chevrier CommitDate: Mon Nov 19 10:56:02 2018 +0100 CMP0083: fix warning message on try_compile Fixes: #18593 diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst index 28caa7c..310ad11 100644 --- a/Help/command/try_compile.rst +++ b/Help/command/try_compile.rst @@ -127,7 +127,8 @@ default values: If :policy:`CMP0056` is set to ``NEW``, then :variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well. -The current setting of :policy:`CMP0065` is set in the generated project. +The current settings of :policy:`CMP0065` and :policy:`CMP0083` are set in the +generated project. Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose a build configuration. diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 0b50121..f6ec606 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -656,6 +656,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv, ? "NEW" : "OLD"); + /* Set the appropriate policy information for PIE link flags */ + fprintf(fout, "cmake_policy(SET CMP0083 %s)\n", + this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) == + cmPolicies::NEW + ? "NEW" + : "OLD"); + if (targetType == cmStateEnums::EXECUTABLE) { /* Put the executable at a known location (for COPY_FILE). */ fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n", https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b82526c6542afbaea7e315cc4628cacdfe90ebae commit b82526c6542afbaea7e315cc4628cacdfe90ebae Author: Craig Scott AuthorDate: Fri Nov 16 07:54:59 2018 +1100 Commit: Craig Scott CommitDate: Fri Nov 16 08:01:55 2018 +1100 Help: Minor grammar and typo corrections for macro command docs Follow-up to !2616, specifically commit 22cca9b810 diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 42a99fc..464940f 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -76,16 +76,16 @@ Macro vs Function The ``macro`` command is very similar to the :command:`function` command. Nonetheless, there are a few important differences. -In a function, ``ARGC``, ``ARGC`` and ``ARGV0``, ``ARGV1``, ... are -true variables in the usual CMake sense. In a macro, they are not. -They are string replacements much like the C preprocessor would do +In a function, ``ARGN``, ``ARGC``, ``ARGV`` and ``ARGV0``, ``ARGV1``, ... +are true variables in the usual CMake sense. In a macro, they are not, +they are string replacements much like the C preprocessor would do with a macro. This has a number of consequences, as explained in the :ref:`Argument Caveats` section below. Another difference between macros and functions is the control flow. A function is executed by transfering control from the calling statement to the function body. A macro is executed as if the macro -body were pasted in place of the calling statement. This has for +body were pasted in place of the calling statement. This has the consequence that a :command:`return()` in a macro body does not just terminate execution of the macro; rather, control is returned from the scope of the macro call. To avoid confusion, it is recommended @@ -96,7 +96,7 @@ to avoid :command:`return()` in macros altogether. Argument Caveats ^^^^^^^^^^^^^^^^ -Since ``ARGC``, ``ARGC``, ``ARGV0`` etc are not variables, +Since ``ARGN``, ``ARGC``, ``ARGV``, ``ARGV0`` etc. are not variables, you will NOT be able to use commands like .. code-block:: cmake https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bced9d5e568604509db43b16d8baa7f1c7b4e714 commit bced9d5e568604509db43b16d8baa7f1c7b4e714 Author: Ben Boeckel AuthorDate: Mon Nov 12 15:51:50 2018 -0500 Commit: Ben Boeckel CommitDate: Thu Nov 15 13:08:18 2018 -0500 Tests/FindX11: add a test diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 132855b..96cdfd0 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1485,6 +1485,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindVulkan) endif() + if(CMake_TEST_FindX11) + add_subdirectory(FindX11) + endif() + if(CMake_TEST_FindXalanC) add_subdirectory(FindXalanC) endif() diff --git a/Tests/FindX11/CMakeLists.txt b/Tests/FindX11/CMakeLists.txt new file mode 100644 index 0000000..cc931a1 --- /dev/null +++ b/Tests/FindX11/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindX11.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindX11/Test" + "${CMake_BINARY_DIR}/Tests/FindX11/Test" + ${build_generator_args} + --build-project TestFindX11 + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt new file mode 100644 index 0000000..769271f --- /dev/null +++ b/Tests/FindX11/Test/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 3.10) +project(TestFindX11 C) +include(CTest) + +find_package(X11 REQUIRED) + +function (test_x11_component have_var component) + if (NOT X11_${component}_FOUND) + message("Skipping ${component} because it was not found.") + return () + endif () + + add_executable(test_tgt_${component} main.c) + target_link_libraries(test_tgt_${component} PRIVATE X11::${component}) + target_compile_definitions(test_tgt_${component} PRIVATE HAVE_X11_${component}) + add_test(NAME test_tgt_${component} COMMAND test_tgt_${component}) + + # Add to the list of components to test for the parent. + set(${have_var} + ${${have_var}} + HAVE_X11_${component} + PARENT_SCOPE) +endfunction () + +set(x11_components) +test_x11_component(x11_components ICE) +test_x11_component(x11_components SM) +# Not a component; hack it up. +set(X11_X11_FOUND ${X11_FOUND}) +test_x11_component(x11_components X11) +test_x11_component(x11_components Xau) +test_x11_component(x11_components Xcomposite) +test_x11_component(x11_components Xdamage) +test_x11_component(x11_components Xdmcp) +test_x11_component(x11_components Xext) +test_x11_component(x11_components Xxf86misc) +test_x11_component(x11_components Xxf86vm) +test_x11_component(x11_components Xfixes) +# We ignore the Xft component because the variables do not provide the required +# dependency information (Freetype and Fontconfig). +test_x11_component(x11_components_ignore Xft) +test_x11_component(x11_components Xi) +test_x11_component(x11_components Xinerama) +test_x11_component(x11_components Xkb) +test_x11_component(x11_components xkbfile) +test_x11_component(x11_components Xmu) +test_x11_component(x11_components Xpm) +test_x11_component(x11_components Xtst) +test_x11_component(x11_components Xrandr) +test_x11_component(x11_components Xrender) +test_x11_component(x11_components XRes) +test_x11_component(x11_components Xss) +test_x11_component(x11_components Xt) +test_x11_component(x11_components Xutil) +test_x11_component(x11_components Xv) + +# The variables do not include dependency information. Just test "everything". +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${X11_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${X11_LIBRARIES}) +# Not included in X11_LIBRARIES. +foreach(lib + Xau + Xcomposite + Xdamage + Xdmcp + Xxf86misc + Xxf86vm + Xfixes + Xi + Xinerama + Xkb + xkbfile + Xmu + Xpm + Xtst + Xrandr + Xrender + XRes + Xss + Xt + Xv + ) + if (X11_${lib}_FOUND) + target_link_libraries(test_var PRIVATE ${X11_${lib}_LIB}) + endif () +endforeach() +target_compile_definitions(test_var PRIVATE ${x11_components}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindX11/Test/main.c b/Tests/FindX11/Test/main.c new file mode 100644 index 0000000..044bfa2 --- /dev/null +++ b/Tests/FindX11/Test/main.c @@ -0,0 +1,405 @@ +#ifdef HAVE_X11_ICE +# include + +static Status test_ICE(void) +{ + return IceInitThreads(); +} +#endif + +#ifdef HAVE_X11_SM +# include +# include + +static void test_SM(void) +{ + SmcProtocolVersion(NULL); +} +#endif + +#ifdef HAVE_X11_X11 +# include + +static Status test_X11(void) +{ + return XInitThreads(); +} +#endif + +#ifdef HAVE_X11_Xau +# include + +static char* test_Xau(void) +{ + return XauFileName(); +} +#endif + +#ifdef HAVE_X11_Xcomposite +# include + +static int test_Xcomposite(void) +{ + return XCompositeVersion(); +} +#endif + +#ifdef HAVE_X11_Xdamage +# include + +static Bool test_Xdamage(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XDamageQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xdmcp +# include + +static int test_Xdmcp(void) +{ + BYTE data[1024]; + XdmcpBuffer buf = { data, sizeof(data), 0, 0 }; + return XdmcpReadRemaining(&buf); +} +#endif + +#ifdef HAVE_X11_Xext +# include +# include + +static int test_Xext(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ret = XMissingExtension(dpy, "cmake"); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xxf86misc +# include +# include + +static Bool test_Xxf86misc(void) +{ + Display* dpy = XOpenDisplay(NULL); + Bool ret = XF86MiscSetClientVersion(dpy); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xxf86vm +# include +# include + +static Bool test_Xxf86vm(void) +{ + Display* dpy = XOpenDisplay(NULL); + Bool ret = XF86VidModeSetClientVersion(dpy); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xfixes +# include + +static Bool test_Xfixes(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XFixesQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xft +# include + +static FcBool test_Xft(void) +{ + return XftInitFtLibrary(); +} +#endif + +#ifdef HAVE_X11_Xi +# include + +static XExtensionVersion* test_Xi(void) +{ + Display* dpy = XOpenDisplay(NULL); + XExtensionVersion* ret = XGetExtensionVersion(dpy, "cmake"); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xinerama +# include + +static Bool test_Xinerama(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XineramaQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xkb +# include + +static Bool test_Xkb(void) +{ + return XkbIgnoreExtension(0); +} +#endif + +#ifdef HAVE_X11_xkbfile +# include + +# include +# include + +# include + +static void test_xkbfile(void) +{ + Display* dpy = XOpenDisplay(NULL); + XkbInitAtoms(dpy); + XCloseDisplay(dpy); +} +#endif + +#ifdef HAVE_X11_Xmu +# include + +# include + +static Bool test_Xmu(void) +{ + return XmuValidArea(NULL); +} +#endif + +#ifdef HAVE_X11_Xpm +# include + +static int test_Xpm(void) +{ + return XpmAttributesSize(); +} +#endif + +#ifdef HAVE_X11_Xtst +# include + +static Status test_Xtst(void) +{ + Display* dpy = XOpenDisplay(NULL); + Status ret = XTestDiscard(dpy); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xrandr +# include + +static Bool test_Xrandr(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XRRQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xrender +# include + +static Bool test_Xrender(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XRenderQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_XRes +# include +# include + +static Bool test_XRes(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XResQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xss +# include + +static Bool test_Xss(void) +{ + Display* dpy = XOpenDisplay(NULL); + int ev_base; + int err_base; + Bool ret = XScreenSaverQueryExtension(dpy, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#ifdef HAVE_X11_Xt +# include + +static void test_Xt(void) +{ + return XtToolkitInitialize(); +} +#endif + +#ifdef HAVE_X11_Xutil +# include + +static int test_Xutil(void) +{ + Region r = XCreateRegion(); + return XDestroyRegion(r); +} +#endif + +#ifdef HAVE_X11_Xv +# include +# include + +static int test_Xv(void) +{ + Display* dpy = XOpenDisplay(NULL); + unsigned int version; + unsigned int revision; + unsigned int req_base; + unsigned int ev_base; + unsigned int err_base; + int ret = + XvQueryExtension(dpy, &version, &revision, &req_base, &ev_base, &err_base); + XCloseDisplay(dpy); + return ret; +} +#endif + +#include + +int main(int argc, char* argv[]) +{ + (void)argv; + void* fptrs[] = { +#ifdef HAVE_X11_ICE + test_ICE, +#endif +#ifdef HAVE_X11_SM + test_SM, +#endif +#ifdef HAVE_X11_X11 + test_X11, +#endif +#ifdef HAVE_X11_Xau + test_Xau, +#endif +#ifdef HAVE_X11_Xcomposite + test_Xcomposite, +#endif +#ifdef HAVE_X11_Xdamage + test_Xdamage, +#endif +#ifdef HAVE_X11_Xdmcp + test_Xdmcp, +#endif +#ifdef HAVE_X11_Xext + test_Xext, +#endif +#ifdef HAVE_X11_Xxf86misc + test_Xxf86misc, +#endif +#ifdef HAVE_X11_Xxf86vm + test_Xxf86vm, +#endif +#ifdef HAVE_X11_Xfixes + test_Xfixes, +#endif +#ifdef HAVE_X11_Xft + test_Xft, +#endif +#ifdef HAVE_X11_Xi + test_Xi, +#endif +#ifdef HAVE_X11_Xinerama + test_Xinerama, +#endif +#ifdef HAVE_X11_Xkb + test_Xkb, +#endif +#ifdef HAVE_X11_xkbfile + test_xkbfile, +#endif +#ifdef HAVE_X11_Xmu + test_Xmu, +#endif +#ifdef HAVE_X11_Xpm + test_Xpm, +#endif +#ifdef HAVE_X11_Xtst + test_Xtst, +#endif +#ifdef HAVE_X11_Xrandr + test_Xrandr, +#endif +#ifdef HAVE_X11_Xrender + test_Xrender, +#endif +#ifdef HAVE_X11_XRes + test_XRes, +#endif +#ifdef HAVE_X11_Xss + test_Xss, +#endif +#ifdef HAVE_X11_Xt + test_Xt, +#endif +#ifdef HAVE_X11_Xutil + test_Xutil, +#endif +#ifdef HAVE_X11_Xv + test_Xv, +#endif + NULL, + }; + + // The code here is to convince the compiler to keep the static functions but + // without calling them. This ends up always being "0" because `argc` is + // always 1 in the test harness which always returns the sentinel at the end + // of the array. The array logic is there to ensure that the contents of + // `fptrs` is not optimized out. + return (int)fptrs[(sizeof(fptrs) / sizeof(*fptrs)) - argc]; +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a7d2ffb2325478e4d242e3b7338f8ca1c1898ff7 commit a7d2ffb2325478e4d242e3b7338f8ca1c1898ff7 Author: Ben Boeckel AuthorDate: Mon Nov 12 15:51:08 2018 -0500 Commit: Ben Boeckel CommitDate: Tue Nov 13 10:22:00 2018 -0500 FindX11: add imported targets These imported targets are fine-grained and recommended over the global `X11_LIBRARIES` and `X11_INCLUDE_DIR` variables. diff --git a/Help/release/dev/FindX11-imported-targets.rst b/Help/release/dev/FindX11-imported-targets.rst index 495795c..4df753d 100644 --- a/Help/release/dev/FindX11-imported-targets.rst +++ b/Help/release/dev/FindX11-imported-targets.rst @@ -29,3 +29,4 @@ FindX11-imported-targets - ``X11_Xinput_FOUND`` (use ``X11_Xi_FOUND``) * The :module:`FindX11` now provides ``X11_Xext_INCLUDE_PATH``. +* The :module:`FindX11` now provides imported targets. diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 01a9ef7..46a7449 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -15,42 +15,43 @@ Try to find X11 on UNIX systems. The following values are defined X11_INCLUDE_DIR - include directories to use X11 X11_LIBRARIES - link against these to use X11 -and also the following more fine grained variables: +and also the following more fine grained variables and targets: :: - X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND - X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND - X11_X11_INCLUDE_PATH, X11_X11_LIB + X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND, X11::ICE + X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND, X11::SM + X11_X11_INCLUDE_PATH, X11_X11_LIB, X11::X11 X11_Xaccessrules_INCLUDE_PATH, X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND - X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND - X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND - X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND - X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND - X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND - X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND + X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND, X11::Xau + X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite + X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor + X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND, X11::Xdamage + X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND, X11::Xdmcp + X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND, X11::Xext + X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND, X11::Xxf86misc + X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND, X11::Xxf86vm + X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND, X11::Xfixes + X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND, X11::Xft + X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND, X11::Xi + X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND, X11::Xinerama + X11_Xkb_INCLUDE_PATH, + X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND, X11::Xkb + X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND, X11::xkbfile + X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND, X11::Xmu + X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND, X11::Xpm + X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND, X11::Xtst + X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND, X11::Xrandr + X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND, X11::Xrender + X11_XRes_INCLUDE_PATH, X11_XRes_LIB, X11_XRes_FOUND, X11::XRes + X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND, X11::Xss + X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND, X11::Xt + X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND, X11::Xutil + X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND, X11::Xv X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND - X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND - X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND - X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND - X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND - X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND - X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND - X11_Xkb_INCLUDE_PATH, X11_Xkb_FOUND - X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND - X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND - X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND - X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND - X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND - X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND - X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND - X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND - X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND - X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND - X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND #]=======================================================================] @@ -361,6 +362,11 @@ if (UNIX) set(X11_FOUND 1) endif () + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + find_package_handle_standard_args(X11 + REQUIRED_VARS X11_X11_INCLUDE_PATH X11_X11_LIB + HANDLE_COMPONENTS) + if(X11_FOUND) include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake) @@ -443,15 +449,218 @@ if (UNIX) # Build the final list of libraries. set(X11_LIBRARIES ${X11_X_PRE_LIBS} ${X11_LIBRARIES} ${X11_X_EXTRA_LIBS}) - include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - find_package_message(X11 "Found X11: ${X11_X11_LIB}" - "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") - else () - if (X11_FIND_REQUIRED) - message(FATAL_ERROR "Could not find X11") + if (NOT TARGET X11::X11) + add_library(X11::X11 UNKNOWN IMPORTED) + set_target_properties(X11::X11 PROPERTIES + IMPORTED_LOCATION "${X11_X11_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_X11_INCLUDE_PATH}") endif () endif () + if (X11_ICE_FOUND AND NOT TARGET X11::ICE) + add_library(X11::ICE UNKNOWN IMPORTED) + set_target_properties(X11::ICE PROPERTIES + IMPORTED_LOCATION "${X11_ICE_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_ICE_INCLUDE_PATH}") + endif () + + if (X11_SM_FOUND AND NOT TARGET X11::SM) + add_library(X11::SM UNKNOWN IMPORTED) + set_target_properties(X11::SM PROPERTIES + IMPORTED_LOCATION "${X11_SM_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_SM_INCLUDE_PATH}") + endif () + + if (X11_Xau_FOUND AND NOT TARGET X11::Xau) + add_library(X11::Xau UNKNOWN IMPORTED) + set_target_properties(X11::Xau PROPERTIES + IMPORTED_LOCATION "${X11_Xau_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xau_INCLUDE_PATH}") + endif () + + if (X11_Xcomposite_FOUND AND NOT TARGET X11::Xcomposite) + add_library(X11::Xcomposite UNKNOWN IMPORTED) + set_target_properties(X11::Xcomposite PROPERTIES + IMPORTED_LOCATION "${X11_Xcomposite_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xcomposite_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xcursor_FOUND AND NOT TARGET X11::Xcursor) + add_library(X11::Xcursor UNKNOWN IMPORTED) + set_target_properties(X11::Xcursor PROPERTIES + IMPORTED_LOCATION "${X11_Xcursor_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xcursor_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xrender;X11::Xfixes;X11::X11") + endif () + + if (X11_Xdamage_FOUND AND NOT TARGET X11::Xdamage) + add_library(X11::Xdamage UNKNOWN IMPORTED) + set_target_properties(X11::Xdamage PROPERTIES + IMPORTED_LOCATION "${X11_Xdamage_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xdamage_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xfixes;X11::X11") + endif () + + if (X11_Xdmcp_FOUND AND NOT TARGET X11::Xdmcp) + add_library(X11::Xdmcp UNKNOWN IMPORTED) + set_target_properties(X11::Xdmcp PROPERTIES + IMPORTED_LOCATION "${X11_Xdmcp_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xdmcp_INCLUDE_PATH}") + endif () + + if (X11_Xext_FOUND AND NOT TARGET X11::Xext) + add_library(X11::Xext UNKNOWN IMPORTED) + set_target_properties(X11::Xext PROPERTIES + IMPORTED_LOCATION "${X11_Xext_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xext_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xxf86misc_FOUND AND NOT TARGET X11::Xxf86misc) + add_library(X11::Xxf86misc UNKNOWN IMPORTED) + set_target_properties(X11::Xxf86misc PROPERTIES + IMPORTED_LOCATION "${X11_Xxf86misc_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xxf86misc_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11;X11::Xext") + endif () + + if (X11_Xxf86vm_FOUND AND NOT TARGET X11::Xxf86vm) + add_library(X11::Xxf86vm UNKNOWN IMPORTED) + set_target_properties(X11::Xxf86vm PROPERTIES + IMPORTED_LOCATION "${X11_Xxf86vm_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xxf86vm_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11;X11::Xext") + endif () + + if (X11_Xfixes_FOUND AND NOT TARGET X11::Xfixes) + add_library(X11::Xfixes UNKNOWN IMPORTED) + set_target_properties(X11::Xfixes PROPERTIES + IMPORTED_LOCATION "${X11_Xfixes_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xfixes_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xft_FOUND AND NOT TARGET X11::Xft) + add_library(X11::Xft UNKNOWN IMPORTED) + set_target_properties(X11::Xft PROPERTIES + IMPORTED_LOCATION "${X11_Xft_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xft_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xrender;X11::X11;Fontconfig::Fontconfig;Freetype::Freetype") + endif () + + if (X11_Xi_FOUND AND NOT TARGET X11::Xi) + add_library(X11::Xi UNKNOWN IMPORTED) + set_target_properties(X11::Xi PROPERTIES + IMPORTED_LOCATION "${X11_Xi_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xi_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xext;X11::X11") + endif () + + if (X11_Xinerama_FOUND AND NOT TARGET X11::Xinerama) + add_library(X11::Xinerama UNKNOWN IMPORTED) + set_target_properties(X11::Xinerama PROPERTIES + IMPORTED_LOCATION "${X11_Xinerama_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xinerama_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xext;X11::X11") + endif () + + if (X11_Xkb_FOUND AND NOT TARGET X11::Xkb) + add_library(X11::Xkb INTERFACE IMPORTED) + set_target_properties(X11::Xkb PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xkb_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_xkbfile_FOUND AND NOT TARGET X11::xkbfile) + add_library(X11::xkbfile UNKNOWN IMPORTED) + set_target_properties(X11::xkbfile PROPERTIES + IMPORTED_LOCATION "${X11_xkbfile_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_xkbfile_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xmu_FOUND AND NOT TARGET X11::Xmu) + add_library(X11::Xmu UNKNOWN IMPORTED) + set_target_properties(X11::Xmu PROPERTIES + IMPORTED_LOCATION "${X11_Xmu_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xmu_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xt;X11::Xext;X11::X11") + endif () + + if (X11_Xpm_FOUND AND NOT TARGET X11::Xpm) + add_library(X11::Xpm UNKNOWN IMPORTED) + set_target_properties(X11::Xpm PROPERTIES + IMPORTED_LOCATION "${X11_Xpm_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xpm_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xtst_FOUND AND NOT TARGET X11::Xtst) + add_library(X11::Xtst UNKNOWN IMPORTED) + set_target_properties(X11::Xtst PROPERTIES + IMPORTED_LOCATION "${X11_Xtst_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xtst_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xi;X11::Xext;X11::X11") + endif () + + if (X11_Xrandr_FOUND AND NOT TARGET X11::Xrandr) + add_library(X11::Xrandr UNKNOWN IMPORTED) + set_target_properties(X11::Xrandr PROPERTIES + IMPORTED_LOCATION "${X11_Xrandr_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xrandr_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xrender;X11::Xext;X11::X11") + endif () + + if (X11_Xrender_FOUND AND NOT TARGET X11::Xrender) + add_library(X11::Xrender UNKNOWN IMPORTED) + set_target_properties(X11::Xrender PROPERTIES + IMPORTED_LOCATION "${X11_Xrender_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xrender_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_XRes_FOUND AND NOT TARGET X11::XRes) + add_library(X11::XRes UNKNOWN IMPORTED) + set_target_properties(X11::XRes PROPERTIES + IMPORTED_LOCATION "${X11_XRes_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_XRes_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xext;X11::X11") + endif () + + if (X11_Xss_FOUND AND NOT TARGET X11::Xss) + add_library(X11::Xss UNKNOWN IMPORTED) + set_target_properties(X11::Xss PROPERTIES + IMPORTED_LOCATION "${X11_Xss_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xss_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xext;X11::X11") + endif () + + if (X11_Xt_FOUND AND NOT TARGET X11::Xt) + add_library(X11::Xt UNKNOWN IMPORTED) + set_target_properties(X11::Xt PROPERTIES + IMPORTED_LOCATION "${X11_Xt_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xt_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::ICE;X11::SM;X11::X11") + endif () + + if (X11_Xutil_FOUND AND NOT TARGET X11::Xutil) + add_library(X11::Xutil INTERFACE IMPORTED) + set_target_properties(X11::Xutil PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xutil_INCLUDE_PATH}" + # libX11 contains the implementations for functions in the Xutil.h + # header. + INTERFACE_LINK_LIBRARIES "X11::X11") + endif () + + if (X11_Xv_FOUND AND NOT TARGET X11::Xv) + add_library(X11::Xv UNKNOWN IMPORTED) + set_target_properties(X11::Xv PROPERTIES + IMPORTED_LOCATION "${X11_Xv_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${X11_Xv_INCLUDE_PATH}" + INTERFACE_LINK_LIBRARIES "X11::Xext;X11::X11") + endif () + mark_as_advanced( X11_X11_INCLUDE_PATH X11_X11_LIB @@ -518,5 +727,3 @@ if (UNIX) set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE}) set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) endif () - -# X11_FIND_REQUIRED_ could be checked too https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=40b3dba52995e2c0275ae1712a169173aed6fcbf commit 40b3dba52995e2c0275ae1712a169173aed6fcbf Author: Ben Boeckel AuthorDate: Mon Nov 12 15:50:05 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 16:10:14 2018 -0500 FindX11: require Freetype and Fontconfig for Xft The Xft header includes headers from freetype and fontconfig, so they are necessary for its use. diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 8a18d4d..01a9ef7 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -203,7 +203,11 @@ if (UNIX) endif() if(X11_Xft_LIB AND X11_Xft_INCLUDE_PATH) - set(X11_Xft_FOUND TRUE) + find_package(Freetype QUIET) + find_package(Fontconfig QUIET) + if (FREETYPE_FOUND AND FONTCONFIG_FOUND) + set(X11_Xft_FOUND TRUE) + endif () list(APPEND X11_INCLUDE_DIR ${X11_Xft_INCLUDE_PATH}) endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cc96249e2eee63e90999b1d6cb87dd355696a355 commit cc96249e2eee63e90999b1d6cb87dd355696a355 Author: Ben Boeckel AuthorDate: Mon Nov 12 15:49:52 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 16:10:14 2018 -0500 FindX11: remove local variable from the advanced list diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index b7ab0b0..8a18d4d 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -459,7 +459,6 @@ if (UNIX) X11_Xutil_INCLUDE_PATH X11_Xcomposite_INCLUDE_PATH X11_Xcomposite_LIB - X11_Xaccess_INCLUDE_PATH X11_Xfixes_LIB X11_Xfixes_INCLUDE_PATH X11_Xrandr_LIB https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=99489d9f10ac23da29c0ed2ed9bd371946df0991 commit 99489d9f10ac23da29c0ed2ed9bd371946df0991 Author: Ben Boeckel AuthorDate: Mon Nov 12 15:49:33 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 16:10:13 2018 -0500 FindX11: find Xext.h diff --git a/Help/release/dev/FindX11-imported-targets.rst b/Help/release/dev/FindX11-imported-targets.rst index 859a5c0..495795c 100644 --- a/Help/release/dev/FindX11-imported-targets.rst +++ b/Help/release/dev/FindX11-imported-targets.rst @@ -27,3 +27,5 @@ FindX11-imported-targets - ``X11_Xinput_INCLUDE_PATH`` (use ``X11_Xi_INCLUDE_PATH``) - ``X11_Xinput_LIB`` (use ``X11_Xi_LIB``) - ``X11_Xinput_FOUND`` (use ``X11_Xi_FOUND``) + +* The :module:`FindX11` now provides ``X11_Xext_INCLUDE_PATH``. diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index e425008..b7ab0b0 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -29,7 +29,7 @@ and also the following more fine grained variables: X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND - X11_Xext_LIB, X11_Xext_FOUND + X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND @@ -97,6 +97,7 @@ if (UNIX) find_path(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xdmcp_INCLUDE_PATH X11/Xdmcp.h ${X11_INC_SEARCH_PATH}) + find_path(X11_Xext_INCLUDE_PATH X11/extensions/Xext.h ${X11_INC_SEARCH_PATH}) find_path(X11_dpms_INCLUDE_PATH X11/extensions/dpms.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xxf86misc_INCLUDE_PATH X11/extensions/xf86misc.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xxf86vm_INCLUDE_PATH X11/extensions/xf86vmode.h ${X11_INC_SEARCH_PATH}) @@ -450,6 +451,7 @@ if (UNIX) mark_as_advanced( X11_X11_INCLUDE_PATH X11_X11_LIB + X11_Xext_INCLUDE_PATH X11_Xext_LIB X11_Xau_LIB X11_Xau_INCLUDE_PATH https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b8b598061a3968bcf3998040a3ca76a085592c83 commit b8b598061a3968bcf3998040a3ca76a085592c83 Author: Ben Boeckel AuthorDate: Mon Nov 12 14:18:34 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 16:09:36 2018 -0500 FindX11: match variables with library names This deprecates various variables, but provides them for backwards compatibility. diff --git a/Help/release/dev/FindX11-imported-targets.rst b/Help/release/dev/FindX11-imported-targets.rst new file mode 100644 index 0000000..859a5c0 --- /dev/null +++ b/Help/release/dev/FindX11-imported-targets.rst @@ -0,0 +1,29 @@ +FindX11-imported-targets +------------------------ + +* The :module:`FindX11` had the following variables renamed in order to match + their library names rather than header names. The old variables are provided + for compatibility: + + - ``X11_Xxf86misc_INCLUDE_PATH`` instead of ``X11_xf86misc_INCLUDE_PATH`` + - ``X11_Xxf86misc_LIB`` instead of ``X11_xf86misc_LIB`` + - ``X11_Xxf86misc_FOUND`` instead of ``X11_xf86misc_FOUND`` + - ``X11_Xxf86vm_INCLUDE_PATH`` instead of ``X11_xf86vmode_INCLUDE_PATH`` + - ``X11_Xxf86vm_LIB`` instead of ``X11_xf86vmode_LIB`` + - ``X11_Xxf86vm_FOUND`` instead of ``X11_xf86vmode_FOUND`` + - ``X11_xkbfile_INCLUDE_PATH`` instead of ``X11_Xkbfile_INCLUDE_PATH`` + - ``X11_xkbfile_LIB`` instead of ``X11_Xkbfile_LIB`` + - ``X11_xkbfile_FOUND`` instead of ``X11_Xkbfile_FOUND`` + - ``X11_Xtst_INCLUDE_PATH`` instead of ``X11_XTest_INCLUDE_PATH`` + - ``X11_Xtst_LIB`` instead of ``X11_XTest_LIB`` + - ``X11_Xtst_FOUND`` instead of ``X11_XTest_FOUND`` + - ``X11_Xss_INCLUDE_PATH`` instead of ``X11_Xscreensaver_INCLUDE_PATH`` + - ``X11_Xss_LIB`` instead of ``X11_Xscreensaver_LIB`` + - ``X11_Xss_FOUND`` instead of ``X11_Xscreensaver_FOUND`` + + The following variables are deprecated completely since they were + essentially duplicates: + + - ``X11_Xinput_INCLUDE_PATH`` (use ``X11_Xi_INCLUDE_PATH``) + - ``X11_Xinput_LIB`` (use ``X11_Xi_LIB``) + - ``X11_Xinput_FOUND`` (use ``X11_Xi_FOUND``) diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 22a63d7..e425008 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -33,22 +33,21 @@ and also the following more fine grained variables: X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND - X11_xf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_xf86misc_FOUND - X11_xf86vmode_INCLUDE_PATH, X11_Xxf86vm_LIB X11_xf86vmode_FOUND + X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND + X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND - X11_Xinput_INCLUDE_PATH, X11_Xinput_LIB, X11_Xinput_FOUND X11_Xkb_INCLUDE_PATH, X11_Xkb_FOUND X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND - X11_Xkbfile_INCLUDE_PATH, X11_Xkbfile_LIB, X11_Xkbfile_FOUND + X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND - X11_XTest_INCLUDE_PATH, X11_XTest_LIB, X11_XTest_FOUND + X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND - X11_Xscreensaver_INCLUDE_PATH, X11_Xscreensaver_LIB, X11_Xscreensaver_FOUND + X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND @@ -99,30 +98,36 @@ if (UNIX) find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xdmcp_INCLUDE_PATH X11/Xdmcp.h ${X11_INC_SEARCH_PATH}) find_path(X11_dpms_INCLUDE_PATH X11/extensions/dpms.h ${X11_INC_SEARCH_PATH}) - find_path(X11_xf86misc_INCLUDE_PATH X11/extensions/xf86misc.h ${X11_INC_SEARCH_PATH}) - find_path(X11_xf86vmode_INCLUDE_PATH X11/extensions/xf86vmode.h ${X11_INC_SEARCH_PATH}) + find_path(X11_Xxf86misc_INCLUDE_PATH X11/extensions/xf86misc.h ${X11_INC_SEARCH_PATH}) + find_path(X11_Xxf86vm_INCLUDE_PATH X11/extensions/xf86vmode.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xfixes_INCLUDE_PATH X11/extensions/Xfixes.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xft_INCLUDE_PATH X11/Xft/Xft.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xi_INCLUDE_PATH X11/extensions/XInput.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xinerama_INCLUDE_PATH X11/extensions/Xinerama.h ${X11_INC_SEARCH_PATH}) - find_path(X11_Xinput_INCLUDE_PATH X11/extensions/XInput.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xkb_INCLUDE_PATH X11/extensions/XKB.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xkblib_INCLUDE_PATH X11/XKBlib.h ${X11_INC_SEARCH_PATH}) - find_path(X11_Xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h ${X11_INC_SEARCH_PATH}) + find_path(X11_xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xmu_INCLUDE_PATH X11/Xmu/Xmu.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xpm_INCLUDE_PATH X11/xpm.h ${X11_INC_SEARCH_PATH}) - find_path(X11_XTest_INCLUDE_PATH X11/extensions/XTest.h ${X11_INC_SEARCH_PATH}) + find_path(X11_Xtst_INCLUDE_PATH X11/extensions/XTest.h ${X11_INC_SEARCH_PATH}) find_path(X11_XShm_INCLUDE_PATH X11/extensions/XShm.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xrandr_INCLUDE_PATH X11/extensions/Xrandr.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xrender_INCLUDE_PATH X11/extensions/Xrender.h ${X11_INC_SEARCH_PATH}) find_path(X11_XRes_INCLUDE_PATH X11/extensions/XRes.h ${X11_INC_SEARCH_PATH}) - find_path(X11_Xscreensaver_INCLUDE_PATH X11/extensions/scrnsaver.h ${X11_INC_SEARCH_PATH}) + find_path(X11_Xss_INCLUDE_PATH X11/extensions/scrnsaver.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xshape_INCLUDE_PATH X11/extensions/shape.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xutil_INCLUDE_PATH X11/Xutil.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xt_INCLUDE_PATH X11/Intrinsic.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xv_INCLUDE_PATH X11/extensions/Xvlib.h ${X11_INC_SEARCH_PATH}) find_path(X11_XSync_INCLUDE_PATH X11/extensions/sync.h ${X11_INC_SEARCH_PATH}) + # Backwards compatibility. + set(X11_Xinput_INCLUDE_PATH "${X11_Xi_INCLUDE_PATH}") + set(X11_xf86misc_INCLUDE_PATH "${X11_Xxf86misc_INCLUDE_PATH}") + set(X11_xf86vmode_INCLUDE_PATH "${X11_Xxf8vm_INCLUDE_PATH}") + set(X11_Xkbfile_INCLUDE_PATH "${X11_xkbfile_INCLUDE_PATH}") + set(X11_XTest_INCLUDE_PATH "${X11_Xtst_INCLUDE_PATH}") + set(X11_Xscreensaver_INCLUDE_PATH "${X11_Xss_INCLUDE_PATH}") find_library(X11_X11_LIB X11 ${X11_LIB_SEARCH_PATH}) @@ -139,20 +144,25 @@ if (UNIX) find_library(X11_Xft_LIB Xft ${X11_LIB_SEARCH_PATH}) find_library(X11_Xi_LIB Xi ${X11_LIB_SEARCH_PATH}) find_library(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH}) - find_library(X11_Xinput_LIB Xi ${X11_LIB_SEARCH_PATH}) - find_library(X11_Xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH}) + find_library(X11_xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH}) find_library(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH}) find_library(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH}) find_library(X11_Xrandr_LIB Xrandr ${X11_LIB_SEARCH_PATH}) find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH}) find_library(X11_XRes_LIB XRes ${X11_LIB_SEARCH_PATH}) - find_library(X11_Xscreensaver_LIB Xss ${X11_LIB_SEARCH_PATH}) + find_library(X11_Xss_LIB Xss ${X11_LIB_SEARCH_PATH}) find_library(X11_Xt_LIB Xt ${X11_LIB_SEARCH_PATH}) - find_library(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH}) + find_library(X11_Xtst_LIB Xtst ${X11_LIB_SEARCH_PATH}) find_library(X11_Xv_LIB Xv ${X11_LIB_SEARCH_PATH}) find_library(X11_Xxf86misc_LIB Xxf86misc ${X11_LIB_SEARCH_PATH}) find_library(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH}) + # Backwards compatibility. + set(X11_Xinput_LIB "${X11_Xi_LIB}") + set(X11_Xkbfile_LIB "${X11_xkbfile_LIB}") + set(X11_XTest_LIB "${X11_Xtst_LIB}") + set(X11_Xscreensaver_LIB "${X11_Xss_LIB}") + set(X11_LIBRARY_DIR "") if(X11_X11_LIB) get_filename_component(X11_LIBRARY_DIR ${X11_X11_LIB} PATH) @@ -236,13 +246,17 @@ if (UNIX) list(APPEND X11_INCLUDE_DIR ${X11_XShm_INCLUDE_PATH}) endif () - if (X11_XTest_INCLUDE_PATH AND X11_XTest_LIB) + if (X11_Xtst_INCLUDE_PATH AND X11_Xtst_LIB) + set(X11_Xtst_FOUND TRUE) + # Backwards compatibility. set(X11_XTest_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_XTest_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xtst_INCLUDE_PATH}) endif () if (X11_Xi_INCLUDE_PATH AND X11_Xi_LIB) set(X11_Xi_FOUND TRUE) + # Backwards compatibility. + set(X11_Xinput_FOUND TRUE) list(APPEND X11_INCLUDE_DIR ${X11_Xi_INCLUDE_PATH}) endif () @@ -271,14 +285,18 @@ if (UNIX) list(APPEND X11_INCLUDE_DIR ${X11_Xrandr_INCLUDE_PATH}) endif () - if (X11_xf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB) + if (X11_Xxf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB) + set(X11_Xxf86misc_FOUND TRUE) + # Backwards compatibility. set(X11_xf86misc_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_xf86misc_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xxf86misc_INCLUDE_PATH}) endif () - if (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB) + if (X11_Xxf86vm_INCLUDE_PATH AND X11_Xxf86vm_LIB) + set(X11_Xxf86vm_FOUND TRUE) + # Backwards compatibility. set(X11_xf86vmode_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_xf86vmode_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xxf86vm_INCLUDE_PATH}) endif () if (X11_Xcursor_INCLUDE_PATH AND X11_Xcursor_LIB) @@ -286,9 +304,10 @@ if (UNIX) list(APPEND X11_INCLUDE_DIR ${X11_Xcursor_INCLUDE_PATH}) endif () - if (X11_Xscreensaver_INCLUDE_PATH AND X11_Xscreensaver_LIB) + if (X11_Xss_INCLUDE_PATH AND X11_Xss_LIB) + set(X11_Xss_FOUND TRUE) set(X11_Xscreensaver_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_Xscreensaver_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xss_INCLUDE_PATH}) endif () if (X11_dpms_INCLUDE_PATH) @@ -301,9 +320,11 @@ if (UNIX) list(APPEND X11_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH} ) endif () - if (X11_Xkbfile_INCLUDE_PATH AND X11_Xkbfile_LIB AND X11_Xlib_INCLUDE_PATH) + if (X11_xkbfile_INCLUDE_PATH AND X11_xkbfile_LIB AND X11_Xlib_INCLUDE_PATH) + set(X11_xkbfile_FOUND TRUE) + # Backwards compatibility. set(X11_Xkbfile_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_Xkbfile_INCLUDE_PATH} ) + list(APPEND X11_INCLUDE_DIR ${X11_xkbfile_INCLUDE_PATH} ) endif () if (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB) @@ -311,11 +332,6 @@ if (UNIX) list(APPEND X11_INCLUDE_DIR ${X11_Xmu_INCLUDE_PATH}) endif () - if (X11_Xinput_INCLUDE_PATH AND X11_Xinput_LIB) - set(X11_Xinput_FOUND TRUE) - list(APPEND X11_INCLUDE_DIR ${X11_Xinput_INCLUDE_PATH}) - endif () - if (X11_XSync_INCLUDE_PATH) set(X11_XSync_FOUND TRUE) list(APPEND X11_INCLUDE_DIR ${X11_XSync_INCLUDE_PATH}) @@ -453,15 +469,15 @@ if (UNIX) X11_XRes_LIB X11_XRes_INCLUDE_PATH X11_Xxf86misc_LIB - X11_xf86misc_INCLUDE_PATH + X11_Xxf86misc_INCLUDE_PATH X11_Xxf86vm_LIB - X11_xf86vmode_INCLUDE_PATH + X11_Xxf86vm_INCLUDE_PATH X11_Xi_LIB X11_Xi_INCLUDE_PATH X11_Xinerama_LIB X11_Xinerama_INCLUDE_PATH - X11_XTest_LIB - X11_XTest_INCLUDE_PATH + X11_Xtst_LIB + X11_Xtst_INCLUDE_PATH X11_Xcursor_LIB X11_Xcursor_INCLUDE_PATH X11_dpms_INCLUDE_PATH @@ -474,16 +490,14 @@ if (UNIX) X11_Xdmcp_INCLUDE_PATH X11_Xkb_INCLUDE_PATH X11_Xkblib_INCLUDE_PATH - X11_Xkbfile_INCLUDE_PATH - X11_Xkbfile_LIB + X11_xkbfile_INCLUDE_PATH + X11_xkbfile_LIB X11_Xmu_INCLUDE_PATH X11_Xmu_LIB - X11_Xscreensaver_INCLUDE_PATH - X11_Xscreensaver_LIB + X11_Xss_INCLUDE_PATH + X11_Xss_LIB X11_Xpm_INCLUDE_PATH X11_Xpm_LIB - X11_Xinput_LIB - X11_Xinput_INCLUDE_PATH X11_Xft_LIB X11_Xft_INCLUDE_PATH X11_Xshape_INCLUDE_PATH https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6079a0d00f38a27e17c9d07465e108d9e1f34960 commit 6079a0d00f38a27e17c9d07465e108d9e1f34960 Author: Ben Boeckel AuthorDate: Mon Nov 12 14:17:53 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 14:42:56 2018 -0500 FindX11: fix some formatting in the documentation diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 515932e..22a63d7 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -22,14 +22,14 @@ and also the following more fine grained variables: X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND X11_X11_INCLUDE_PATH, X11_X11_LIB - X11_Xaccessrules_INCLUDE_PATH, X11_Xaccess_FOUND + X11_Xaccessrules_INCLUDE_PATH, X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND - X11_Xext_LIB, X11_Xext_FOUND + X11_Xext_LIB, X11_Xext_FOUND X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3c54955d0d6c994e36cd128ee7b7b286b0425148 commit 3c54955d0d6c994e36cd128ee7b7b286b0425148 Author: Ben Boeckel AuthorDate: Mon Nov 12 11:56:32 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 13:30:07 2018 -0500 FindX11: use `list(APPEND)` for clearer code diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index e7dcff6..515932e 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -160,31 +160,31 @@ if (UNIX) set(X11_INCLUDE_DIR) # start with empty list if(X11_X11_INCLUDE_PATH) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_X11_INCLUDE_PATH}) endif() if(X11_Xlib_INCLUDE_PATH) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xlib_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xlib_INCLUDE_PATH}) endif() if(X11_Xutil_INCLUDE_PATH) set(X11_Xutil_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xutil_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xutil_INCLUDE_PATH}) endif() if(X11_Xshape_INCLUDE_PATH) set(X11_Xshape_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xshape_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xshape_INCLUDE_PATH}) endif() set(X11_LIBRARIES) # start with empty list if(X11_X11_LIB) - set(X11_LIBRARIES ${X11_LIBRARIES} ${X11_X11_LIB}) + list(APPEND X11_LIBRARIES ${X11_X11_LIB}) endif() if(X11_Xext_LIB) set(X11_Xext_FOUND TRUE) - set(X11_LIBRARIES ${X11_LIBRARIES} ${X11_Xext_LIB}) + list(APPEND X11_LIBRARIES ${X11_Xext_LIB}) endif() if(X11_Xt_LIB AND X11_Xt_INCLUDE_PATH) @@ -193,12 +193,12 @@ if (UNIX) if(X11_Xft_LIB AND X11_Xft_INCLUDE_PATH) set(X11_Xft_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xft_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xft_INCLUDE_PATH}) endif() if(X11_Xv_LIB AND X11_Xv_INCLUDE_PATH) set(X11_Xv_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xv_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xv_INCLUDE_PATH}) endif() if (X11_Xau_LIB AND X11_Xau_INCLUDE_PATH) @@ -207,118 +207,118 @@ if (UNIX) if (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB) set(X11_Xdmcp_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xdmcp_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xdmcp_INCLUDE_PATH}) endif () if (X11_Xaccessrules_INCLUDE_PATH AND X11_Xaccessstr_INCLUDE_PATH) set(X11_Xaccess_FOUND TRUE) set(X11_Xaccess_INCLUDE_PATH ${X11_Xaccessstr_INCLUDE_PATH}) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xaccess_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xaccess_INCLUDE_PATH}) endif () if (X11_Xpm_INCLUDE_PATH AND X11_Xpm_LIB) set(X11_Xpm_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xpm_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xpm_INCLUDE_PATH}) endif () if (X11_Xcomposite_INCLUDE_PATH AND X11_Xcomposite_LIB) set(X11_Xcomposite_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xcomposite_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xcomposite_INCLUDE_PATH}) endif () if (X11_Xdamage_INCLUDE_PATH AND X11_Xdamage_LIB) set(X11_Xdamage_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xdamage_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xdamage_INCLUDE_PATH}) endif () if (X11_XShm_INCLUDE_PATH) set(X11_XShm_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XShm_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_XShm_INCLUDE_PATH}) endif () if (X11_XTest_INCLUDE_PATH AND X11_XTest_LIB) set(X11_XTest_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XTest_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_XTest_INCLUDE_PATH}) endif () if (X11_Xi_INCLUDE_PATH AND X11_Xi_LIB) set(X11_Xi_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xi_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xi_INCLUDE_PATH}) endif () if (X11_Xinerama_INCLUDE_PATH AND X11_Xinerama_LIB) set(X11_Xinerama_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xinerama_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xinerama_INCLUDE_PATH}) endif () if (X11_Xfixes_INCLUDE_PATH AND X11_Xfixes_LIB) set(X11_Xfixes_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xfixes_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xfixes_INCLUDE_PATH}) endif () if (X11_Xrender_INCLUDE_PATH AND X11_Xrender_LIB) set(X11_Xrender_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xrender_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xrender_INCLUDE_PATH}) endif () if (X11_XRes_INCLUDE_PATH AND X11_XRes_LIB) set(X11_XRes_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XRes_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_XRes_INCLUDE_PATH}) endif () if (X11_Xrandr_INCLUDE_PATH AND X11_Xrandr_LIB) set(X11_Xrandr_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xrandr_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xrandr_INCLUDE_PATH}) endif () if (X11_xf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB) set(X11_xf86misc_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86misc_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_xf86misc_INCLUDE_PATH}) endif () if (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB) set(X11_xf86vmode_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86vmode_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_xf86vmode_INCLUDE_PATH}) endif () if (X11_Xcursor_INCLUDE_PATH AND X11_Xcursor_LIB) set(X11_Xcursor_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xcursor_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xcursor_INCLUDE_PATH}) endif () if (X11_Xscreensaver_INCLUDE_PATH AND X11_Xscreensaver_LIB) set(X11_Xscreensaver_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xscreensaver_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xscreensaver_INCLUDE_PATH}) endif () if (X11_dpms_INCLUDE_PATH) set(X11_dpms_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_dpms_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_dpms_INCLUDE_PATH}) endif () if (X11_Xkb_INCLUDE_PATH AND X11_Xkblib_INCLUDE_PATH AND X11_Xlib_INCLUDE_PATH) set(X11_Xkb_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xkb_INCLUDE_PATH} ) + list(APPEND X11_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH} ) endif () if (X11_Xkbfile_INCLUDE_PATH AND X11_Xkbfile_LIB AND X11_Xlib_INCLUDE_PATH) set(X11_Xkbfile_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xkbfile_INCLUDE_PATH} ) + list(APPEND X11_INCLUDE_DIR ${X11_Xkbfile_INCLUDE_PATH} ) endif () if (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB) set(X11_Xmu_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xmu_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xmu_INCLUDE_PATH}) endif () if (X11_Xinput_INCLUDE_PATH AND X11_Xinput_LIB) set(X11_Xinput_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xinput_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_Xinput_INCLUDE_PATH}) endif () if (X11_XSync_INCLUDE_PATH) set(X11_XSync_FOUND TRUE) - set(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XSync_INCLUDE_PATH}) + list(APPEND X11_INCLUDE_DIR ${X11_XSync_INCLUDE_PATH}) endif () if(X11_ICE_LIB AND X11_ICE_INCLUDE_PATH) @@ -357,11 +357,11 @@ if (UNIX) # Find library needed for dnet_ntoa. check_library_exists("dnet" "dnet_ntoa" "" X11_LIB_DNET_HAS_DNET_NTOA) if (X11_LIB_DNET_HAS_DNET_NTOA) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet) + list(APPEND X11_X_EXTRA_LIBS -ldnet) else () check_library_exists("dnet_stub" "dnet_ntoa" "" X11_LIB_DNET_STUB_HAS_DNET_NTOA) if (X11_LIB_DNET_STUB_HAS_DNET_NTOA) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet_stub) + list(APPEND X11_X_EXTRA_LIBS -ldnet_stub) endif () endif () endif() @@ -371,11 +371,11 @@ if (UNIX) if(NOT CMAKE_HAVE_GETHOSTBYNAME) check_library_exists("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) if (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl) + list(APPEND X11_X_EXTRA_LIBS -lnsl) else () check_library_exists("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) if (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd) + list(APPEND X11_X_EXTRA_LIBS -lbsd) endif () endif () endif() @@ -385,7 +385,7 @@ if (UNIX) if(NOT CMAKE_HAVE_CONNECT) check_library_exists("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT) if (CMAKE_LIB_SOCKET_HAS_CONNECT) - set (X11_X_EXTRA_LIBS -lsocket ${X11_X_EXTRA_LIBS}) + list(INSERT X11_X_EXTRA_LIBS 0 -lsocket) endif () endif() @@ -394,7 +394,7 @@ if (UNIX) if(NOT CMAKE_HAVE_REMOVE) check_library_exists("posix" "remove" "" CMAKE_LIB_POSIX_HAS_REMOVE) if (CMAKE_LIB_POSIX_HAS_REMOVE) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lposix) + list(APPEND X11_X_EXTRA_LIBS -lposix) endif () endif() @@ -403,7 +403,7 @@ if (UNIX) if(NOT CMAKE_HAVE_SHMAT) check_library_exists("ipc" "shmat" "" CMAKE_LIB_IPS_HAS_SHMAT) if (CMAKE_LIB_IPS_HAS_SHMAT) - set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lipc) + list(APPEND X11_X_EXTRA_LIBS -lipc) endif () endif() endif() @@ -414,7 +414,7 @@ if (UNIX) if(CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER) set (X11_X_PRE_LIBS ${X11_ICE_LIB}) if(X11_SM_LIB) - set (X11_X_PRE_LIBS ${X11_SM_LIB} ${X11_X_PRE_LIBS}) + list(INSERT X11_X_PRE_LIBS 0 ${X11_SM_LIB}) endif() endif() endif () https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1217ff41388e53003424e2f58265ed4321e2030b commit 1217ff41388e53003424e2f58265ed4321e2030b Author: Ben Boeckel AuthorDate: Mon Nov 12 11:50:52 2018 -0500 Commit: Ben Boeckel CommitDate: Mon Nov 12 11:50:52 2018 -0500 FindX11: use lowercase function names diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 232804a..e7dcff6 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -352,14 +352,14 @@ if (UNIX) set(X11_X_EXTRA_LIBS "") # See if XOpenDisplay in X11 works by itself. - CHECK_LIBRARY_EXISTS("${X11_LIBRARIES}" "XOpenDisplay" "${X11_LIBRARY_DIR}" X11_LIB_X11_SOLO) + check_library_exists("${X11_LIBRARIES}" "XOpenDisplay" "${X11_LIBRARY_DIR}" X11_LIB_X11_SOLO) if(NOT X11_LIB_X11_SOLO) # Find library needed for dnet_ntoa. - CHECK_LIBRARY_EXISTS("dnet" "dnet_ntoa" "" X11_LIB_DNET_HAS_DNET_NTOA) + check_library_exists("dnet" "dnet_ntoa" "" X11_LIB_DNET_HAS_DNET_NTOA) if (X11_LIB_DNET_HAS_DNET_NTOA) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet) else () - CHECK_LIBRARY_EXISTS("dnet_stub" "dnet_ntoa" "" X11_LIB_DNET_STUB_HAS_DNET_NTOA) + check_library_exists("dnet_stub" "dnet_ntoa" "" X11_LIB_DNET_STUB_HAS_DNET_NTOA) if (X11_LIB_DNET_STUB_HAS_DNET_NTOA) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet_stub) endif () @@ -367,13 +367,13 @@ if (UNIX) endif() # Find library needed for gethostbyname. - CHECK_FUNCTION_EXISTS("gethostbyname" CMAKE_HAVE_GETHOSTBYNAME) + check_function_exists("gethostbyname" CMAKE_HAVE_GETHOSTBYNAME) if(NOT CMAKE_HAVE_GETHOSTBYNAME) - CHECK_LIBRARY_EXISTS("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) + check_library_exists("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) if (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl) else () - CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) + check_library_exists("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) if (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd) endif () @@ -381,27 +381,27 @@ if (UNIX) endif() # Find library needed for connect. - CHECK_FUNCTION_EXISTS("connect" CMAKE_HAVE_CONNECT) + check_function_exists("connect" CMAKE_HAVE_CONNECT) if(NOT CMAKE_HAVE_CONNECT) - CHECK_LIBRARY_EXISTS("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT) + check_library_exists("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT) if (CMAKE_LIB_SOCKET_HAS_CONNECT) set (X11_X_EXTRA_LIBS -lsocket ${X11_X_EXTRA_LIBS}) endif () endif() # Find library needed for remove. - CHECK_FUNCTION_EXISTS("remove" CMAKE_HAVE_REMOVE) + check_function_exists("remove" CMAKE_HAVE_REMOVE) if(NOT CMAKE_HAVE_REMOVE) - CHECK_LIBRARY_EXISTS("posix" "remove" "" CMAKE_LIB_POSIX_HAS_REMOVE) + check_library_exists("posix" "remove" "" CMAKE_LIB_POSIX_HAS_REMOVE) if (CMAKE_LIB_POSIX_HAS_REMOVE) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lposix) endif () endif() # Find library needed for shmat. - CHECK_FUNCTION_EXISTS("shmat" CMAKE_HAVE_SHMAT) + check_function_exists("shmat" CMAKE_HAVE_SHMAT) if(NOT CMAKE_HAVE_SHMAT) - CHECK_LIBRARY_EXISTS("ipc" "shmat" "" CMAKE_LIB_IPS_HAS_SHMAT) + check_library_exists("ipc" "shmat" "" CMAKE_LIB_IPS_HAS_SHMAT) if (CMAKE_LIB_IPS_HAS_SHMAT) set (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lipc) endif () @@ -409,7 +409,7 @@ if (UNIX) endif() if (X11_ICE_FOUND) - CHECK_LIBRARY_EXISTS("ICE" "IceConnectionNumber" "${X11_LIBRARY_DIR}" + check_library_exists("ICE" "IceConnectionNumber" "${X11_LIBRARY_DIR}" CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER) if(CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER) set (X11_X_PRE_LIBS ${X11_ICE_LIB}) @@ -423,7 +423,7 @@ if (UNIX) set(X11_LIBRARIES ${X11_X_PRE_LIBS} ${X11_LIBRARIES} ${X11_X_EXTRA_LIBS}) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" + find_package_message(X11 "Found X11: ${X11_X11_LIB}" "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") else () if (X11_FIND_REQUIRED) ----------------------------------------------------------------------- Summary of changes: Help/command/macro.rst | 10 +- Help/command/try_compile.rst | 3 +- Help/release/dev/FindX11-imported-targets.rst | 32 ++ Modules/FindX11.cmake | 468 +++++++++++++++++++------- Source/cmCoreTryCompile.cxx | 7 + Tests/CMakeLists.txt | 4 + Tests/{FindPNG => FindX11}/CMakeLists.txt | 8 +- Tests/FindX11/Test/CMakeLists.txt | 89 +++++ Tests/FindX11/Test/main.c | 405 ++++++++++++++++++++++ 9 files changed, 895 insertions(+), 131 deletions(-) create mode 100644 Help/release/dev/FindX11-imported-targets.rst copy Tests/{FindPNG => FindX11}/CMakeLists.txt (55%) create mode 100644 Tests/FindX11/Test/CMakeLists.txt create mode 100644 Tests/FindX11/Test/main.c hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 19 10:53:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 19 Nov 2018 10:53:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-495-g1dc85a6 Message-ID: <20181119155305.3CC5C127B0E@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 1dc85a6652bc8255ff7a9ef39028a7df45e3007b (commit) via 9e1ee3a7c90af46a9c8126e3e5136074db5da490 (commit) via e593161bd5952f7e24e88a368cc0b39c9a2ca795 (commit) via 57701227d68d7add76c119a570adf654af03de95 (commit) via d68409047048f99d28129a60c44a302c8b5e0b8f (commit) from 8866f63f60a46f947fb9a6658944988da84867c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1dc85a6652bc8255ff7a9ef39028a7df45e3007b commit 1dc85a6652bc8255ff7a9ef39028a7df45e3007b Merge: 9e1ee3a e593161 Author: Brad King AuthorDate: Mon Nov 19 10:47:42 2018 -0500 Commit: Brad King CommitDate: Mon Nov 19 10:47:42 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e1ee3a7c90af46a9c8126e3e5136074db5da490 commit 9e1ee3a7c90af46a9c8126e3e5136074db5da490 Merge: 8866f63 5770122 Author: Brad King AuthorDate: Mon Nov 19 15:46:57 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 19 10:47:04 2018 -0500 Merge topic 'backport-configure_file-canonical-deps' 57701227d6 configure_file: canonicalize input and output path in dependencies Acked-by: Kitware Robot Merge-request: !2635 ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 19 10:53:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 19 Nov 2018 10:53:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-13-ge593161 Message-ID: <20181119155305.D3EC7127B17@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via e593161bd5952f7e24e88a368cc0b39c9a2ca795 (commit) via 57701227d68d7add76c119a570adf654af03de95 (commit) via d68409047048f99d28129a60c44a302c8b5e0b8f (commit) via 86e8315482fd8f0bba85af6f4f8363ead6a0818d (commit) via bdec3bd896b6faabab1c7cae79d8e75e8d0f0e41 (commit) from ad6ef6c1d5ba1434215bf9e891c87f71514446e9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/CTest/cmProcess.cxx | 3 ++- Source/cmConfigureFileCommand.cxx | 14 ++++---------- Tests/RunCMake/CMakeLists.txt | 3 ++- Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake | 12 ++++++++++++ Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt | 1 + Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt | 1 + .../Ninja/PreventConfigureFileDupBuildRule.cmake | 5 +++++ Tests/RunCMake/Ninja/RunCMakeTest.cmake | 7 +++++++ .../Ninja/SubDirConfigureFileDup/CMakeLists.txt | 1 + Tests/RunCMake/RunCMake.cmake | 9 +++++++++ Tests/RunCMake/configure_file/DirInput-stderr.txt | 2 +- Tests/RunCMake/print_stdin.c | 18 ++++++++++++++++++ 12 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 Tests/RunCMake/CTestCommandLine/TestStdin-stdin.txt create mode 100644 Tests/RunCMake/CTestCommandLine/TestStdin-stdout.txt create mode 100644 Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake create mode 100644 Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt create mode 100644 Tests/RunCMake/print_stdin.c hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 00:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 00:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-496-gd851a8b Message-ID: <20181120050306.63660127ED6@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via d851a8b457251a577f10055d9fb277b75a82da6c (commit) from 1dc85a6652bc8255ff7a9ef39028a7df45e3007b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d851a8b457251a577f10055d9fb277b75a82da6c commit d851a8b457251a577f10055d9fb277b75a82da6c Author: Kitware Robot AuthorDate: Tue Nov 20 00:01:05 2018 -0500 Commit: Kitware Robot CommitDate: Tue Nov 20 00:01:05 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index eec8d1a..4a312ec 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 13) -set(CMake_VERSION_PATCH 20181119) +set(CMake_VERSION_PATCH 20181120) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 09:33:07 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 09:33:07 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-508-ga09274c Message-ID: <20181120143307.E68F7127BB1@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via a09274c6ec5a3cbe1d57c48199279946d6c997a7 (commit) via aed259ac414e49933e498639edadfff6290d2a65 (commit) via e653f46677450090b6acb46e9e12543cc307021a (commit) via fc366d25946f7434527658475835d1e587cea4ea (commit) via 4b94f3420c78e1bb7aa1324973e3ec76ba765c27 (commit) via b5f8113ca7796df47bcb04bcd77991885c3b1b07 (commit) via a5241cc3a7d5c7173603e637c039f1b8a1852627 (commit) via a3c31effedbaf6c552fc433ac6688cb0453e7bf3 (commit) via 3e1c361afa1c58b3c56a3253f8215dfaac2c0cc4 (commit) via c24f29c6647f70e6597dd35a1fe276279e019ad4 (commit) via d3fa2e7400f4c7ce88c8fe762810bc379879444c (commit) via 01c7d9ce863d6f8bcae578b500dd2e8ba2d97967 (commit) from d851a8b457251a577f10055d9fb277b75a82da6c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a09274c6ec5a3cbe1d57c48199279946d6c997a7 commit a09274c6ec5a3cbe1d57c48199279946d6c997a7 Merge: aed259a a5241cc Author: Brad King AuthorDate: Tue Nov 20 09:30:24 2018 -0500 Commit: Brad King CommitDate: Tue Nov 20 09:30:24 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=aed259ac414e49933e498639edadfff6290d2a65 commit aed259ac414e49933e498639edadfff6290d2a65 Merge: e653f46 b5f8113 Author: Brad King AuthorDate: Tue Nov 20 14:29:38 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 20 09:29:44 2018 -0500 Merge topic 'genex-in_list-empty-args' b5f8113ca7 Genex: Add policy to handle empty list items in $ Acked-by: Kitware Robot Merge-request: !2569 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e653f46677450090b6acb46e9e12543cc307021a commit e653f46677450090b6acb46e9e12543cc307021a Merge: fc366d2 a3c31ef Author: Brad King AuthorDate: Tue Nov 20 14:25:39 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 20 09:26:31 2018 -0500 Merge topic 'blas-pkgcfg' a3c31effed FindBLAS: Restore BLAS_FOUND when found using pkgconfig Acked-by: Kitware Robot Merge-request: !2631 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fc366d25946f7434527658475835d1e587cea4ea commit fc366d25946f7434527658475835d1e587cea4ea Merge: 4b94f34 c24f29c Author: Brad King AuthorDate: Tue Nov 20 14:25:21 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 20 09:25:48 2018 -0500 Merge topic 'FindPython-lib-arch' c24f29c664 FindPython: Ensure config tool matches library architecture Acked-by: Kitware Robot Acked-by: Eric Noulard Merge-request: !2624 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4b94f3420c78e1bb7aa1324973e3ec76ba765c27 commit 4b94f3420c78e1bb7aa1324973e3ec76ba765c27 Merge: d851a8b 01c7d9c Author: Brad King AuthorDate: Tue Nov 20 14:24:56 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 20 09:25:03 2018 -0500 Merge topic 'irsl-ucrt-version' 01c7d9ce86 IRSL: Detect versioned Windows Universal CRT directories Acked-by: Kitware Robot Merge-request: !2637 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b5f8113ca7796df47bcb04bcd77991885c3b1b07 commit b5f8113ca7796df47bcb04bcd77991885c3b1b07 Author: Kyle Edwards AuthorDate: Tue Nov 6 11:27:03 2018 -0500 Commit: Kyle Edwards CommitDate: Mon Nov 19 17:02:06 2018 -0500 Genex: Add policy to handle empty list items in $ The old behavior of $ is inconsistent with that of if(IN_LIST), in that it does not find an empty search item even if the list contains empty items. This change adds a new policy to correctly handle empty items and make the behavior more consistent with if(IN_LIST). Fixes: #18556 diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 7c0fe6d..044a06e 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14 .. toctree:: :maxdepth: 1 + CMP0085: IN_LIST generator expression handles empty list items. CMP0084: The FindQt module does not exist for find_package(). CMP0083: Add PIE options when linking executable. CMP0082: Install rules from add_subdirectory() are interleaved with those in caller. diff --git a/Help/policy/CMP0085.rst b/Help/policy/CMP0085.rst new file mode 100644 index 0000000..d9ec9a2 --- /dev/null +++ b/Help/policy/CMP0085.rst @@ -0,0 +1,21 @@ +CMP0085 +------- + +``$`` handles empty list items. + +In CMake 3.13 and lower, the ``$`` generator expression always +returned ``0`` if the first argument was empty, even if the list contained an +empty item. This behavior is inconsistent with the ``IN_LIST`` behavior of +:command:`if`, which this generator expression is meant to emulate. CMake 3.14 +and later handles this case correctly. + +The ``OLD`` behavior of this policy is for ``$`` to always return +``0`` if the first argument is empty. The ``NEW`` behavior is to return ``1`` +if the first argument is empty and the list contains an empty item. + +This policy was introduced in CMake version 3.14. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/genex-in_list-empty-args.rst b/Help/release/dev/genex-in_list-empty-args.rst new file mode 100644 index 0000000..ec1c6c0 --- /dev/null +++ b/Help/release/dev/genex-in_list-empty-args.rst @@ -0,0 +1,5 @@ +genex-in_list-empty-args +------------------------ + +* The $ generator expression now correctly handles an empty + argument. See :policy:`CMP0085` for details. diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 49b97fb..eb3df16 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -283,14 +283,39 @@ static const struct InListNode : public cmGeneratorExpressionNode std::string Evaluate( const std::vector& parameters, - cmGeneratorExpressionContext* /*context*/, + cmGeneratorExpressionContext* context, const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - std::vector values; - cmSystemTools::ExpandListArgument(parameters[1], values); - if (values.empty()) { - return "0"; + std::vector values, checkValues; + bool check = false; + switch (context->LG->GetPolicyStatus(cmPolicies::CMP0085)) { + case cmPolicies::WARN: + if (parameters.front().empty()) { + check = true; + cmSystemTools::ExpandListArgument(parameters[1], checkValues, true); + } + CM_FALLTHROUGH; + case cmPolicies::OLD: + cmSystemTools::ExpandListArgument(parameters[1], values); + if (check && values != checkValues) { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0085) + << "\nSearch Item:\n \"" << parameters.front() + << "\"\nList:\n \"" << parameters[1] << "\"\n"; + context->LG->GetCMakeInstance()->IssueMessage( + cmake::AUTHOR_WARNING, e.str(), context->Backtrace); + return "0"; + } + if (values.empty()) { + return "0"; + } + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + cmSystemTools::ExpandListArgument(parameters[1], values, true); + break; } return std::find(values.cbegin(), values.cend(), parameters.front()) == diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 6b1314f..9985d63 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -249,7 +249,9 @@ class cmMakefile; 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0084, \ "The FindQt module does not exist for find_package().", 3, 14, 0, \ - cmPolicies::WARN) + cmPolicies::WARN) \ + SELECT(POLICY, CMP0085, "$ handles empty list items.", 3, 14, \ + 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-NEW-check.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-NEW-check.cmake new file mode 100644 index 0000000..520bf3d --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-NEW-check.cmake @@ -0,0 +1,6 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/CMP0085-NEW-generated.txt" content) + +set(expected "101011") +if(NOT content STREQUAL expected) + set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]") +endif() diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-NEW.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-NEW.cmake new file mode 100644 index 0000000..ee85c0d --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-NEW.cmake @@ -0,0 +1,4 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT CMP0085-NEW-generated.txt CONTENT + "$$$$$$" + ) diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-check.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-check.cmake new file mode 100644 index 0000000..c387db7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-check.cmake @@ -0,0 +1,6 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/CMP0085-OLD-generated.txt" content) + +set(expected "000011") +if(NOT content STREQUAL expected) + set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]") +endif() diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-OLD.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD.cmake new file mode 100644 index 0000000..31b6a51 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD.cmake @@ -0,0 +1,4 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT CMP0085-OLD-generated.txt CONTENT + "$$$$$$" + ) diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-check.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-check.cmake new file mode 100644 index 0000000..f7bcf0f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-check.cmake @@ -0,0 +1,6 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/CMP0085-WARN-generated.txt" content) + +set(expected "000011") +if(NOT content STREQUAL expected) + set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]") +endif() diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-stderr.txt b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-stderr.txt new file mode 100644 index 0000000..81bd450 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN-stderr.txt @@ -0,0 +1,33 @@ +CMake Warning \(dev\) at CMP0085-WARN\.cmake:[0-9]+ \(file\): + Policy CMP0085 is not set: \$ handles empty list items\. Run + "cmake --help-policy CMP0085" for policy details\. Use the cmake_policy + command to set the policy and suppress this warning\. + + Search Item: + + "" + + List: + + "" + +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Warning \(dev\) at CMP0085-WARN\.cmake:[0-9]+ \(file\): + Policy CMP0085 is not set: \$ handles empty list items\. Run + "cmake --help-policy CMP0085" for policy details\. Use the cmake_policy + command to set the policy and suppress this warning\. + + Search Item: + + "" + + List: + + ";a" + +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-WARN.cmake b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN.cmake new file mode 100644 index 0000000..59c7826 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMP0085-WARN.cmake @@ -0,0 +1,4 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT CMP0085-WARN-generated.txt CONTENT + "$$$$$$" + ) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 3905c5f..013117e 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -61,3 +61,13 @@ if(LINKER_SUPPORTS_PDB) else() run_cmake(NonValidCompiler-TARGET_PDB_FILE) endif() + +set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0085:STRING=OLD) +run_cmake(CMP0085-OLD) +unset(RunCMake_TEST_OPTIONS) + +run_cmake(CMP0085-WARN) + +set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0085:STRING=NEW) +run_cmake(CMP0085-NEW) +unset(RunCMake_TEST_OPTIONS) ----------------------------------------------------------------------- Summary of changes: Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0085.rst | 21 +++++++++++++ Help/release/dev/genex-in_list-empty-args.rst | 5 ++++ Modules/FindBLAS.cmake | 1 + Modules/FindPython/Support.cmake | 17 +++++++++++ Modules/InstallRequiredSystemLibraries.cmake | 22 ++++++++++++-- Source/cmGeneratorExpressionNode.cxx | 35 ++++++++++++++++++---- Source/cmPolicies.h | 4 ++- ..._EXISTS-check.cmake => CMP0085-NEW-check.cmake} | 4 +-- .../RunCMake/GeneratorExpression/CMP0085-NEW.cmake | 4 +++ ..._EXISTS-check.cmake => CMP0085-OLD-check.cmake} | 4 +-- .../RunCMake/GeneratorExpression/CMP0085-OLD.cmake | 4 +++ ...EXISTS-check.cmake => CMP0085-WARN-check.cmake} | 4 +-- .../GeneratorExpression/CMP0085-WARN-stderr.txt | 33 ++++++++++++++++++++ .../GeneratorExpression/CMP0085-WARN.cmake | 4 +++ .../GeneratorExpression/RunCMakeTest.cmake | 10 +++++++ 16 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 Help/policy/CMP0085.rst create mode 100644 Help/release/dev/genex-in_list-empty-args.rst copy Tests/RunCMake/GeneratorExpression/{TARGET_EXISTS-check.cmake => CMP0085-NEW-check.cmake} (58%) create mode 100644 Tests/RunCMake/GeneratorExpression/CMP0085-NEW.cmake copy Tests/RunCMake/GeneratorExpression/{TARGET_EXISTS-check.cmake => CMP0085-OLD-check.cmake} (58%) create mode 100644 Tests/RunCMake/GeneratorExpression/CMP0085-OLD.cmake copy Tests/RunCMake/GeneratorExpression/{TARGET_EXISTS-check.cmake => CMP0085-WARN-check.cmake} (58%) create mode 100644 Tests/RunCMake/GeneratorExpression/CMP0085-WARN-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/CMP0085-WARN.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 09:33:08 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 09:33:08 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-19-ga5241cc Message-ID: <20181120143308.0447A127BDA@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via a5241cc3a7d5c7173603e637c039f1b8a1852627 (commit) via a3c31effedbaf6c552fc433ac6688cb0453e7bf3 (commit) via 3e1c361afa1c58b3c56a3253f8215dfaac2c0cc4 (commit) via c24f29c6647f70e6597dd35a1fe276279e019ad4 (commit) via d3fa2e7400f4c7ce88c8fe762810bc379879444c (commit) via 01c7d9ce863d6f8bcae578b500dd2e8ba2d97967 (commit) from e593161bd5952f7e24e88a368cc0b39c9a2ca795 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindBLAS.cmake | 1 + Modules/FindPython/Support.cmake | 17 +++++++++++++++++ Modules/InstallRequiredSystemLibraries.cmake | 22 +++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 11:53:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 11:53:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-rc3-510-gea52ec9 Message-ID: <20181120165306.6042E127C38@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via ea52ec9420a6f147a78276bda8110999faa9e094 (commit) via 05a2ca7f87b9ae73f373e9967fde1ee5210e33af (commit) from a09274c6ec5a3cbe1d57c48199279946d6c997a7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ea52ec9420a6f147a78276bda8110999faa9e094 commit ea52ec9420a6f147a78276bda8110999faa9e094 Merge: a09274c 05a2ca7 Author: Brad King AuthorDate: Tue Nov 20 11:45:54 2018 -0500 Commit: Brad King CommitDate: Tue Nov 20 11:45:54 2018 -0500 Merge branch 'release-3.13' ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 11:53:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 11:53:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-rc3-20-g05a2ca7 Message-ID: <20181120165306.6EDF5127C86@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 05a2ca7f87b9ae73f373e9967fde1ee5210e33af (commit) from a5241cc3a7d5c7173603e637c039f1b8a1852627 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 12:03:02 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 12:03:02 -0500 (EST) Subject: [Cmake-commits] CMake annotated tag, v3.13.0, created. v3.13.0 Message-ID: <20181120170302.C44EB127EA7@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The annotated tag, v3.13.0 has been created at 3feab5b94bfe3598fb1078116eb2dffd4a5e2e74 (tag) tagging 05a2ca7f87b9ae73f373e9967fde1ee5210e33af (commit) replaces v3.13.0-rc3 tagged by Brad King on Tue Nov 20 11:44:39 2018 -0500 - Log ----------------------------------------------------------------- CMake 3.13.0 -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEExsJlMku+vcNQtRPQLSzvEDSSFoQFAlv0OfcWHGJyYWQua2lu Z0BraXR3YXJlLmNvbQAKCRAtLO8QNJIWhNFcD/9RGvx6D3GamycBAU8tivLye7Ex odI3Wow3sq2MWtzFtc7wwQo+oiHQO7+DKIth1dcpUpUjKn03uPA/hpKkITIG7tav G4zOpCy63ATRySXH6t0e1t1do0qOyUJAqQmESyoXDy6qcx1IXggY4b5hfPQb1oEy 8Rynr+26/tln/qjNkTQOfEYcE/5po25+Gk7eUYJLCh35dSf61FfqvrAEkugxSGp2 VF4McM0DgNgWI3AWx/JFLUe62aHU0AlfbwX00/us+nNUp6ngNMXBIkKaBPbVrRhM G0ImH4eYUL/W7Gr3xla43ILUTplmdAR1QPHB5EPmSXSuN9P3GaiTq2kEd5dqVPx3 rpCbg6PoU2fJ/FLSwfhVlTImQ0ZhEp4AVSwdSqpRWS+6XClvr9qccB0ybdPftJDi ig4glrmmQvbBilARhNydyF1Q2ovoDN6XbMsa3Hcl/91nm34EFU/0j9KaRebbKSoX aixu8EBhsTOz/j1Wbef/lDnSejp98xiPu6NVx3jhdwTvjY7GCmwXtwHcfylp8l+Z D9kTpB4M8uQGAIjAWIhQ+1hxxwDOaT0WNMNHhZI97n+0VzRPhd6xbV+0kYQFYIhI 5hdddayhsgQU4hEHOmFHrId1Nmb1/Hk9boWpFyMvQyr8ZFySUAP1kF9aczkRrlIk YM75ZNdtbopXe9CjbQ== =Cr7w -----END PGP SIGNATURE----- Brad King (14): ASM: Detect compiler id for Clang used as Assembler Merge branch 'FindBoost-link-threads' into release-3.13 Merge branch 'asm-compiler-id-clang' into release-3.13 Merge branch 'FindBoost-compiler-guess-update' into release-3.13 Merge branch 'FindBoost-1.69' into release-3.13 Tests: Teach RunCMake infrastructure to optionally provide stdin CTest: Restore inheritance of stdin by test processes Merge branch 'ctest-stdin' into release-3.13 Merge branch 'backport-configure_file-canonical-deps' into release-3.13 IRSL: Detect versioned Windows Universal CRT directories Merge branch 'irsl-ucrt-version' into release-3.13 Merge branch 'FindPython-lib-arch' into release-3.13 Merge branch 'blas-pkgcfg' into release-3.13 CMake 3.13.0 Felix Geyer (1): FindBoost: Add system thread library to Boost_LIBRARIES Frank Benkstein (1): configure_file: canonicalize input and output path in dependencies Marc Chevrier (1): FindPython: Ensure config tool matches library architecture Martin von Gagern (1): FindBLAS: Restore BLAS_FOUND when found using pkgconfig Mateusz ?oskot (1): FindBoost: Improve compiler prefix detection for GCC 5+ and clang 4+ Roger Leigh (1): FindBoost: Additional fixes for 1.69 ----------------------------------------------------------------------- hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 20 16:53:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 20 Nov 2018 16:53:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-493-gec43aca Message-ID: <20181120215305.D2C5F127C19@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via ec43aca7037987e189a39ebe2c93c7b4e219a9a7 (commit) via 8369e3e7822712f9415440aede2a470a50925107 (commit) via 664d6178d82edd74e184ff31c8a1faa01b884a48 (commit) from ea52ec9420a6f147a78276bda8110999faa9e094 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ec43aca7037987e189a39ebe2c93c7b4e219a9a7 commit ec43aca7037987e189a39ebe2c93c7b4e219a9a7 Merge: ea52ec9 8369e3e Author: Craig Scott AuthorDate: Tue Nov 20 21:48:27 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 20 16:48:45 2018 -0500 Merge topic 'doc-module-doc-syntax' 8369e3e782 Help/dev: Modernize module example in the CMake Documentation Guide 664d6178d8 Help: Modernize example find module docs in cmake-developer(7) Acked-by: Kitware Robot Merge-request: !2621 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8369e3e7822712f9415440aede2a470a50925107 commit 8369e3e7822712f9415440aede2a470a50925107 Author: Brad King AuthorDate: Thu Nov 15 13:43:09 2018 -0500 Commit: Craig Scott CommitDate: Tue Nov 20 21:03:01 2018 +1100 Help/dev: Modernize module example in the CMake Documentation Guide diff --git a/Help/dev/documentation.rst b/Help/dev/documentation.rst index 1b2c942..c302790 100644 --- a/Help/dev/documentation.rst +++ b/Help/dev/documentation.rst @@ -458,32 +458,22 @@ reStructuredText markup from comment blocks that start in ``.rst:``. At the top of ``Modules/.cmake``, begin with the following license notice: -.. code-block:: cmake +:: # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. After this notice, add a *BLANK* line. Then, add documentation using -a `Line Comment`_ block of the form: - -.. code-block:: cmake - - #.rst: - # - # ------------- - # - # - -or a `Bracket Comment`_ of the form: +a `Bracket Comment`_ of the form: :: - #[[.rst: - - ------------- + #[=======================================================================[.rst: + + ------------- - - #]] + + #]=======================================================================] Any number of ``=`` may be used in the opening and closing brackets as long as they match. Content on the line containing the closing @@ -496,35 +486,38 @@ For example, a ``Findxxx.cmake`` module may contain: :: - # Distributed under the OSI-approved BSD 3-Clause License. See accompanying - # file Copyright.txt or https://cmake.org/licensing for details. + # Distributed under the OSI-approved BSD 3-Clause License. See accompanying + # file Copyright.txt or https://cmake.org/licensing for details. + + #[=======================================================================[.rst: + FindXxx + ------- + + This is a cool module. + This module does really cool stuff. + It can do even more than you think. + + It even needs two paragraphs to tell you about it. + And it defines the following variables: + + ``VAR_COOL`` + this is great isn't it? + ``VAR_REALLY_COOL`` + cool right? + #]=======================================================================] + + + + #[=======================================================================[.rst: + .. command:: xxx_do_something + + This command does something for Xxx:: - #.rst: - # FindXxx - # ------- - # - # This is a cool module. - # This module does really cool stuff. - # It can do even more than you think. - # - # It even needs two paragraphs to tell you about it. - # And it defines the following variables: - # - # * VAR_COOL: this is great isn't it? - # * VAR_REALLY_COOL: cool right? - - - - #[========================================[.rst: - .. command:: xxx_do_something - - This command does something for Xxx:: - - xxx_do_something(some arguments) - #]========================================] - macro(xxx_do_something) - - endmacro() + xxx_do_something(some arguments) + #]=======================================================================] + macro(xxx_do_something) + + endmacro() Test the documentation formatting by running ``cmake --help-module ``, and also by enabling the @@ -534,5 +527,4 @@ have a .cmake file in this directory NOT show up in the modules documentation, simply leave out the ``Help/module/.rst`` file and the ``Help/manual/cmake-modules.7.rst`` toctree entry. -.. _`Line Comment`: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#line-comment .. _`Bracket Comment`: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#bracket-comment https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=664d6178d82edd74e184ff31c8a1faa01b884a48 commit 664d6178d82edd74e184ff31c8a1faa01b884a48 Author: Brad King AuthorDate: Thu Nov 15 13:38:57 2018 -0500 Commit: Craig Scott CommitDate: Tue Nov 20 21:03:01 2018 +1100 Help: Modernize example find module docs in cmake-developer(7) diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index b949464..85ed935 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -196,49 +196,78 @@ them. A Sample Find Module -------------------- -We will describe how to create a simple find module for a library -``Foo``. +We will describe how to create a simple find module for a library ``Foo``. -The first thing that is needed is a license notice. +The top of the module should begin with a license notice, followed by +a blank line, and then followed by a :ref:`Bracket Comment`. The comment +should begin with ``.rst:`` to indicate that the rest of its content is +reStructuredText-format documentation. For example: -.. code-block:: cmake +:: - # Distributed under the OSI-approved BSD 3-Clause License. See accompanying - # file Copyright.txt or https://cmake.org/licensing for details. + # Distributed under the OSI-approved BSD 3-Clause License. See accompanying + # file Copyright.txt or https://cmake.org/licensing for details. -Next we need module documentation. CMake's documentation system requires you -to follow the license notice with a blank line and then with a documentation -marker and the name of the module. You should follow this with a simple -statement of what the module does. + #[=======================================================================[.rst: + FindFoo + ------- -.. code-block:: cmake + Finds the Foo library. - #.rst: - # FindFoo - # ------- - # - # Finds the Foo library - # + Imported Targets + ^^^^^^^^^^^^^^^^ -More description may be required for some packages. If there are -caveats or other details users of the module should be aware of, you can -add further paragraphs below this. Then you need to document what -variables and imported targets are set by the module, such as + This module provides the following imported targets, if found: -.. code-block:: cmake + ``Foo::Foo`` + The Foo library + + Result Variables + ^^^^^^^^^^^^^^^^ + + This will define the following variables: + + ``Foo_FOUND`` + True if the system has the Foo library. + ``Foo_VERSION`` + The version of the Foo library which was found. + ``Foo_INCLUDE_DIRS`` + Include directories needed to use Foo. + ``Foo_LIBRARIES`` + Libraries needed to link to Foo. + + Cache Variables + ^^^^^^^^^^^^^^^ + + The following cache variables may also be set: + + ``Foo_INCLUDE_DIR`` + The directory containing ``foo.h``. + ``Foo_LIBRARY`` + The path to the Foo library. + + #]=======================================================================] + +The module documentation consists of: + +* An underlined heading specifying the module name. + +* A simple description of what the module finds. + More description may be required for some packages. If there are + caveats or other details users of the module should be aware of, + specify them here. + +* A section listing imported targets provided by the module, if any. + +* A section listing result variables provided by the module. - # This will define the following variables:: - # - # Foo_FOUND - True if the system has the Foo library - # Foo_VERSION - The version of the Foo library which was found - # - # and the following imported targets:: - # - # Foo::Foo - The Foo library +* Optionally a section listing cache variables used by the module, if any. -If the package provides any macros, they should be listed here, but can -be documented where they are defined. +If the package provides any macros or functions, they should be listed in +an additional section, but can be documented by additional ``.rst:`` +comment blocks immediately above where those macros or functions are defined. +The find module implementation may begin below the documentation block. Now the actual libraries and so on have to be found. The code here will obviously vary from module to module (dealing with that, after all, is the point of find modules), but there tends to be a common pattern for libraries. ----------------------------------------------------------------------- Summary of changes: Help/dev/documentation.rst | 84 ++++++++++++++++------------------- Help/manual/cmake-developer.7.rst | 93 +++++++++++++++++++++++++-------------- 2 files changed, 99 insertions(+), 78 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 21 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 21 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-494-g3804122 Message-ID: <20181121050305.90893128014@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 3804122ab2793b9d54aa8c69df62ed86f526d50f (commit) from ec43aca7037987e189a39ebe2c93c7b4e219a9a7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3804122ab2793b9d54aa8c69df62ed86f526d50f commit 3804122ab2793b9d54aa8c69df62ed86f526d50f Author: Kitware Robot AuthorDate: Wed Nov 21 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Wed Nov 21 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4a312ec..869c6dd 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 13) -set(CMake_VERSION_PATCH 20181120) +set(CMake_VERSION_PATCH 20181121) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 21 07:43:12 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 21 Nov 2018 07:43:12 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-507-g4e0c75b Message-ID: <20181121124312.C987C12688A@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 4e0c75b78f5745d1369867f25a46ab7d158b4469 (commit) via 2b427c2fadc917ebcaf2f246d53504ce5b6ad754 (commit) via 74cc42e937e3117e9514f0c1561f212a8867bc92 (commit) via 8b83d1fdffeab9d24946552a9b8252c2e0dc4570 (commit) via 3d48c5404cde1ca5f9956d9587f7d5b134a696eb (commit) via a586b60129bb29ad99107164439b38f4de60f599 (commit) via 6962a41e6b83e1ead36ab26b06ebe81aeee0087a (commit) via 5bc64fe6c25f3c02dda7d22eb65c07bdf2e6eb46 (commit) via 8068850fcc1575210c968365e71cb7ece6771022 (commit) via ead16adfc8dc387a59057717521976cbe7ae9067 (commit) via 19d92d5e6e79448337aface8ed40df78240d674b (commit) via 186f69cf26b02ec4e2583c846ab3f2d4211997b7 (commit) via 5731ec30f0596fefede4321e9883043aa7db60ba (commit) from 3804122ab2793b9d54aa8c69df62ed86f526d50f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4e0c75b78f5745d1369867f25a46ab7d158b4469 commit 4e0c75b78f5745d1369867f25a46ab7d158b4469 Merge: 2b427c2 5731ec3 Author: Brad King AuthorDate: Wed Nov 21 12:42:26 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 21 07:42:32 2018 -0500 Merge topic 'clang-tidy' 5731ec30f0 clang-tidy: fix warnings from version 7 Acked-by: Kitware Robot Merge-request: !2636 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2b427c2fadc917ebcaf2f246d53504ce5b6ad754 commit 2b427c2fadc917ebcaf2f246d53504ce5b6ad754 Merge: 8b83d1f 74cc42e Author: Brad King AuthorDate: Wed Nov 21 12:41:21 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 21 07:41:27 2018 -0500 Merge topic 'FindGIF-modernize' 74cc42e937 Help: Add notes for topic 'FindGIF-modernize' 6962a41e6b FindGIF: Add test 5bc64fe6c2 FindGIF: Modernize Acked-by: Kitware Robot Merge-request: !2632 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=74cc42e937e3117e9514f0c1561f212a8867bc92 commit 74cc42e937e3117e9514f0c1561f212a8867bc92 Author: Brad King AuthorDate: Wed Nov 21 07:39:58 2018 -0500 Commit: Brad King CommitDate: Wed Nov 21 07:39:58 2018 -0500 Help: Add notes for topic 'FindGIF-modernize' diff --git a/Help/release/dev/FindGIF-modernize.rst b/Help/release/dev/FindGIF-modernize.rst new file mode 100644 index 0000000..3bb4821 --- /dev/null +++ b/Help/release/dev/FindGIF-modernize.rst @@ -0,0 +1,4 @@ +FindGIF-modernize +----------------- + +* The :module:`FindGIF` module now provides imported targets. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8b83d1fdffeab9d24946552a9b8252c2e0dc4570 commit 8b83d1fdffeab9d24946552a9b8252c2e0dc4570 Merge: 3d48c54 19d92d5 Author: Brad King AuthorDate: Wed Nov 21 12:37:04 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 21 07:37:11 2018 -0500 Merge topic 'find-boost-test-version' 19d92d5e6e FindBoost: provide the version in x.y.z format 186f69cf26 FindBoost: test version variables Acked-by: Kitware Robot Merge-request: !2638 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3d48c5404cde1ca5f9956d9587f7d5b134a696eb commit 3d48c5404cde1ca5f9956d9587f7d5b134a696eb Merge: a586b60 8068850 Author: Brad King AuthorDate: Wed Nov 21 07:35:52 2018 -0500 Commit: Brad King CommitDate: Wed Nov 21 07:35:52 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a586b60129bb29ad99107164439b38f4de60f599 commit a586b60129bb29ad99107164439b38f4de60f599 Merge: 3804122 ead16ad Author: Brad King AuthorDate: Wed Nov 21 12:34:42 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 21 07:34:53 2018 -0500 Merge topic 'fortran-submodule-case' ead16adfc8 Fortran: Fix module dependency scanning with upper-case SUBMODULE Acked-by: Kitware Robot Merge-request: !2644 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6962a41e6b83e1ead36ab26b06ebe81aeee0087a commit 6962a41e6b83e1ead36ab26b06ebe81aeee0087a Author: Maximilian Heinzler AuthorDate: Tue Nov 20 21:03:19 2018 +0100 Commit: Maximilian Heinzler CommitDate: Tue Nov 20 21:07:03 2018 +0100 FindGIF: Add test This tests whether GIFLIB can be found and the linker works. For newer versions (>=5) it also tests if the version was parsed correctly. diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 96cdfd0..8b5f2e9 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1388,6 +1388,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindGDAL) endif() + if(CMake_TEST_FindGIF) + add_subdirectory(FindGIF) + endif() + if(CMake_TEST_FindGSL) add_subdirectory(FindGSL) endif() diff --git a/Tests/FindGIF/CMakeLists.txt b/Tests/FindGIF/CMakeLists.txt new file mode 100644 index 0000000..bac64af --- /dev/null +++ b/Tests/FindGIF/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindGIF.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $ + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindGIF/Test" + "${CMake_BINARY_DIR}/Tests/FindGIF/Test" + ${build_generator_args} + --build-project TestFindGIF + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $ + ) diff --git a/Tests/FindGIF/Test/CMakeLists.txt b/Tests/FindGIF/Test/CMakeLists.txt new file mode 100644 index 0000000..961e636 --- /dev/null +++ b/Tests/FindGIF/Test/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.4) +project(TestFindGIF C) +include(CTest) + +find_package(GIF REQUIRED) + +add_definitions(-DCMAKE_EXPECTED_GIF_VERSION="${GIF_VERSION}") + +add_executable(test_tgt main.c) +target_link_libraries(test_tgt GIF::GIF) +add_test(NAME test_tgt COMMAND test_tgt) + +add_executable(test_var main.c) +target_include_directories(test_var PRIVATE ${GIF_INCLUDE_DIRS}) +target_link_libraries(test_var PRIVATE ${GIF_LIBRARIES}) +add_test(NAME test_var COMMAND test_var) diff --git a/Tests/FindGIF/Test/main.c b/Tests/FindGIF/Test/main.c new file mode 100644 index 0000000..4ed72ec --- /dev/null +++ b/Tests/FindGIF/Test/main.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#include + +// GIFLIB before version 5 didn't know this macro +#ifndef GIFLIB_MAJOR +# define GIFLIB_MAJOR 4 +#endif + +int main() +{ + // because of the API changes we have to test different functions depending + // on the version of GIFLIB +#if GIFLIB_MAJOR >= 5 + // test the linker + GifErrorString(D_GIF_SUCCEEDED); + + // check the version + char gif_version_string[16]; + snprintf(gif_version_string, 16, "%i.%i.%i", GIFLIB_MAJOR, GIFLIB_MINOR, + GIFLIB_RELEASE); + + assert(strcmp(gif_version_string, CMAKE_EXPECTED_GIF_VERSION) == 0); +#else + // test the linker + GifLastError(); + + // unfortunately there is no way to check the version in older version of + // GIFLIB +#endif + + return 0; +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5bc64fe6c25f3c02dda7d22eb65c07bdf2e6eb46 commit 5bc64fe6c25f3c02dda7d22eb65c07bdf2e6eb46 Author: Maximilian Heinzler AuthorDate: Sun Nov 18 16:59:50 2018 +0100 Commit: Maximilian Heinzler CommitDate: Tue Nov 20 21:07:03 2018 +0100 FindGIF: Modernize This brings the module up to the current find module standards by adding the GIF_INCLUDE_DIRS variable and the target GIF::GIF. It also updates the documentation style to that of similar modules. diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake index 9a995af..9687b57 100644 --- a/Modules/FindGIF.cmake +++ b/Modules/FindGIF.cmake @@ -7,22 +7,43 @@ FindGIF This finds the GIF library (giflib) -The module defines the following variables: +Imported targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` target: + +``GIF::GIF`` + The giflib library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: ``GIF_FOUND`` - True if giflib was found + If false, do not try to use GIF. +``GIF_INCLUDE_DIRS`` + where to find gif_lib.h, etc. ``GIF_LIBRARIES`` - Libraries to link to in order to use giflib -``GIF_INCLUDE_DIR`` - where to find the headers + the libraries needed to use GIF. ``GIF_VERSION`` - 3, 4 or a full version string (eg 5.1.4) for versions >= 4.1.6 + 3, 4 or a full version string (eg 5.1.4) for versions >= 4.1.6. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: -The minimum required version of giflib can be specified using the -standard syntax, e.g. find_package(GIF 4) +``GIF_INCLUDE_DIR`` + where to find the GIF headers. +``GIF_LIBRARY`` + where to find the GIF library. + +Hints +^^^^^ -$GIF_DIR is an environment variable that would correspond to the -./configure --prefix=$GIF_DIR +``GIF_DIR`` is an environment variable that would correspond to the +``./configure --prefix=$GIF_DIR``. #]=======================================================================] # Created by Eric Wing. @@ -44,9 +65,6 @@ find_library(GIF_LIBRARY PATH_SUFFIXES lib ) -# see readme.txt -set(GIF_LIBRARIES ${GIF_LIBRARY}) - # Very basic version detection. # The GIF_LIB_VERSION string in gif_lib.h seems to be unreliable, since it seems # to be always " Version 2.0, " in versions 3.x of giflib. @@ -90,4 +108,20 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GIF REQUIRED_VARS GIF_LIBRARY GIF_INCLUDE_DIR VERSION_VAR GIF_VERSION ) +if(GIF_FOUND) + set(GIF_INCLUDE_DIRS "${GIF_INCLUDE_DIR}") + set(GIF_LIBRARIES ${GIF_LIBRARY}) + + if(NOT TARGET GIF::GIF) + add_library(GIF::GIF UNKNOWN IMPORTED) + set_target_properties(GIF::GIF PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${GIF_INCLUDE_DIRS}") + if(EXISTS "${GIF_LIBRARY}") + set_target_properties(GIF::GIF PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${GIF_LIBRARY}") + endif() + endif() +endif() + mark_as_advanced(GIF_INCLUDE_DIR GIF_LIBRARY) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=19d92d5e6e79448337aface8ed40df78240d674b commit 19d92d5e6e79448337aface8ed40df78240d674b Author: Ben Boeckel AuthorDate: Mon Nov 19 16:23:31 2018 -0500 Commit: Ben Boeckel CommitDate: Tue Nov 20 10:45:24 2018 -0500 FindBoost: provide the version in x.y.z format diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index ccd245b..a336495 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -35,6 +35,7 @@ case results are reported in variables:: Boost_MAJOR_VERSION - Boost major version number (X in X.y.z) Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z) Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z) + Boost_VERSION_STRING - Boost version number in x.y.z format Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) - Pass to add_definitions() to have diagnostic information about Boost's automatic linking @@ -1371,6 +1372,7 @@ if(Boost_INCLUDE_DIR) math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000") math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000") math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100") + set(Boost_VERSION_STRING "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") string(APPEND Boost_ERROR_REASON "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}") diff --git a/Tests/FindBoost/Test/CMakeLists.txt b/Tests/FindBoost/Test/CMakeLists.txt index 81433ea..39e92c1 100644 --- a/Tests/FindBoost/Test/CMakeLists.txt +++ b/Tests/FindBoost/Test/CMakeLists.txt @@ -14,7 +14,7 @@ if(NOT Boost_PROGRAM_OPTIONS_FOUND) endif(NOT Boost_PROGRAM_OPTIONS_FOUND) add_definitions(-DCMAKE_EXPECTED_BOOST_VERSION="${Boost_VERSION}") -add_definitions(-DCMAKE_EXPECTED_BOOST_VERSION_COMPONENTS="${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") +add_definitions(-DCMAKE_EXPECTED_BOOST_VERSION_COMPONENTS="${Boost_VERSION_STRING}") add_executable(test_boost_tgt main.cxx) target_link_libraries(test_boost_tgt https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=186f69cf26b02ec4e2583c846ab3f2d4211997b7 commit 186f69cf26b02ec4e2583c846ab3f2d4211997b7 Author: Ben Boeckel AuthorDate: Mon Nov 19 16:21:55 2018 -0500 Commit: Ben Boeckel CommitDate: Tue Nov 20 10:45:24 2018 -0500 FindBoost: test version variables diff --git a/Tests/FindBoost/Test/CMakeLists.txt b/Tests/FindBoost/Test/CMakeLists.txt index 663f414..81433ea 100644 --- a/Tests/FindBoost/Test/CMakeLists.txt +++ b/Tests/FindBoost/Test/CMakeLists.txt @@ -13,6 +13,9 @@ if(NOT Boost_PROGRAM_OPTIONS_FOUND) message(FATAL_ERROR "Optional Boost component \"program_options\" not found which is unexpected") endif(NOT Boost_PROGRAM_OPTIONS_FOUND) +add_definitions(-DCMAKE_EXPECTED_BOOST_VERSION="${Boost_VERSION}") +add_definitions(-DCMAKE_EXPECTED_BOOST_VERSION_COMPONENTS="${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") + add_executable(test_boost_tgt main.cxx) target_link_libraries(test_boost_tgt Boost::dynamic_linking diff --git a/Tests/FindBoost/Test/main.cxx b/Tests/FindBoost/Test/main.cxx index 6e8b5da..50ddadf 100644 --- a/Tests/FindBoost/Test/main.cxx +++ b/Tests/FindBoost/Test/main.cxx @@ -20,5 +20,20 @@ int main() boost::thread foo(threadmain); foo.join(); - return 0; + int version = BOOST_VERSION; + int major = version / 100000; + int minor = version / 100 % 1000; + int patch = version % 100; + char version_string[100]; + snprintf(version_string, sizeof(version_string), "%d.%d.%d", major, minor, + patch); + printf("Found Boost version %s, expected version %s\n", version_string, + CMAKE_EXPECTED_BOOST_VERSION_COMPONENTS); + int ret = strcmp(version_string, CMAKE_EXPECTED_BOOST_VERSION_COMPONENTS); + char raw_version_string[100]; + snprintf(raw_version_string, sizeof(raw_version_string), "%d", + BOOST_VERSION); + printf("Found Boost version %s, expected version %s\n", raw_version_string, + CMAKE_EXPECTED_BOOST_VERSION); + return ret | strcmp(raw_version_string, CMAKE_EXPECTED_BOOST_VERSION); } https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5731ec30f0596fefede4321e9883043aa7db60ba commit 5731ec30f0596fefede4321e9883043aa7db60ba Author: Regina Pfeifer AuthorDate: Mon Nov 19 18:10:40 2018 +0100 Commit: Brad King CommitDate: Tue Nov 20 10:36:08 2018 -0500 clang-tidy: fix warnings from version 7 Fix some warnings that are new since clang-tidy version 4, and update `.clang-tidy` to suppress the rest. diff --git a/.clang-tidy b/.clang-tidy index 8d79b0c..cec7d03 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -21,15 +21,18 @@ modernize-*,\ -modernize-use-using,\ performance-*,\ -performance-inefficient-string-concatenation,\ +-performance-inefficient-vector-operation,\ readability-*,\ -readability-function-size,\ -readability-identifier-naming,\ -readability-implicit-bool-cast,\ +-readability-implicit-bool-conversion,\ -readability-inconsistent-declaration-parameter-name,\ -readability-named-parameter,\ -readability-redundant-declaration,\ -readability-redundant-member-init,\ -readability-simplify-boolean-expr,\ +-readability-static-accessed-through-instance,\ " HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$' ... diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index 6284ac9..70610d7 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -21,8 +21,8 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames, , VarTypes(varTypes) { this->setupUi(this); - for (int i = 0; i < NumTypes; i++) { - this->Type->addItem(TypeStrings[i]); + for (auto const& elem : TypeStrings) { + this->Type->addItem(elem); } QWidget* cb = new QCheckBox(); QWidget* path = new QCMakePathEditor(); diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 0ccd68a..27f9131 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -684,7 +684,7 @@ cmELF::cmELF(const char* fname) std::unique_ptr fin(new cmsys::ifstream(fname)); // Quit now if the file could not be opened. - if (!fin.get() || !*fin) { + if (!fin || !*fin) { this->ErrorMessage = "Error opening input file."; return; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index bddc3c4..df27c62 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -79,7 +79,7 @@ bool cmExportFileGenerator::GenerateImportFile() ap->SetCopyIfDifferent(true); foutPtr = std::move(ap); } - if (!foutPtr.get() || !*foutPtr) { + if (!foutPtr || !*foutPtr) { std::string se = cmSystemTools::GetLastSystemError(); std::ostringstream e; e << "cannot write to file \"" << this->MainImportFile << "\": " << se; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index f86e5e2..3012b0a 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2824,7 +2824,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector const& args) std::string algo = i->substr(0, pos); expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1)); hash = std::unique_ptr(cmCryptoHash::New(algo.c_str())); - if (!hash.get()) { + if (!hash) { std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: "; err += algo; this->SetError(err); diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 9ff967c..739c9c0 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -38,7 +38,7 @@ bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, // Remove the function blocker for this scope or bail. std::unique_ptr fb( mf.RemoveFunctionBlocker(this, lff)); - if (!fb.get()) { + if (!fb) { return false; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 0b28d1e..80d81d5 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4379,8 +4379,7 @@ const char* impliedValue(const char* /*unused*/) return ""; } template <> -std::string impliedValue( - std::string /*unused*/) // NOLINT(clang-tidy) +std::string impliedValue(std::string /*unused*/) // NOLINT(*) { return std::string(); } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index fbc756c..0271b6f 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -112,7 +112,7 @@ std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit) std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) { - std::string result = path; // NOLINT(clang-tidy) + std::string result = path; #ifdef _WIN32 if (this->IsGCCOnWindows()) std::replace(result.begin(), result.end(), '\\', '/'); @@ -254,7 +254,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( bool restat, const cmNinjaDeps& outputs, const cmNinjaDeps& deps, const cmNinjaDeps& orderOnly) { - std::string cmd = command; // NOLINT(clang-tidy) + std::string cmd = command; // NOLINT(*) #ifdef _WIN32 if (cmd.empty()) // TODO Shouldn't an empty command be handled by ninja? @@ -1940,7 +1940,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector::const_iterator argBeg, cm.SetHomeOutputDirectory(dir_top_bld); std::unique_ptr ggd( static_cast(cm.CreateGlobalGenerator("Ninja"))); - if (!ggd.get() || + if (!ggd || !ggd->WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis, module_dir, linked_target_dirs)) { diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index ae4041d..5d952da 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -39,7 +39,7 @@ bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, // Remove the function blocker for this scope or bail. std::unique_ptr fb( mf.RemoveFunctionBlocker(this, lff)); - if (!fb.get()) { + if (!fb) { return false; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 790f6e0..5ad8ef6 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2342,7 +2342,7 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const { "watchsimulator", AppleSDK::WatchSimulator }, }; - for (auto entry : sdkDatabase) { + for (auto const& entry : sdkDatabase) { if (sdkRoot.find(entry.name) == 0 || sdkRoot.find(std::string("/") + entry.name) != std::string::npos) { return entry.sdk; diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index d5bcfc2..9d43d19 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -37,7 +37,7 @@ bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, // Remove the function blocker for this scope or bail. std::unique_ptr fb( mf.RemoveFunctionBlocker(this, lff)); - if (!fb.get()) { + if (!fb) { return false; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 35730b8..2ac7f4d 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2596,7 +2596,7 @@ bool cmake::Open(const std::string& dir, bool dryRun) std::unique_ptr gen( this->CreateGlobalGenerator(fullName)); - if (!gen.get()) { + if (!gen) { std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName << "\"\n"; return false; ----------------------------------------------------------------------- Summary of changes: .clang-tidy | 3 + Help/release/dev/FindGIF-modernize.rst | 4 + Modules/FindBoost.cmake | 2 + Modules/FindGIF.cmake | 60 ++++++-- Source/LexerParser/cmFortranLexer.cxx | 226 +++++++++++++++--------------- Source/LexerParser/cmFortranLexer.in.l | 2 +- Source/QtDialog/AddCacheEntry.cxx | 4 +- Source/cmELF.cxx | 2 +- Source/cmExportFileGenerator.cxx | 2 +- Source/cmFileCommand.cxx | 2 +- Source/cmForEachCommand.cxx | 2 +- Source/cmGeneratorTarget.cxx | 3 +- Source/cmGlobalNinjaGenerator.cxx | 6 +- Source/cmIfCommand.cxx | 2 +- Source/cmMakefile.cxx | 2 +- Source/cmWhileCommand.cxx | 2 +- Source/cmake.cxx | 2 +- Tests/CMakeLists.txt | 4 + Tests/FindBoost/Test/CMakeLists.txt | 3 + Tests/FindBoost/Test/main.cxx | 17 ++- Tests/{FindPNG => FindGIF}/CMakeLists.txt | 8 +- Tests/FindGIF/Test/CMakeLists.txt | 16 +++ Tests/FindGIF/Test/main.c | 35 +++++ Tests/FortranModules/Submodules/child.f90 | 6 +- 24 files changed, 265 insertions(+), 150 deletions(-) create mode 100644 Help/release/dev/FindGIF-modernize.rst copy Tests/{FindPNG => FindGIF}/CMakeLists.txt (55%) create mode 100644 Tests/FindGIF/Test/CMakeLists.txt create mode 100644 Tests/FindGIF/Test/main.c hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 21 07:43:12 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 21 Nov 2018 07:43:12 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-2-g8068850 Message-ID: <20181121124313.1EF3A126873@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 8068850fcc1575210c968365e71cb7ece6771022 (commit) via ead16adfc8dc387a59057717521976cbe7ae9067 (commit) from 05a2ca7f87b9ae73f373e9967fde1ee5210e33af (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Source/LexerParser/cmFortranLexer.cxx | 226 +++++++++++++++--------------- Source/LexerParser/cmFortranLexer.in.l | 2 +- Tests/FortranModules/Submodules/child.f90 | 6 +- 3 files changed, 117 insertions(+), 117 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Thu Nov 22 00:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Thu, 22 Nov 2018 00:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-508-gf32c0a2 Message-ID: <20181122050304.64AD9127B60@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via f32c0a2400238e754b630d99fed66f36dd0f7083 (commit) from 4e0c75b78f5745d1369867f25a46ab7d158b4469 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f32c0a2400238e754b630d99fed66f36dd0f7083 commit f32c0a2400238e754b630d99fed66f36dd0f7083 Author: Kitware Robot AuthorDate: Thu Nov 22 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Thu Nov 22 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 869c6dd..eb62f68 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 13) -set(CMake_VERSION_PATCH 20181121) +set(CMake_VERSION_PATCH 20181122) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Fri Nov 23 00:03:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Fri, 23 Nov 2018 00:03:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-509-g0d6c98d Message-ID: <20181123050306.52014127C3A@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 0d6c98d895abade47ca13586fe56e2d0398c0ca6 (commit) from f32c0a2400238e754b630d99fed66f36dd0f7083 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0d6c98d895abade47ca13586fe56e2d0398c0ca6 commit 0d6c98d895abade47ca13586fe56e2d0398c0ca6 Author: Kitware Robot AuthorDate: Fri Nov 23 00:01:03 2018 -0500 Commit: Kitware Robot CommitDate: Fri Nov 23 00:01:03 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index eb62f68..4ed7640 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 13) -set(CMake_VERSION_PATCH 20181122) +set(CMake_VERSION_PATCH 20181123) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sat Nov 24 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sat, 24 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-510-ga44191a Message-ID: <20181124050305.C62F812534B@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via a44191abc489373d295ecaeb5c2eb1573c876a1a (commit) from 0d6c98d895abade47ca13586fe56e2d0398c0ca6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a44191abc489373d295ecaeb5c2eb1573c876a1a commit a44191abc489373d295ecaeb5c2eb1573c876a1a Author: Kitware Robot AuthorDate: Sat Nov 24 00:01:03 2018 -0500 Commit: Kitware Robot CommitDate: Sat Nov 24 00:01:03 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4ed7640..a0ec6e7 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 13) -set(CMake_VERSION_PATCH 20181123) +set(CMake_VERSION_PATCH 20181124) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Sun Nov 25 00:03:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Sun, 25 Nov 2018 00:03:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-511-g37317ec Message-ID: <20181125050305.F2B63126508@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 37317ece8a04054eeeab5de5157f8c366bd69f1a (commit) from a44191abc489373d295ecaeb5c2eb1573c876a1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=37317ece8a04054eeeab5de5157f8c366bd69f1a commit 37317ece8a04054eeeab5de5157f8c366bd69f1a Author: Kitware Robot AuthorDate: Sun Nov 25 00:01:03 2018 -0500 Commit: Kitware Robot CommitDate: Sun Nov 25 00:01:03 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a0ec6e7..081348a 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 13) -set(CMake_VERSION_PATCH 20181124) +set(CMake_VERSION_PATCH 20181125) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 26 00:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 26 Nov 2018 00:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-512-g6786345 Message-ID: <20181126050304.85B2F12790F@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 6786345210994063030ad82f7ece66a461bbfb76 (commit) from 37317ece8a04054eeeab5de5157f8c366bd69f1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6786345210994063030ad82f7ece66a461bbfb76 commit 6786345210994063030ad82f7ece66a461bbfb76 Author: Kitware Robot AuthorDate: Mon Nov 26 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Mon Nov 26 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 081348a..32b08a7 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 13) -set(CMake_VERSION_PATCH 20181125) +set(CMake_VERSION_PATCH 20181126) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 26 07:53:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 26 Nov 2018 07:53:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-514-gaf2960e Message-ID: <20181126125304.90A66FB64E@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via af2960e0fdd8be7cd3ab8b2b894e18a0d3056db9 (commit) via 2ca89b5a6969ce6b0bca44abf02a072e28e5c1cd (commit) from 6786345210994063030ad82f7ece66a461bbfb76 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=af2960e0fdd8be7cd3ab8b2b894e18a0d3056db9 commit af2960e0fdd8be7cd3ab8b2b894e18a0d3056db9 Merge: 6786345 2ca89b5 Author: Brad King AuthorDate: Mon Nov 26 12:50:38 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 26 07:50:51 2018 -0500 Merge topic 'cxx-checks-tolerate-sprintf-warning' 2ca89b5a69 C++ feature checks: Filter out libstdc++ sprintf warnings Acked-by: Kitware Robot Merge-request: !2643 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2ca89b5a6969ce6b0bca44abf02a072e28e5c1cd commit 2ca89b5a6969ce6b0bca44abf02a072e28e5c1cd Author: Brad King AuthorDate: Tue Nov 20 12:50:45 2018 -0500 Commit: Brad King CommitDate: Tue Nov 20 12:50:45 2018 -0500 C++ feature checks: Filter out libstdc++ sprintf warnings On OpenBSD linking to `libstdc++` with GCC 6.4 always warns: warning: sprintf() is often misused, please use snprintf() These do not affect the availability of C++ features we're checking, so filter them out. Fixes: #18602 diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake index 1b57fd8..d941c16 100644 --- a/Source/Checks/cm_cxx_features.cmake +++ b/Source/Checks/cm_cxx_features.cmake @@ -22,6 +22,8 @@ function(cm_check_cxx_feature name) # Filter out warnings caused by local configuration. string(REGEX REPLACE "[^\n]*warning:[^\n]*directory not found for option[^\n]*" "" check_output "${check_output}") string(REGEX REPLACE "[^\n]*warning:[^\n]*object file compiled with -mlong-branch which is no longer needed[^\n]*" "" check_output "${check_output}") + # Filter out other warnings unrelated to feature checks. + string(REGEX REPLACE "[^\n]*warning:[^\n]*sprintf\\(\\) is often misused, please use snprintf[^\n]*" "" check_output "${check_output}") # Filter out xcodebuild warnings. string(REGEX REPLACE "[^\n]* xcodebuild\\[[0-9]*:[0-9]*\\] warning: [^\n]*" "" check_output "${check_output}") # If using the feature causes warnings, treat it as broken/unavailable. ----------------------------------------------------------------------- Summary of changes: Source/Checks/cm_cxx_features.cmake | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- CMake From kwrobot at kitware.com Mon Nov 26 08:03:02 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Mon, 26 Nov 2018 08:03:02 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-518-g5bc3322 Message-ID: <20181126130302.B4750125A18@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 5bc33226b2a0e8ff3c80b292abbfbc6f6b2c405b (commit) via ada104175454f8e393083f116e200344fe846f34 (commit) via ce2570b2071360c0b4bb4cd3c62ed8cccab26513 (commit) via 9175a378f5d8786a54e35576853e7e6b068f17b0 (commit) from af2960e0fdd8be7cd3ab8b2b894e18a0d3056db9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5bc33226b2a0e8ff3c80b292abbfbc6f6b2c405b commit 5bc33226b2a0e8ff3c80b292abbfbc6f6b2c405b Merge: ada1041 9175a37 Author: Brad King AuthorDate: Mon Nov 26 13:00:20 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 26 08:00:36 2018 -0500 Merge topic 'windows-taskbar-progress' 9175a378f5 QtDialog: Add windows taskbar progress Acked-by: Kitware Robot Merge-request: !2628 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ada104175454f8e393083f116e200344fe846f34 commit ada104175454f8e393083f116e200344fe846f34 Merge: af2960e ce2570b Author: Brad King AuthorDate: Mon Nov 26 12:59:53 2018 +0000 Commit: Kitware Robot CommitDate: Mon Nov 26 08:00:01 2018 -0500 Merge topic 'clang-tidy-bugprone' ce2570b207 clang-tidy: Enable checks from bugprone set Acked-by: Kitware Robot Merge-request: !2642 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ce2570b2071360c0b4bb4cd3c62ed8cccab26513 commit ce2570b2071360c0b4bb4cd3c62ed8cccab26513 Author: Regina Pfeifer AuthorDate: Tue Nov 20 09:13:58 2018 +0100 Commit: Brad King CommitDate: Wed Nov 21 07:47:40 2018 -0500 clang-tidy: Enable checks from bugprone set diff --git a/.clang-tidy b/.clang-tidy index cec7d03..0ba4b0b 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,8 @@ --- Checks: "-*,\ +bugprone-*,\ +-bugprone-macro-parentheses,\ +-bugprone-misplaced-widening-cast,\ google-readability-casting,\ misc-*,\ -misc-incorrect-roundings,\ diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 1d938e6..2e1bb0a 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -3,6 +3,7 @@ #include "cmCTestTestHandler.h" #include #include +#include #include #include #include @@ -544,8 +545,7 @@ int cmCTestTestHandler::ProcessHandler() } cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl - << passColorCode << static_cast(percent + .5f) - << "% tests passed" + << passColorCode << std::lround(percent) << "% tests passed" << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) << ", " << failedColorCode << failed.size() << " tests failed" << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 3012b0a..fa2a3e1 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -10,6 +10,7 @@ #include #include +#include #include #include // IWYU pragma: keep #include @@ -2602,10 +2603,10 @@ public: bool UpdatePercentage(double value, double total, std::string& status) { - int OldPercentage = this->CurrentPercentage; + long OldPercentage = this->CurrentPercentage; if (total > 0.0) { - this->CurrentPercentage = static_cast(value / total * 100.0 + 0.5); + this->CurrentPercentage = std::lround(value / total * 100.0); if (this->CurrentPercentage > 100) { // Avoid extra progress reports for unexpected data beyond total. this->CurrentPercentage = 100; @@ -2627,7 +2628,7 @@ public: cmFileCommand* GetFileCommand() { return this->FileCommand; } private: - int CurrentPercentage; + long CurrentPercentage; cmFileCommand* FileCommand; std::string Text; }; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9175a378f5d8786a54e35576853e7e6b068f17b0 commit 9175a378f5d8786a54e35576853e7e6b068f17b0 Author: Julien Jomier AuthorDate: Sat Nov 17 14:01:23 2018 +0100 Commit: Julien Jomier CommitDate: Tue Nov 20 17:16:08 2018 +0100 QtDialog: Add windows taskbar progress diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 330b747..9ce0323 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -19,9 +19,20 @@ if (Qt5Widgets_FOUND) macro(qt4_add_resources) qt5_add_resources(${ARGN}) endmacro() + set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES}) set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES}) + # Try to find the package WinExtras for the task bar progress + if(WIN32) + find_package(Qt5WinExtras QUIET) + if (Qt5WinExtras_FOUND) + include_directories(${Qt5WinExtras_INCLUDE_DIRS}) + add_definitions(-DQT_WINEXTRAS) + list(APPEND CMake_QT_LIBRARIES ${Qt5WinExtras_LIBRARIES}) + endif() + endif() + # Remove this when the minimum version of Qt is 4.6. add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0) diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 3761bd3..444a980 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -21,6 +21,11 @@ #include #include +#ifdef QT_WINEXTRAS +# include +# include +#endif + #include "AddCacheEntry.h" #include "FirstConfigure.h" #include "QCMake.h" @@ -294,6 +299,12 @@ void CMakeSetupDialog::initialize() } else { this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text()); } + +#ifdef QT_WINEXTRAS + this->TaskbarButton = new QWinTaskbarButton(this); + this->TaskbarButton->setWindow(this->windowHandle()); + this->TaskbarButton->setOverlayIcon(QIcon(":/loading.png")); +#endif } CMakeSetupDialog::~CMakeSetupDialog() @@ -381,6 +392,10 @@ void CMakeSetupDialog::doConfigure() this->CacheValues->scrollToTop(); } this->ProgressBar->reset(); + +#ifdef QT_WINEXTRAS + this->TaskbarButton->progress()->reset(); +#endif } bool CMakeSetupDialog::doConfigureInternal() @@ -495,6 +510,9 @@ void CMakeSetupDialog::doGenerate() this->enterState(ReadyConfigure); this->ProgressBar->reset(); +#ifdef QT_WINEXTRAS + this->TaskbarButton->progress()->reset(); +#endif this->ConfigureNeeded = true; } @@ -674,6 +692,12 @@ void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent) { percent = (percent * ProgressFactor) + ProgressOffset; this->ProgressBar->setValue(qRound(percent * 100)); + +#ifdef QT_WINEXTRAS + QWinTaskbarProgress* progress = this->TaskbarButton->progress(); + progress->setVisible(true); + progress->setValue(qRound(percent * 100)); +#endif } void CMakeSetupDialog::error(const QString& msg) diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index 1cce35c..39c1053 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -15,6 +15,10 @@ class CMakeCacheModel; class QProgressBar; class QToolButton; +#ifdef QT_WINEXTRAS +class QWinTaskbarButton; +#endif + /// Qt user interface for CMake class CMakeSetupDialog : public QMainWindow @@ -118,6 +122,10 @@ protected: QEventLoop LocalLoop; +#ifdef QT_WINEXTRAS + QWinTaskbarButton* TaskbarButton; +#endif + float ProgressOffset; float ProgressFactor; }; ----------------------------------------------------------------------- Summary of changes: .clang-tidy | 3 +++ Source/CTest/cmCTestTestHandler.cxx | 4 ++-- Source/QtDialog/CMakeLists.txt | 11 +++++++++++ Source/QtDialog/CMakeSetupDialog.cxx | 24 ++++++++++++++++++++++++ Source/QtDialog/CMakeSetupDialog.h | 8 ++++++++ Source/cmFileCommand.cxx | 7 ++++--- 6 files changed, 52 insertions(+), 5 deletions(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 27 00:03:03 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 27 Nov 2018 00:03:03 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-519-gcee8434 Message-ID: <20181127050303.EABE3127541@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via cee843475d82150cc56d12badd04eb737bff6551 (commit) from 5bc33226b2a0e8ff3c80b292abbfbc6f6b2c405b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cee843475d82150cc56d12badd04eb737bff6551 commit cee843475d82150cc56d12badd04eb737bff6551 Author: Kitware Robot AuthorDate: Tue Nov 27 00:01:04 2018 -0500 Commit: Kitware Robot CommitDate: Tue Nov 27 00:01:04 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 32b08a7..63a1573 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 13) -set(CMake_VERSION_PATCH 20181126) +set(CMake_VERSION_PATCH 20181127) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 27 08:53:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 27 Nov 2018 08:53:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-546-gf49efe2 Message-ID: <20181127135305.DF0E71277BA@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via f49efe283ed005aac642f5af58ea971d468de88c (commit) via e3ec57483464b4c509e9f8b24e4ac8c6990f823b (commit) via bae71966fb35649dda8fc4f962316e3dbea8f787 (commit) via 2a6e8644dd9650c7c749990410a5c50f12a786cb (commit) via 4833d2ef45cccb8f3e6b5a48f9747386fd9193ac (commit) via 43deb8e004bcf143df8757c65ea5b5fa33bda893 (commit) via 4aad340ec446e3def2bda4f2d474ab0cf86e902e (commit) via 85a035bf00d53d33251f30f850be7be169cbcde8 (commit) via 2cf836fa5ee71417145ec93e8f962d08c4a7d565 (commit) via f54d28a838ca7d4efbbd0155c4f61c287ae2b9cb (commit) via 1f531e0428d0aa5804fd8f4d1b58fe69edc30eed (commit) via 0369362132b3deae30828299131647cc3754abeb (commit) via d9195ab081b9c23a96d5a9c1b8e8be4da4f6e976 (commit) via 0d80977af4bbd1c76448307f577a7f22db792e65 (commit) via c259912b14fc63db0441c30c33b79ebbef058e06 (commit) via 1ca53f5ef1335561d952603d48c48da549d41271 (commit) via 15ac4aae0e3199fe8ac7f46cf4eb064cbeb1660d (commit) via 3125c47d27d4d57cb31e10c4bd658fc1e352299d (commit) via 36bbd07a765820ddbcaef3db4e2a78d95910f5e1 (commit) via e1dfe8cee619be2db2dcccfae5381376d336c6a3 (commit) via d5f691be0b78a48e836dc42b97d000ba151c44d6 (commit) via 8b63265ea53dbd2e035a6b616ba0e82bfc0decc0 (commit) via ede1715c1d4f35e806e3dabddd09c39eeed9a628 (commit) via 03879b11af0b2179d879358df3cce3c2b7acb047 (commit) via b4edf7b5d2b2ba8eccfa0230dad98d0815a17d5d (commit) via fc149a72f7e9128c0ad54014d745500fd31eea36 (commit) via f0d52f55f155ac3f3e2bafa072a4e0d7f1431d76 (commit) from cee843475d82150cc56d12badd04eb737bff6551 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f49efe283ed005aac642f5af58ea971d468de88c commit f49efe283ed005aac642f5af58ea971d468de88c Merge: e3ec574 0d80977 Author: Brad King AuthorDate: Tue Nov 27 13:51:18 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:51:27 2018 -0500 Merge topic 'autogen_target_docs' 0d80977af4 Autogen: Documentation updates Acked-by: Kitware Robot Merge-request: !2659 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e3ec57483464b4c509e9f8b24e4ac8c6990f823b commit e3ec57483464b4c509e9f8b24e4ac8c6990f823b Merge: bae7196 85a035b Author: Brad King AuthorDate: Tue Nov 27 13:50:00 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:50:07 2018 -0500 Merge topic 'FindDoxygen-win-glob' 85a035bf00 FindDoxygen: Avoid Windows-specific GLOB on other platforms Acked-by: Kitware Robot Merge-request: !2660 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bae71966fb35649dda8fc4f962316e3dbea8f787 commit bae71966fb35649dda8fc4f962316e3dbea8f787 Merge: 2a6e864 d9195ab Author: Brad King AuthorDate: Tue Nov 27 13:48:33 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:48:49 2018 -0500 Merge topic 'ctest-updates' d9195ab081 Tests: Teach run_ctest to handle removal of CTestConfig.cmake 1ca53f5ef1 Remove unnecessary CTEST_PROJECT_NAME variables 15ac4aae0e Remove warning when no CTestConfig.cmake file exists 3125c47d27 ctest_build: Do not require unnecessary [CTEST_]PROJECT_NAME value 36bbd07a76 CDashUpload: Use the query part of the submit url as field e1dfe8cee6 CTest: Don't require 'submit.php?' in submit location Acked-by: Kitware Robot Merge-request: !2640 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2a6e8644dd9650c7c749990410a5c50f12a786cb commit 2a6e8644dd9650c7c749990410a5c50f12a786cb Merge: 4833d2e c259912 Author: Brad King AuthorDate: Tue Nov 27 13:48:00 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:48:08 2018 -0500 Merge topic 'blaslapack_mkl_gfortran' c259912b14 FindBLAS: Do not look for BLAS once BLAS95 has been found d5f691be0b FindLAPACK: Additional libraries for MKL+gfortran combination 8b63265ea5 FindLAPACK: Unify internal variables related to MKL ede1715c1d FindLAPACK: Remove MKL components already provided by MKL BLAS 03879b11af FindLAPACK: Prioritize Intel MKL b4edf7b5d2 FindBLAS: Support 32bit Intel MKL 10.3+ fc149a72f7 FindBLAS: Support combination of gfortran and Intel MKL f0d52f55f1 FindBLAS: Consolidate duplicated code related to MKL on Windows Acked-by: Kitware Robot Merge-request: !2633 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4833d2ef45cccb8f3e6b5a48f9747386fd9193ac commit 4833d2ef45cccb8f3e6b5a48f9747386fd9193ac Merge: 43deb8e 2cf836f Author: Brad King AuthorDate: Tue Nov 27 08:45:18 2018 -0500 Commit: Brad King CommitDate: Tue Nov 27 08:45:18 2018 -0500 Merge branch 'release-3.13' https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=43deb8e004bcf143df8757c65ea5b5fa33bda893 commit 43deb8e004bcf143df8757c65ea5b5fa33bda893 Merge: 4aad340 f54d28a Author: Brad King AuthorDate: Tue Nov 27 13:44:34 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:45:00 2018 -0500 Merge topic 'vs2015-no-sdk' f54d28a838 VS: Avoid crash with VS 2015 when all SDKs are higher than 10.0.14393.0 Acked-by: Kitware Robot Merge-request: !2656 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4aad340ec446e3def2bda4f2d474ab0cf86e902e commit 4aad340ec446e3def2bda4f2d474ab0cf86e902e Merge: cee8434 0369362 Author: Brad King AuthorDate: Tue Nov 27 13:44:03 2018 +0000 Commit: Kitware Robot CommitDate: Tue Nov 27 08:44:11 2018 -0500 Merge topic 'FindBoost-no-cxx' 0369362132 FindBoost: Restore finding without CXX language enabled Acked-by: Kitware Robot Merge-request: !2663 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=85a035bf00d53d33251f30f850be7be169cbcde8 commit 85a035bf00d53d33251f30f850be7be169cbcde8 Author: Noel Eck AuthorDate: Mon Nov 26 16:25:26 2018 +0100 Commit: Brad King CommitDate: Mon Nov 26 14:39:36 2018 -0500 FindDoxygen: Avoid Windows-specific GLOB on other platforms When `$ENV{ProgramFiles}` is empty, GLOB takes `/Graphviz*/bin` as a path cusing the implementation to look at every directory in `/`. If the system has a slow(er) path mounted on '/' then `stat` call can take some time. There *may* be a better fix for this elsewhere, but for now simply do this GLOB only on Windows. Signed-off-by: Noel Eck diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 2ed9449..fdd3a92 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -485,12 +485,18 @@ endmacro() # Find Graphviz Dot... # macro(_Doxygen_find_dot) - set(_x86 "(x86)") - file( - GLOB _Doxygen_GRAPHVIZ_BIN_DIRS - "$ENV{ProgramFiles}/Graphviz*/bin" - "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" - ) + if(WIN32) + set(_x86 "(x86)") + file( + GLOB _Doxygen_GRAPHVIZ_BIN_DIRS + "$ENV{ProgramFiles}/Graphviz*/bin" + "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" + ) + unset(_x86) + else() + set(_Doxygen_GRAPHVIZ_BIN_DIRS "") + endif() + find_program( DOXYGEN_DOT_EXECUTABLE NAMES dot @@ -529,7 +535,6 @@ macro(_Doxygen_find_dot) endif() unset(_Doxygen_GRAPHVIZ_BIN_DIRS) - unset(_x86) endmacro() # https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d9195ab081b9c23a96d5a9c1b8e8be4da4f6e976 commit d9195ab081b9c23a96d5a9c1b8e8be4da4f6e976 Author: Brad King AuthorDate: Mon Nov 26 08:05:13 2018 -0500 Commit: Brad King CommitDate: Mon Nov 26 08:05:13 2018 -0500 Tests: Teach run_ctest to handle removal of CTestConfig.cmake When running tests in a non-fresh build tree there may be files left from previous test runs. In the case that a test removes `CTestConfig.cmake.in`, we must remove any `CTestConfig.cmake` that may have been left behind. diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake index c2c31d1..98fdf20 100644 --- a/Tests/RunCMake/RunCTest.cmake +++ b/Tests/RunCMake/RunCTest.cmake @@ -6,6 +6,8 @@ function(run_ctest CASE_NAME) if(EXISTS "${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in") configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake @ONLY) + else() + file(REMOVE ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake) endif() configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in ${RunCMake_BINARY_DIR}/${CASE_NAME}/CMakeLists.txt @ONLY) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0d80977af4bbd1c76448307f577a7f22db792e65 commit 0d80977af4bbd1c76448307f577a7f22db792e65 Author: Sebastian Holtermann AuthorDate: Mon Nov 26 09:53:40 2018 +0100 Commit: Sebastian Holtermann CommitDate: Mon Nov 26 09:57:20 2018 +0100 Autogen: Documentation updates This extends the documentation for - :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` - :prop_tgt:`AUTOGEN_TARGET_DEPENDS` - :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst index f61089a..022bab5 100644 --- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst @@ -5,22 +5,34 @@ Switch for forwarding origin target dependencies to the corresponding ``_autogen`` target. Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding ``_autogen`` target which is used to auto generate +``ON`` have a corresponding ``_autogen`` target which generates ``moc`` and ``uic`` files. As this ``_autogen`` target is created at -generate-time, it is not possible to define dependencies of it, -such as to create inputs for the ``moc`` or ``uic`` executable. - -The dependencies of the ``_autogen`` target are composed from - -- the origin target dependencies - (by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) -- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` - -:prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` decides whether the origin target -dependencies should be forwarded to the ``_autogen`` target or not. +generate-time, it is not possible to define dependencies of it using +e.g. :command:`add_dependencies`. Instead the +:prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property decides whether the origin +target dependencies should be forwarded to the ``_autogen`` target or not. By default :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` is initialized from :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default. +In total the dependencies of the ``_autogen`` target are composed from + +- forwarded origin target dependencies + (enabled by default via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) +- additional user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. + +Note +^^^^ + +Disabling :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` is useful to avoid building of +origin target dependencies when building the ``_autogen`` target only. +This is especially interesting when a +:variable:`global autogen target ` is enabled. + +When the ``_autogen`` target doesn't require all the origin target's +dependencies, and :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` is disabled, it might be +necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` to add missing +dependencies. diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index 84c2bfe..d5c5e14 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst @@ -1,23 +1,22 @@ AUTOGEN_TARGET_DEPENDS ---------------------- -Target dependencies of the corresponding ``_autogen`` target. +Additional target dependencies of the corresponding ``_autogen`` target. Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding ``_autogen`` target which is used to auto generate +``ON`` have a corresponding ``_autogen`` target which generates ``moc`` and ``uic`` files. As this ``_autogen`` target is created at -generate-time, it is not possible to define dependencies of it, -such as to create inputs for the ``moc`` or ``uic`` executable. +generate-time, it is not possible to define dependencies of it using +e.g. :command:`add_dependencies`. Instead the +:prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set to a +:ref:`;-list ` of additional dependencies for the +``_autogen`` target. Dependencies can be target names or file names. -The dependencies of the ``_autogen`` target are composed from +In total the dependencies of the ``_autogen`` target are composed from -- the origin target dependencies - (by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) -- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` - -The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set to a -list of additional dependencies for the ``_autogen`` target. Dependencies -can be target names or file names. +- forwarded origin target dependencies + (enabled by default via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) +- additional user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS` See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. @@ -32,6 +31,6 @@ If :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` depends on a file that is either - a :prop_sf:`GENERATED` C++ file that isn't recognized by :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` because it's skipped by :prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071` or -- a file that isn't in the target's sources +- a file that isn't in the origin target's sources it must added to :prop_tgt:`AUTOGEN_TARGET_DEPENDS`. diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst index 75903ab..e82867d 100644 --- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst @@ -16,3 +16,11 @@ By default :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is unset. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. + +Note +^^^^ + +``_autogen`` targets by default inherit their origin target's +dependencies. This might result in unintended dependency target +builds when only ``_autogen`` targets are built. A solution is to +disable :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on the respective origin targets. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c259912b14fc63db0441c30c33b79ebbef058e06 commit c259912b14fc63db0441c30c33b79ebbef058e06 Author: Jakub Benda AuthorDate: Sun Nov 18 21:37:14 2018 +0000 Commit: Jakub Benda CommitDate: Sat Nov 24 12:14:32 2018 +0000 FindBLAS: Do not look for BLAS once BLAS95 has been found When BLA_F95 is ON, FindBLAS looks for BLAS95_LIBRARIES (in Intel MKL). As this is a superset of BLAS_LIBRARIES, if they are found, no further search in other vendors is necessary. diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index c286a4d..cd6ed8f 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -405,6 +405,14 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") endif () endif () +if(BLA_F95) + find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES) + set(BLAS95_FOUND ${BLAS_FOUND}) + if(BLAS_FOUND) + set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") + endif() +endif() + if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") if(NOT BLAS_LIBRARIES) # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) @@ -740,13 +748,7 @@ if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") endif() endif () -if(BLA_F95) - find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES) - set(BLAS95_FOUND ${BLAS_FOUND}) - if(BLAS_FOUND) - set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") - endif() -else() +if(NOT BLA_F95) find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES) endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1ca53f5ef1335561d952603d48c48da549d41271 commit 1ca53f5ef1335561d952603d48c48da549d41271 Author: Regina Pfeifer AuthorDate: Tue Nov 20 17:08:02 2018 +0100 Commit: Regina Pfeifer CommitDate: Tue Nov 20 21:43:27 2018 +0100 Remove unnecessary CTEST_PROJECT_NAME variables diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 2ea931d..18bb452 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -27,7 +27,6 @@ to creating tests when testing is enabled. To enable submissions to a CDash server, create a ``CTestConfig.cmake`` file at the top of the project with content such as:: - set(CTEST_PROJECT_NAME "MyProject") set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "my.cdash.org") diff --git a/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in b/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in index 670a874..0f56781 100644 --- a/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in +++ b/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 2.8.10) set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/VSProjectInSubdir") set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestBuildCommandProjectInSubdir/Nested") set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") -set(CTEST_PROJECT_NAME "VSProjectInSubdir") set(CTEST_BUILD_CONFIGURATION "@CTestTest_CONFIG@") ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) diff --git a/Tests/CTestConfig/script.cmake.in b/Tests/CTestConfig/script.cmake.in index b6ccedb..973c7b8 100644 --- a/Tests/CTestConfig/script.cmake.in +++ b/Tests/CTestConfig/script.cmake.in @@ -1,7 +1,6 @@ set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@") set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") -set(CTEST_PROJECT_NAME "CTestConfig") set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig") set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg at -script") diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in index d48ef61..2c98876 100644 --- a/Tests/CTestCoverageCollectGCOV/test.cmake.in +++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 2.8.12) -set(CTEST_PROJECT_NAME "TestProject") set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/TestProject") set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV/TestProject") set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") diff --git a/Tests/CTestTestBadExe/CTestConfig.cmake b/Tests/CTestTestBadExe/CTestConfig.cmake index c7286e2..fc5bffc 100644 --- a/Tests/CTestTestBadExe/CTestConfig.cmake +++ b/Tests/CTestTestBadExe/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestBadExe") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestBadGenerator/CTestConfig.cmake b/Tests/CTestTestBadGenerator/CTestConfig.cmake index 1e61bf4..fc5bffc 100644 --- a/Tests/CTestTestBadGenerator/CTestConfig.cmake +++ b/Tests/CTestTestBadGenerator/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestBadGenerator") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestCostSerial/CTestConfig.cmake b/Tests/CTestTestCostSerial/CTestConfig.cmake index 3ab99ac..faa91f0 100644 --- a/Tests/CTestTestCostSerial/CTestConfig.cmake +++ b/Tests/CTestTestCostSerial/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestCostSerial") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestCrash/CTestConfig.cmake b/Tests/CTestTestCrash/CTestConfig.cmake index 5c2ca0e..fc5bffc 100644 --- a/Tests/CTestTestCrash/CTestConfig.cmake +++ b/Tests/CTestTestCrash/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestCrash") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestCycle/CTestConfig.cmake b/Tests/CTestTestCycle/CTestConfig.cmake index 8aeb09b..fc5bffc 100644 --- a/Tests/CTestTestCycle/CTestConfig.cmake +++ b/Tests/CTestTestCycle/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestCycle") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestDepends/CTestConfig.cmake b/Tests/CTestTestDepends/CTestConfig.cmake index 7af9200..fc5bffc 100644 --- a/Tests/CTestTestDepends/CTestConfig.cmake +++ b/Tests/CTestTestDepends/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestDepends") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestFailure/CTestConfig.cmake b/Tests/CTestTestFailure/CTestConfig.cmake index 07e1be0..fc5bffc 100644 --- a/Tests/CTestTestFailure/CTestConfig.cmake +++ b/Tests/CTestTestFailure/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestFailure") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestFdSetSize/CTestConfig.cmake b/Tests/CTestTestFdSetSize/CTestConfig.cmake deleted file mode 100644 index b5f3c33..0000000 --- a/Tests/CTestTestFdSetSize/CTestConfig.cmake +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestTestFdSetSize") diff --git a/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake index 669b0fb..409d83a 100644 --- a/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake +++ b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake @@ -1,5 +1,4 @@ set(CTEST_USE_LAUNCHERS 1) -set(CTEST_PROJECT_NAME "CTestTestLaunchers") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake index 669b0fb..409d83a 100644 --- a/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake +++ b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake @@ -1,5 +1,4 @@ set(CTEST_USE_LAUNCHERS 1) -set(CTEST_PROJECT_NAME "CTestTestLaunchers") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake index 669b0fb..409d83a 100644 --- a/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake +++ b/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake @@ -1,5 +1,4 @@ set(CTEST_USE_LAUNCHERS 1) -set(CTEST_PROJECT_NAME "CTestTestLaunchers") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestParallel/CTestConfig.cmake b/Tests/CTestTestParallel/CTestConfig.cmake index fc5b666..faa91f0 100644 --- a/Tests/CTestTestParallel/CTestConfig.cmake +++ b/Tests/CTestTestParallel/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestParallel") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestResourceLock/CTestConfig.cmake b/Tests/CTestTestResourceLock/CTestConfig.cmake index c118777..faa91f0 100644 --- a/Tests/CTestTestResourceLock/CTestConfig.cmake +++ b/Tests/CTestTestResourceLock/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestResourceLock") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestScheduler/CTestConfig.cmake b/Tests/CTestTestScheduler/CTestConfig.cmake index 797387b..faa91f0 100644 --- a/Tests/CTestTestScheduler/CTestConfig.cmake +++ b/Tests/CTestTestScheduler/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestScheduler") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestSkipReturnCode/CTestConfig.cmake b/Tests/CTestTestSkipReturnCode/CTestConfig.cmake index da0c76b..fc5bffc 100644 --- a/Tests/CTestTestSkipReturnCode/CTestConfig.cmake +++ b/Tests/CTestTestSkipReturnCode/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestSkipReturnCode") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestStopTime/CTestConfig.cmake b/Tests/CTestTestStopTime/CTestConfig.cmake index 412283e..fc5bffc 100644 --- a/Tests/CTestTestStopTime/CTestConfig.cmake +++ b/Tests/CTestTestStopTime/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestStopTime") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestSubdir/CTestConfig.cmake b/Tests/CTestTestSubdir/CTestConfig.cmake index 47ebb92..faa91f0 100644 --- a/Tests/CTestTestSubdir/CTestConfig.cmake +++ b/Tests/CTestTestSubdir/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestSubdir") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestTimeout/CTestConfig.cmake b/Tests/CTestTestTimeout/CTestConfig.cmake index 13114f1..faa91f0 100644 --- a/Tests/CTestTestTimeout/CTestConfig.cmake +++ b/Tests/CTestTestTimeout/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestTimeout") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestUpload/CTestConfig.cmake b/Tests/CTestTestUpload/CTestConfig.cmake index a547088..95c79ff 100644 --- a/Tests/CTestTestUpload/CTestConfig.cmake +++ b/Tests/CTestTestUpload/CTestConfig.cmake @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestUpload") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set (CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestVerboseOutput/CTestConfig.cmake b/Tests/CTestTestVerboseOutput/CTestConfig.cmake index 4f96c79..faa91f0 100644 --- a/Tests/CTestTestVerboseOutput/CTestConfig.cmake +++ b/Tests/CTestTestVerboseOutput/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestVerboseOutput") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestTestZeroTimeout/CTestConfig.cmake b/Tests/CTestTestZeroTimeout/CTestConfig.cmake index 6094864..faa91f0 100644 --- a/Tests/CTestTestZeroTimeout/CTestConfig.cmake +++ b/Tests/CTestTestZeroTimeout/CTestConfig.cmake @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestTestZeroTimeout") set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set(CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake index 61aa13b..0f8ec8e 100644 --- a/Tests/CTestUpdateCommon.cmake +++ b/Tests/CTestUpdateCommon.cmake @@ -130,7 +130,6 @@ function(create_content dir) # An example CTest project configuration file. file(WRITE ${TOP}/${dir}/CTestConfig.cmake "# CTest Configuration File -set(CTEST_PROJECT_NAME TestProject) set(CTEST_NIGHTLY_START_TIME \"21:00:00 EDT\") ") diff --git a/Tests/RunCMake/CTestTimeoutAfterMatch/CTestConfig.cmake.in b/Tests/RunCMake/CTestTimeoutAfterMatch/CTestConfig.cmake.in deleted file mode 100644 index 58b11af..0000000 --- a/Tests/RunCMake/CTestTimeoutAfterMatch/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "TimeoutAfterMatch at CASE_NAME@") diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake index 89e16ee..c2c31d1 100644 --- a/Tests/RunCMake/RunCTest.cmake +++ b/Tests/RunCMake/RunCTest.cmake @@ -3,8 +3,10 @@ include(RunCMake) function(run_ctest CASE_NAME) configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake @ONLY) - configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in - ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake @ONLY) + if(EXISTS "${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in") + configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in + ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake @ONLY) + endif() configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in ${RunCMake_BINARY_DIR}/${CASE_NAME}/CMakeLists.txt @ONLY) run_cmake_command(${CASE_NAME} ${CMAKE_CTEST_COMMAND} diff --git a/Tests/RunCMake/WorkingDirectory/CTestConfig.cmake.in b/Tests/RunCMake/WorkingDirectory/CTestConfig.cmake.in deleted file mode 100644 index 0226230..0000000 --- a/Tests/RunCMake/WorkingDirectory/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestTestWorkingDir. at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt index 2e59d99..cc9085f 100644 --- a/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt +++ b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_build/BuildQuiet Build directory: .*/Tests/RunCMake/ctest_build/BuildQuiet-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_build/BuildQuiet/CTestConfig.cmake Site: test-site Build name: test-build-name Use Experimental tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_build/CTestConfig.cmake.in b/Tests/RunCMake/ctest_build/CTestConfig.cmake.in deleted file mode 100644 index 097f82c..0000000 --- a/Tests/RunCMake/ctest_build/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestBuild at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_cmake_error/CTestConfig.cmake.in b/Tests/RunCMake/ctest_cmake_error/CTestConfig.cmake.in deleted file mode 100644 index 1f679d5..0000000 --- a/Tests/RunCMake/ctest_cmake_error/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestCoverage at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in b/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in deleted file mode 100644 index 7e30ab9..0000000 --- a/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestConfigure at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt index 015644d..98f5a4c 100644 --- a/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt +++ b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet Build directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet/CTestConfig.cmake Site: test-site Build name: test-build-name Use Experimental tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in b/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in deleted file mode 100644 index 1f679d5..0000000 --- a/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestCoverage at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_disabled_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_disabled_test/CTestConfig.cmake.in deleted file mode 100644 index c0d7e42..0000000 --- a/Tests/RunCMake/ctest_disabled_test/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_fixtures/CTestConfig.cmake.in b/Tests/RunCMake/ctest_fixtures/CTestConfig.cmake.in deleted file mode 100644 index 9823562..0000000 --- a/Tests/RunCMake/ctest_fixtures/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestTestFixtures. at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_labels_for_subprojects/CTestConfig.cmake.in b/Tests/RunCMake/ctest_labels_for_subprojects/CTestConfig.cmake.in index 1e1905b..5d83530 100644 --- a/Tests/RunCMake/ctest_labels_for_subprojects/CTestConfig.cmake.in +++ b/Tests/RunCMake/ctest_labels_for_subprojects/CTestConfig.cmake.in @@ -1,2 +1 @@ -set(CTEST_PROJECT_NAME "CTestLabelsForSubprojects at CASE_NAME@") @CTEST_EXTRA_CONFIG@ diff --git a/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in index 6d4a718..fe6f6ce 100644 --- a/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in +++ b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in @@ -1,4 +1,3 @@ -set (CTEST_PROJECT_NAME "CTestTestMemcheck at CASE_NAME@") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in deleted file mode 100644 index c0d7e42..0000000 --- a/Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_start/AppendDifferentModel-stdout.txt b/Tests/RunCMake/ctest_start/AppendDifferentModel-stdout.txt index bc9a4c8..78f36a1 100644 --- a/Tests/RunCMake/ctest_start/AppendDifferentModel-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendDifferentModel-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_start/AppendDifferentModel Build directory: .*/Tests/RunCMake/ctest_start/AppendDifferentModel-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendDifferentModel/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - ContinuousTrack diff --git a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt index ab1c1f7..25085ef 100644 --- a/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendDifferentTrack-stdout.txt @@ -2,7 +2,6 @@ Run dashboard with to-be-determined model Source directory: .*/Tests/RunCMake/ctest_start/AppendDifferentTrack Build directory: .*/Tests/RunCMake/ctest_start/AppendDifferentTrack-build Track: ExperimentalDifferent - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendDifferentTrack/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - ExperimentalDifferent diff --git a/Tests/RunCMake/ctest_start/AppendNoMatchingTrack-stdout.txt b/Tests/RunCMake/ctest_start/AppendNoMatchingTrack-stdout.txt index 55f2d8e..5780629 100644 --- a/Tests/RunCMake/ctest_start/AppendNoMatchingTrack-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendNoMatchingTrack-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Continuous Source directory: .*/Tests/RunCMake/ctest_start/AppendNoMatchingTrack Build directory: .*/Tests/RunCMake/ctest_start/AppendNoMatchingTrack-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendNoMatchingTrack/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - SomeWeirdTrackName diff --git a/Tests/RunCMake/ctest_start/AppendNoModel-stdout.txt b/Tests/RunCMake/ctest_start/AppendNoModel-stdout.txt index f909a44..bcd0125 100644 --- a/Tests/RunCMake/ctest_start/AppendNoModel-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendNoModel-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with to-be-determined model Source directory: .*/Tests/RunCMake/ctest_start/AppendNoModel Build directory: .*/Tests/RunCMake/ctest_start/AppendNoModel-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendNoModel/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - ContinuousTrack diff --git a/Tests/RunCMake/ctest_start/AppendOldContinuous-stdout.txt b/Tests/RunCMake/ctest_start/AppendOldContinuous-stdout.txt index 0660f5d..e58cd9c 100644 --- a/Tests/RunCMake/ctest_start/AppendOldContinuous-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendOldContinuous-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Continuous Source directory: .*/Tests/RunCMake/ctest_start/AppendOldContinuous Build directory: .*/Tests/RunCMake/ctest_start/AppendOldContinuous-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendOldContinuous/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - ContinuousTrack diff --git a/Tests/RunCMake/ctest_start/AppendOldNoModel-stdout.txt b/Tests/RunCMake/ctest_start/AppendOldNoModel-stdout.txt index 0bdf9e4..47331e6 100644 --- a/Tests/RunCMake/ctest_start/AppendOldNoModel-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendOldNoModel-stdout.txt @@ -1,6 +1,5 @@ Run dashboard with to-be-determined model Source directory: .*/Tests/RunCMake/ctest_start/AppendOldNoModel Build directory: .*/Tests/RunCMake/ctest_start/AppendOldNoModel-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendOldNoModel/CTestConfig.cmake Site: test-site Build name: test-build-name diff --git a/Tests/RunCMake/ctest_start/AppendSameModel-stdout.txt b/Tests/RunCMake/ctest_start/AppendSameModel-stdout.txt index 4f43626..3abd51e 100644 --- a/Tests/RunCMake/ctest_start/AppendSameModel-stdout.txt +++ b/Tests/RunCMake/ctest_start/AppendSameModel-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Continuous Source directory: .*/Tests/RunCMake/ctest_start/AppendSameModel Build directory: .*/Tests/RunCMake/ctest_start/AppendSameModel-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/AppendSameModel/CTestConfig.cmake Site: test-site Build name: test-build-name Use existing tag: 19551112-2204 - ContinuousTrack diff --git a/Tests/RunCMake/ctest_start/CTestConfig.cmake.in b/Tests/RunCMake/ctest_start/CTestConfig.cmake.in deleted file mode 100644 index e75d14f..0000000 --- a/Tests/RunCMake/ctest_start/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestStart at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt index 7e94b8a..f4a0ba3 100644 --- a/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt +++ b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild Build directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build/CTestConfig.cmake Site: test-site Build name: test-build-name Use Experimental tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt index c390372..5f98b4e 100644 --- a/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt +++ b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt @@ -1,7 +1,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_start/ConfigInSource Build directory: .*/Tests/RunCMake/ctest_start/ConfigInSource-build - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInSource/CTestConfig.cmake Site: test-site Build name: test-build-name Use Experimental tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt index 4a6f1e9..20a29be 100644 --- a/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt +++ b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt @@ -2,7 +2,6 @@ Run dashboard with model Experimental Source directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack Build directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-build Track: ExperimentalDifferent - Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack/CTestConfig.cmake Site: test-site Build name: test-build-name Use ExperimentalDifferent tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake index 9b57b1b..905ad00 100644 --- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake @@ -48,8 +48,6 @@ function(run_ConfigInBuild) set(RunCMake_TEST_NO_CLEAN 1) file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") - configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in - ${RunCMake_BINARY_DIR}/ConfigInBuild-build/CTestConfig.cmake @ONLY) run_ctest_start(ConfigInBuild Experimental) endfunction() run_ConfigInBuild() diff --git a/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in index 378a85a..140e4be 100644 --- a/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in +++ b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in @@ -1,4 +1,3 @@ -set(CTEST_PROJECT_NAME "CTestSubmit at CASE_NAME@") # Intentionally leave out other upload-related CTestConfig.cmake settings # so that any ctest_submit calls fail with an error message. diff --git a/Tests/RunCMake/ctest_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_test/CTestConfig.cmake.in deleted file mode 100644 index 9004419..0000000 --- a/Tests/RunCMake/ctest_test/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestTest at CASE_NAME@") diff --git a/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in b/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in deleted file mode 100644 index 52665a8..0000000 --- a/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(CTEST_PROJECT_NAME "CTestUpload at CASE_NAME@") diff --git a/Tests/Tutorial/Step7/CTestConfig.cmake b/Tests/Tutorial/Step7/CTestConfig.cmake deleted file mode 100644 index d8f5c44..0000000 --- a/Tests/Tutorial/Step7/CTestConfig.cmake +++ /dev/null @@ -1 +0,0 @@ -set (CTEST_PROJECT_NAME "Tutorial") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=15ac4aae0e3199fe8ac7f46cf4eb064cbeb1660d commit 15ac4aae0e3199fe8ac7f46cf4eb064cbeb1660d Author: Regina Pfeifer AuthorDate: Tue Nov 20 21:19:45 2018 +0100 Commit: Regina Pfeifer CommitDate: Tue Nov 20 21:23:59 2018 +0100 Remove warning when no CTestConfig.cmake file exists Some CTestConfig.cmake files used to set CTEST_PROJECT_NAME only. Since this variable is no longer used, it is more likely that the whole file is no longer provided by projects. diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index c2b6575..56c71c2 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -649,16 +649,6 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) command->SetError(m); return false; } - } else { - cmCTestOptionalLog(this, WARNING, - "Cannot locate CTest configuration: in BuildDirectory: " - << bld_dir_fname << std::endl, - command->ShouldBeQuiet()); - cmCTestOptionalLog( - this, WARNING, - "Cannot locate CTest configuration: in SourceDirectory: " - << src_dir_fname << std::endl, - command->ShouldBeQuiet()); } this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime", https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3125c47d27d4d57cb31e10c4bd658fc1e352299d commit 3125c47d27d4d57cb31e10c4bd658fc1e352299d Author: Regina Pfeifer AuthorDate: Tue Nov 20 13:50:19 2018 +0100 Commit: Regina Pfeifer CommitDate: Tue Nov 20 21:23:59 2018 +0100 ctest_build: Do not require unnecessary [CTEST_]PROJECT_NAME value Since commit v3.0.0-rc1~260^2~32 (ctest_build: Use "cmake --build" to launch the native build tool, 2013-11-14) we no longer need to use the project name in `ctest_build()`. Fixes: #18612 diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst index 55bb4a3..66e1844 100644 --- a/Help/command/ctest_build.rst +++ b/Help/command/ctest_build.rst @@ -50,9 +50,7 @@ The options are: for an example. ``PROJECT_NAME `` - Set the name of the project to build. This should correspond - to the top-level call to the :command:`project` command. - If not specified the ``CTEST_PROJECT_NAME`` variable will be checked. + Ignored. This was once used but is no longer needed. ``TARGET `` Specify the name of a target to build. If not specified the diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index ce27da1..65b4976 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -53,10 +53,6 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() } else { const char* cmakeGeneratorName = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR"); - const char* cmakeProjectName = - (this->Values[ctb_PROJECT_NAME] && *this->Values[ctb_PROJECT_NAME]) - ? this->Values[ctb_PROJECT_NAME] - : this->Makefile->GetDefinition("CTEST_PROJECT_NAME"); // Build configuration is determined by: CONFIGURATION argument, // or CTEST_BUILD_CONFIGURATION script variable, or @@ -81,8 +77,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() ? this->Values[ctb_TARGET] : this->Makefile->GetDefinition("CTEST_BUILD_TARGET"); - if (cmakeGeneratorName && *cmakeGeneratorName && cmakeProjectName && - *cmakeProjectName) { + if (cmakeGeneratorName && *cmakeGeneratorName) { if (!cmakeBuildConfiguration) { cmakeBuildConfiguration = "Release"; } @@ -132,14 +127,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() /* clang-format off */ ostr << "has no project to build. If this is a " "\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR " - "and CTEST_PROJECT_NAME are set." - "\n" - "CTEST_PROJECT_NAME is usually set in CTestConfig.cmake. Verify " - "that CTestConfig.cmake exists, or CTEST_PROJECT_NAME " - "is set in the script, or PROJECT_NAME is passed as an argument " - "to ctest_build." - "\n" - "Alternatively, set CTEST_BUILD_COMMAND to build the project " + "is set. Otherwise, set CTEST_BUILD_COMMAND to build the project " "with a custom command line."; /* clang-format on */ this->SetError(ostr.str()); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=36bbd07a765820ddbcaef3db4e2a78d95910f5e1 commit 36bbd07a765820ddbcaef3db4e2a78d95910f5e1 Author: Regina Pfeifer AuthorDate: Tue Nov 20 16:29:08 2018 +0100 Commit: Regina Pfeifer CommitDate: Tue Nov 20 21:23:59 2018 +0100 CDashUpload: Use the query part of the submit url as field diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 34adb4a..60029ab 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -23,8 +23,6 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() const char* ctestTriggerSite = 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"; } @@ -37,8 +35,6 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() // error: CDash requires CTEST_DROP_LOCATION definition // in CTestConfig.cmake } - this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName, - this->Quiet); this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod, this->Quiet); this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet); diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index d57b55e..061c8ef 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -1084,8 +1084,10 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, std::string dropMethod; std::string url; this->ConstructCDashURL(dropMethod, url); + std::string fields; std::string::size_type pos = url.find('?'); if (pos != std::string::npos) { + fields = url.substr(pos + 1); url = url.substr(0, pos); } if (!(dropMethod == "http" || dropMethod == "https")) { @@ -1135,8 +1137,6 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, const char* subproject = cm->GetState()->GetGlobalProperty("SubProject"); // TODO: Encode values for a URL instead of trusting caller. std::ostringstream str; - str << "project=" - << curl.Escape(this->CTest->GetCTestConfiguration("ProjectName")) << "&"; if (subproject) { str << "subproject=" << curl.Escape(subproject) << "&"; } @@ -1154,7 +1154,10 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << "endtime=" << timeNow << "&" << "datafilesmd5[0]=" << md5sum << "&" << "type=" << curl.Escape(typeString); - std::string fields = str.str(); + if (!fields.empty()) { + fields += '&'; + } + fields += str.str(); cmCTestOptionalLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:" << url << "\nfile: " << file << "\n", https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e1dfe8cee619be2db2dcccfae5381376d336c6a3 commit e1dfe8cee619be2db2dcccfae5381376d336c6a3 Author: Regina Pfeifer AuthorDate: Tue Nov 20 15:44:17 2018 +0100 Commit: Regina Pfeifer CommitDate: Tue Nov 20 21:23:59 2018 +0100 CTest: Don't require 'submit.php?' in submit location Fixes: #18611 diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 98872a5..d57b55e 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -1084,8 +1084,10 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, 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); + std::string::size_type pos = url.find('?'); + if (pos != std::string::npos) { + url = url.substr(0, pos); + } if (!(dropMethod == "http" || dropMethod == "https")) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Only http and https are supported for CDASH_UPLOAD\n"); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d5f691be0b78a48e836dc42b97d000ba151c44d6 commit d5f691be0b78a48e836dc42b97d000ba151c44d6 Author: Jakub Benda AuthorDate: Sun Nov 18 20:16:39 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 20:16:39 2018 +0000 FindLAPACK: Additional libraries for MKL+gfortran combination As per Intel MKL command line advisor, "libdl" is added to the list of libraries that provide LAPACK functionality. Furthermore, the implicit link directories are added to the searched libraries to allow finding of "libgomp". diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 89a1430..7619664 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -96,6 +96,9 @@ if (NOT _libdir) set(_libdir ENV LD_LIBRARY_PATH) endif () endif () + +list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + foreach(_library ${_list}) set(_combined_name ${_combined_name}_${_library}) @@ -179,6 +182,7 @@ if(BLAS_FOUND) if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT WIN32) set(LAPACK_mkl_LM "-lm") + set(LAPACK_mkl_LDL "-ldl") endif () if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) @@ -240,7 +244,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") "" "${IT}" "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM}" + "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}" ) endif () endforeach () @@ -248,6 +252,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") unset(LAPACK_mkl_ILP_MODE) unset(LAPACK_mkl_SEARCH_SYMBOL) unset(LAPACK_mkl_LM) + unset(LAPACK_mkl_LDL) endif () endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8b63265ea53dbd2e035a6b616ba0e82bfc0decc0 commit 8b63265ea53dbd2e035a6b616ba0e82bfc0decc0 Author: Jakub Benda AuthorDate: Sun Nov 18 20:00:14 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 20:00:14 2018 +0000 FindLAPACK: Unify internal variables related to MKL Auxiliary internal variables related to MKL are now consistently prefixed with LAPACK_mkl_ and unset at the end of the MKL section. diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index ad1cd45..89a1430 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -178,7 +178,7 @@ if(BLAS_FOUND) #intel lapack if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT WIN32) - set(LM "-lm") + set(LAPACK_mkl_LM "-lm") endif () if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) @@ -188,9 +188,9 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") endif() if (BLA_VENDOR MATCHES "_64ilp") - set(BLAS_mkl_ILP_MODE "ilp64") + set(LAPACK_mkl_ILP_MODE "ilp64") else () - set(BLAS_mkl_ILP_MODE "lp64") + set(LAPACK_mkl_ILP_MODE "lp64") endif () set(LAPACK_SEARCH_LIBS "") @@ -207,7 +207,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") list(APPEND LAPACK_SEARCH_LIBS "mkl_intel_c") list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95_${BLAS_mkl_ILP_MODE}") + "mkl_lapack95_${LAPACK_mkl_ILP_MODE}") else() set(LAPACK_mkl_SEARCH_SYMBOL "cheev") set(_LIBRARIES LAPACK_LIBRARIES) @@ -222,7 +222,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT ${_LIBRARIES}) check_lapack_libraries( ${_LIBRARIES} - BLAS + LAPACK ${LAPACK_mkl_SEARCH_SYMBOL} "" "" @@ -235,17 +235,19 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT ${_LIBRARIES}) check_lapack_libraries( ${_LIBRARIES} - BLAS + LAPACK ${LAPACK_mkl_SEARCH_SYMBOL} "" "${IT}" "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" + "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM}" ) endif () endforeach () - unset(BLAS_mkl_ILP_MODE) + unset(LAPACK_mkl_ILP_MODE) + unset(LAPACK_mkl_SEARCH_SYMBOL) + unset(LAPACK_mkl_LM) endif () endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ede1715c1d4f35e806e3dabddd09c39eeed9a628 commit ede1715c1d4f35e806e3dabddd09c39eeed9a628 Author: Jakub Benda AuthorDate: Sun Nov 18 19:53:32 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 19:56:24 2018 +0000 FindLAPACK: Remove MKL components already provided by MKL BLAS A surplus library libmkl_gf_... has been removed from the LAPACK libraries serach path (when relevant, it is already provided by BLAS). Similarly, the thread libraries do not need to be explicitly added to the implicit LAPACK libraries, as they are already included in the list (via BLAS libraries provided by FindBLAS). diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index d8daef2..ad1cd45 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -216,9 +216,6 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # old list(APPEND LAPACK_SEARCH_LIBS "mkl_lapack") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_gf_${BLAS_mkl_ILP_MODE}") endif() # First try empty lapack libs @@ -230,7 +227,7 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") "" "" "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" + "" ) endif () # Then try the search libs https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=03879b11af0b2179d879358df3cce3c2b7acb047 commit 03879b11af0b2179d879358df3cce3c2b7acb047 Author: Jakub Benda AuthorDate: Sun Nov 18 19:48:23 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 19:48:23 2018 +0000 FindLAPACK: Prioritize Intel MKL As in FindBLAS, the Intel Math Kernel Library is now the preferred LAPACK vendor. (The corresponding section of the code has been moved upwards.) diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 62ff94c..d8daef2 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -175,6 +175,83 @@ if(BLAS_FOUND) endif() endif () +#intel lapack +if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") + if (NOT WIN32) + set(LM "-lm") + endif () + if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) + if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_PACKAGE(Threads) + else() + find_package(Threads REQUIRED) + endif() + + if (BLA_VENDOR MATCHES "_64ilp") + set(BLAS_mkl_ILP_MODE "ilp64") + else () + set(BLAS_mkl_ILP_MODE "lp64") + endif () + + set(LAPACK_SEARCH_LIBS "") + + if (BLA_F95) + set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95") + set(_LIBRARIES LAPACK95_LIBRARIES) + set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) + + # old + list(APPEND LAPACK_SEARCH_LIBS + "mkl_lapack95") + # new >= 10.3 + list(APPEND LAPACK_SEARCH_LIBS + "mkl_intel_c") + list(APPEND LAPACK_SEARCH_LIBS + "mkl_lapack95_${BLAS_mkl_ILP_MODE}") + else() + set(LAPACK_mkl_SEARCH_SYMBOL "cheev") + set(_LIBRARIES LAPACK_LIBRARIES) + set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) + + # old + list(APPEND LAPACK_SEARCH_LIBS + "mkl_lapack") + # new >= 10.3 + list(APPEND LAPACK_SEARCH_LIBS + "mkl_gf_${BLAS_mkl_ILP_MODE}") + endif() + + # First try empty lapack libs + if (NOT ${_LIBRARIES}) + check_lapack_libraries( + ${_LIBRARIES} + BLAS + ${LAPACK_mkl_SEARCH_SYMBOL} + "" + "" + "${_BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif () + # Then try the search libs + foreach (IT ${LAPACK_SEARCH_LIBS}) + if (NOT ${_LIBRARIES}) + check_lapack_libraries( + ${_LIBRARIES} + BLAS + ${LAPACK_mkl_SEARCH_SYMBOL} + "" + "${IT}" + "${_BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif () + endforeach () + + unset(BLAS_mkl_ILP_MODE) + endif () +endif() + if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") if(NOT LAPACK_LIBRARIES) check_lapack_libraries( @@ -267,82 +344,7 @@ if (BLA_VENDOR STREQUAL "Generic" OR ) endif () endif () -#intel lapack -if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") - if (NOT WIN32) - set(LM "-lm") - endif () - if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) - if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_PACKAGE(Threads) - else() - find_package(Threads REQUIRED) - endif() - - if (BLA_VENDOR MATCHES "_64ilp") - set(BLAS_mkl_ILP_MODE "ilp64") - else () - set(BLAS_mkl_ILP_MODE "lp64") - endif () - - set(LAPACK_SEARCH_LIBS "") - - if (BLA_F95) - set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95") - set(_LIBRARIES LAPACK95_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) - - # old - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_intel_c") - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95_${BLAS_mkl_ILP_MODE}") - else() - set(LAPACK_mkl_SEARCH_SYMBOL "cheev") - set(_LIBRARIES LAPACK_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) - # old - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_gf_${BLAS_mkl_ILP_MODE}") - endif() - - # First try empty lapack libs - if (NOT ${_LIBRARIES}) - check_lapack_libraries( - ${_LIBRARIES} - BLAS - ${LAPACK_mkl_SEARCH_SYMBOL} - "" - "" - "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif () - # Then try the search libs - foreach (IT ${LAPACK_SEARCH_LIBS}) - if (NOT ${_LIBRARIES}) - check_lapack_libraries( - ${_LIBRARIES} - BLAS - ${LAPACK_mkl_SEARCH_SYMBOL} - "" - "${IT}" - "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif () - endforeach () - - unset(BLAS_mkl_ILP_MODE) - endif () -endif() else() message(STATUS "LAPACK requires BLAS") endif() https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b4edf7b5d2b2ba8eccfa0230dad98d0815a17d5d commit b4edf7b5d2b2ba8eccfa0230dad98d0815a17d5d Author: Jakub Benda AuthorDate: Sun Nov 18 16:14:39 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 17:00:37 2018 +0000 FindBLAS: Support 32bit Intel MKL 10.3+ The module FindBLAS now correctly finds Intel MKL distributions that do not have the (long deprecated) library "libguide", but use "libiomp5" instead. diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index d113579..c286a4d 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -285,8 +285,13 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") endforeach() else () if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + # old version list(APPEND BLAS_SEARCH_LIBS "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") + + # mkl >= 10.3 + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -341,11 +346,15 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") endforeach() else () if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + # old version list(APPEND BLAS_SEARCH_LIBS "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") + + # mkl >= 10.3 + list(APPEND BLAS_SEARCH_LIBS + "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") - # old version list(APPEND BLAS_SEARCH_LIBS "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fc149a72f7e9128c0ad54014d745500fd31eea36 commit fc149a72f7e9128c0ad54014d745500fd31eea36 Author: Jakub Benda AuthorDate: Sun Nov 18 15:05:28 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 16:59:03 2018 +0000 FindBLAS: Support combination of gfortran and Intel MKL The module FindBLAS now correctly chooses MKL BLAS libraries to search, based on the compiler ID. The MKL libraries needed for BLAS functionality are the following: libmkl_{gf|intel}_{lp64|ilp64}.{a|so} libmkl_{gnu|intel}_thread.{a|so} (or libmkl_sequential.{a|so}) libmkl_core.{a|so} libm libdl lib{gomp|iomp5}.{a|so} (only with libmkl_*_thread.*) To achieve the goal, the following internal variables are defined and used: BLAS_mkl_INTFACE = "gf" or "intel" (based on compiler ID) BLAS_mkl_THREADING = "gnu" or "intel" (based on compiler ID) BLAS_mkl_OMP = "gomp" or "iomp5" (based on compiler ID) BLAS_mkl_LM = "-lm" (not set on Windows) BLAS_mkl_DL = "-ldl" (not set on Windows) The default values for the first three of them are "intel" and "iomp5", unless a Fortran compiler is loaded with CMAKE_Fortran_COMPILER_ID equal to "GNU"; in such case the "gf", "gnu" and "gomp" values are used. In non-Windows systems, the thread library as well as libm and libdl are now added to the linker line to allow static linking of libgomp. diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 369bf06..d113579 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -126,6 +126,8 @@ macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) endif () endif () + list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + foreach(_library ${_list}) set(_combined_name ${_combined_name}_${_library}) @@ -170,6 +172,8 @@ macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) if(_libraries_work) if("${_list}" STREQUAL "") set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + else() + set(${LIBRARIES} ${${LIBRARIES}} ${_thread}) # for static link endif() else() set(${LIBRARIES} FALSE) @@ -205,21 +209,34 @@ endif () #BLAS in intel mkl 10+ library? (em64t 64bit) if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT BLAS_LIBRARIES) + + # System-specific settings if (WIN32) if (BLA_STATIC) set(BLAS_mkl_DLL_SUFFIX "") else() set(BLAS_mkl_DLL_SUFFIX "_dll") endif() + else() + if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + set(BLAS_mkl_INTFACE "gf") + set(BLAS_mkl_THREADING "gnu") + set(BLAS_mkl_OMP "gomp") + else() + set(BLAS_mkl_INTFACE "intel") + set(BLAS_mkl_THREADING "intel") + set(BLAS_mkl_OMP "iomp5") + endif() + set(BLAS_mkl_LM "-lm") + set(BLAS_mkl_LDL "-ldl") endif() + if (BLA_VENDOR MATCHES "_64ilp") set(BLAS_mkl_ILP_MODE "ilp64") else () set(BLAS_mkl_ILP_MODE "lp64") endif () - if (NOT WIN32) - set(LM "-lm") - endif () + if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) find_package(Threads) @@ -269,25 +286,20 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") else () if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide") + "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95 mkl_intel_${BLAS_mkl_ILP_MODE} mkl_intel_thread mkl_core guide") + "mkl_blas95 mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") # mkl >= 10.3 - if (CMAKE_C_COMPILER MATCHES ".+gcc") - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_intel_${BLAS_mkl_ILP_MODE} mkl_gnu_thread mkl_core gomp") - else () - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_intel_${BLAS_mkl_ILP_MODE} mkl_intel_thread mkl_core iomp5") - endif () + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_intel_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") + "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") endif () endif () else () @@ -330,26 +342,21 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") else () if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_intel mkl_intel_thread mkl_core guide") + "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_${BLAS_mkl_ILP_MODE} mkl_intel_thread mkl_core guide") + "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide") # mkl >= 10.3 - if (CMAKE_C_COMPILER MATCHES ".+gcc") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_${BLAS_mkl_ILP_MODE} mkl_gnu_thread mkl_core gomp") - else () - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_${BLAS_mkl_ILP_MODE} mkl_intel_thread mkl_core iomp5") - endif () + list(APPEND BLAS_SEARCH_LIBS + "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") endif () if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") + "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") endif () #older vesions of intel mkl libs @@ -373,13 +380,19 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") ${BLAS_mkl_SEARCH_SYMBOL} "" "${SEARCH_LIBS}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" + "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" ) endif () endforeach () endif () unset(BLAS_mkl_ILP_MODE) + unset(BLAS_mkl_INTFACE) + unset(BLAS_mkl_THREADING) + unset(BLAS_mkl_OMP) + unset(BLAS_mkl_DLL_SUFFIX) + unset(BLAS_mkl_LM) + unset(BLAS_mkl_LDL) endif () endif () https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f0d52f55f155ac3f3e2bafa072a4e0d7f1431d76 commit f0d52f55f155ac3f3e2bafa072a4e0d7f1431d76 Author: Jakub Benda AuthorDate: Sun Nov 18 14:52:13 2018 +0000 Commit: Jakub Benda CommitDate: Sun Nov 18 14:52:13 2018 +0000 FindBLAS: Consolidate duplicated code related to MKL on Windows The code that decides which library suffix to use for MKL libraries in Windows was in two places. This commit consolidates it in one place. diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index d150826..369bf06 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -205,6 +205,13 @@ endif () #BLAS in intel mkl 10+ library? (em64t 64bit) if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if (NOT BLAS_LIBRARIES) + if (WIN32) + if (BLA_STATIC) + set(BLAS_mkl_DLL_SUFFIX "") + else() + set(BLAS_mkl_DLL_SUFFIX "_dll") + endif() + endif() if (BLA_VENDOR MATCHES "_64ilp") set(BLAS_mkl_ILP_MODE "ilp64") else () @@ -226,12 +233,6 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") set(BLAS_mkl_SEARCH_SYMBOL sgemm_f95) set(_LIBRARIES BLAS95_LIBRARIES) if (WIN32) - if (BLA_STATIC) - set(BLAS_mkl_DLL_SUFFIX "") - else() - set(BLAS_mkl_DLL_SUFFIX "_dll") - endif() - # Find the main file (32-bit or 64-bit) set(BLAS_SEARCH_LIBS_WIN_MAIN "") if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") @@ -293,12 +294,6 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") set(BLAS_mkl_SEARCH_SYMBOL sgemm) set(_LIBRARIES BLAS_LIBRARIES) if (WIN32) - if (BLA_STATIC) - set(BLAS_mkl_DLL_SUFFIX "") - else() - set(BLAS_mkl_DLL_SUFFIX "_dll") - endif() - # Find the main file (32-bit or 64-bit) set(BLAS_SEARCH_LIBS_WIN_MAIN "") if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") ----------------------------------------------------------------------- Summary of changes: Help/command/ctest_build.rst | 4 +- Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst | 36 +++-- Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst | 25 ++-- Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst | 8 ++ Modules/CTest.cmake | 1 - Modules/FindBLAS.cmake | 107 ++++++++------ Modules/FindBoost.cmake | 9 +- Modules/FindDoxygen.cmake | 19 ++- Modules/FindLAPACK.cmake | 156 +++++++++++---------- Source/CTest/cmCTestBuildCommand.cxx | 16 +-- Source/CTest/cmCTestSubmitCommand.cxx | 4 - Source/CTest/cmCTestSubmitHandler.cxx | 15 +- Source/cmCTest.cxx | 10 -- Source/cmGlobalVisualStudio14Generator.cxx | 38 ++--- .../CTestBuildCommandProjectInSubdir.cmake.in | 1 - Tests/CTestConfig/script.cmake.in | 1 - Tests/CTestCoverageCollectGCOV/test.cmake.in | 1 - Tests/CTestTestBadExe/CTestConfig.cmake | 1 - Tests/CTestTestBadGenerator/CTestConfig.cmake | 1 - Tests/CTestTestCostSerial/CTestConfig.cmake | 1 - Tests/CTestTestCrash/CTestConfig.cmake | 1 - Tests/CTestTestCycle/CTestConfig.cmake | 1 - Tests/CTestTestDepends/CTestConfig.cmake | 1 - Tests/CTestTestFailure/CTestConfig.cmake | 1 - Tests/CTestTestFdSetSize/CTestConfig.cmake | 1 - .../CTestConfig.cmake | 1 - .../CTestConfig.cmake | 1 - .../launcher_linker_test_project/CTestConfig.cmake | 1 - Tests/CTestTestParallel/CTestConfig.cmake | 1 - Tests/CTestTestResourceLock/CTestConfig.cmake | 1 - Tests/CTestTestScheduler/CTestConfig.cmake | 1 - Tests/CTestTestSkipReturnCode/CTestConfig.cmake | 1 - Tests/CTestTestStopTime/CTestConfig.cmake | 1 - Tests/CTestTestSubdir/CTestConfig.cmake | 1 - Tests/CTestTestTimeout/CTestConfig.cmake | 1 - Tests/CTestTestUpload/CTestConfig.cmake | 1 - Tests/CTestTestVerboseOutput/CTestConfig.cmake | 1 - Tests/CTestTestZeroTimeout/CTestConfig.cmake | 1 - Tests/CTestUpdateCommon.cmake | 1 - .../CTestTimeoutAfterMatch/CTestConfig.cmake.in | 1 - .../NoCXX-stderr.txt} | 0 Tests/RunCMake/FindBoost/NoCXX.cmake | 1 + Tests/RunCMake/FindBoost/RunCMakeTest.cmake | 1 + Tests/RunCMake/RunCTest.cmake | 8 +- .../RunCMake/WorkingDirectory/CTestConfig.cmake.in | 1 - Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt | 1 - Tests/RunCMake/ctest_build/CTestConfig.cmake.in | 1 - .../ctest_cmake_error/CTestConfig.cmake.in | 1 - .../RunCMake/ctest_configure/CTestConfig.cmake.in | 1 - .../ctest_configure/ConfigureQuiet-stdout.txt | 1 - Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in | 1 - .../ctest_disabled_test/CTestConfig.cmake.in | 1 - Tests/RunCMake/ctest_fixtures/CTestConfig.cmake.in | 1 - .../CTestConfig.cmake.in | 1 - Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in | 1 - .../ctest_skipped_test/CTestConfig.cmake.in | 1 - .../ctest_start/AppendDifferentModel-stdout.txt | 1 - .../ctest_start/AppendDifferentTrack-stdout.txt | 1 - .../ctest_start/AppendNoMatchingTrack-stdout.txt | 1 - .../RunCMake/ctest_start/AppendNoModel-stdout.txt | 1 - .../ctest_start/AppendOldContinuous-stdout.txt | 1 - .../ctest_start/AppendOldNoModel-stdout.txt | 1 - .../ctest_start/AppendSameModel-stdout.txt | 1 - Tests/RunCMake/ctest_start/CTestConfig.cmake.in | 1 - .../RunCMake/ctest_start/ConfigInBuild-stdout.txt | 1 - .../RunCMake/ctest_start/ConfigInSource-stdout.txt | 1 - .../ctest_start/NoAppendDifferentTrack-stdout.txt | 1 - Tests/RunCMake/ctest_start/RunCMakeTest.cmake | 2 - Tests/RunCMake/ctest_submit/CTestConfig.cmake.in | 1 - Tests/RunCMake/ctest_test/CTestConfig.cmake.in | 1 - Tests/RunCMake/ctest_upload/CTestConfig.cmake.in | 1 - Tests/Tutorial/Step7/CTestConfig.cmake | 1 - 72 files changed, 245 insertions(+), 268 deletions(-) delete mode 100644 Tests/CTestTestFdSetSize/CTestConfig.cmake delete mode 100644 Tests/RunCMake/CTestTimeoutAfterMatch/CTestConfig.cmake.in copy Tests/RunCMake/{target_link_options/LINK_OPTIONS-shared-result.txt => FindBoost/NoCXX-stderr.txt} (100%) create mode 100644 Tests/RunCMake/FindBoost/NoCXX.cmake delete mode 100644 Tests/RunCMake/WorkingDirectory/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_build/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_cmake_error/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_configure/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_disabled_test/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_fixtures/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_skipped_test/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_start/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_test/CTestConfig.cmake.in delete mode 100644 Tests/RunCMake/ctest_upload/CTestConfig.cmake.in delete mode 100644 Tests/Tutorial/Step7/CTestConfig.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Tue Nov 27 08:53:06 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Tue, 27 Nov 2018 08:53:06 -0500 (EST) Subject: [Cmake-commits] CMake branch, release, updated. v3.13.0-6-g2cf836f Message-ID: <20181127135306.0B2F412785B@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, release has been updated via 2cf836fa5ee71417145ec93e8f962d08c4a7d565 (commit) via f54d28a838ca7d4efbbd0155c4f61c287ae2b9cb (commit) via 1f531e0428d0aa5804fd8f4d1b58fe69edc30eed (commit) via 0369362132b3deae30828299131647cc3754abeb (commit) from 8068850fcc1575210c968365e71cb7ece6771022 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Modules/FindBoost.cmake | 9 ++--- Source/cmGlobalVisualStudio14Generator.cxx | 38 ++++++++++++---------- .../NoCXX-stderr.txt} | 0 Tests/RunCMake/FindBoost/NoCXX.cmake | 1 + Tests/RunCMake/FindBoost/RunCMakeTest.cmake | 1 + 5 files changed, 26 insertions(+), 23 deletions(-) copy Tests/RunCMake/{target_link_options/LINK_OPTIONS-shared-result.txt => FindBoost/NoCXX-stderr.txt} (100%) create mode 100644 Tests/RunCMake/FindBoost/NoCXX.cmake hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 28 00:03:04 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 28 Nov 2018 00:03:04 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-547-g049ca05 Message-ID: <20181128050304.72619127A53@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via 049ca05da93ef7f6fced82a88069a382c6008ebf (commit) from f49efe283ed005aac642f5af58ea971d468de88c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=049ca05da93ef7f6fced82a88069a382c6008ebf commit 049ca05da93ef7f6fced82a88069a382c6008ebf Author: Kitware Robot AuthorDate: Wed Nov 28 00:01:05 2018 -0500 Commit: Kitware Robot CommitDate: Wed Nov 28 00:01:05 2018 -0500 CMake Nightly Date Stamp diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 63a1573..93aad21 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 13) -set(CMake_VERSION_PATCH 20181127) +set(CMake_VERSION_PATCH 20181128) #set(CMake_VERSION_RC 1) ----------------------------------------------------------------------- Summary of changes: Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- CMake From kwrobot at kitware.com Wed Nov 28 04:33:05 2018 From: kwrobot at kitware.com (Kitware Robot) Date: Wed, 28 Nov 2018 04:33:05 -0500 (EST) Subject: [Cmake-commits] CMake branch, master, updated. v3.13.0-551-gfaf4496 Message-ID: <20181128093305.78D05127A28@public.kitware.com> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake". The branch, master has been updated via faf4496db372847f34046acfd0d57dda7812eafa (commit) via e15cac8ee748022d31e734f3ab9529bf6c36ac25 (commit) via 8b3a537c29974da62f4a46f4631bbec1550a2a23 (commit) via f9c3f7b16479f84cde3b0249f83e53a32960dff3 (commit) from 049ca05da93ef7f6fced82a88069a382c6008ebf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=faf4496db372847f34046acfd0d57dda7812eafa commit faf4496db372847f34046acfd0d57dda7812eafa Merge: 049ca05 e15cac8 Author: Craig Scott AuthorDate: Wed Nov 28 09:26:22 2018 +0000 Commit: Kitware Robot CommitDate: Wed Nov 28 04:26:33 2018 -0500 Merge topic 'doc-cmake.1' e15cac8ee7 Help: Extend the cmake(1) manual 8b3a537c29 Help: Improve cmake(1) manual organization f9c3f7b164 Help: Emphasize tool names in their manuals Acked-by: Kitware Robot Merge-request: !2662 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e15cac8ee748022d31e734f3ab9529bf6c36ac25 commit e15cac8ee748022d31e734f3ab9529bf6c36ac25 Author: Brad King AuthorDate: Mon Nov 26 10:26:19 2018 -0500 Commit: Craig Scott CommitDate: Tue Nov 27 21:13:32 2018 +1100 Help: Extend the cmake(1) manual Extend the description section to cover all capabilities that the "cmake" tool has. Extend the buildsystem generation section to introduce important concepts and describe the basic workflow. Inspired-by: Joachim Wuttke (l) diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst index 0287767..1de10c4 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -27,6 +27,8 @@ when creating a new build tree. CMake Generators ================ +.. _`Command-Line Build Tool Generators`: + Command-Line Build Tool Generators ---------------------------------- @@ -58,6 +60,8 @@ Ninja Generator /generator/Ninja +.. _`IDE Build Tool Generators`: + IDE Build Tool Generators ------------------------- diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index c7f3537..915e0d4 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -9,7 +9,8 @@ Synopsis .. parsed-literal:: `Generate a Project Buildsystem`_ - cmake [] { | } + cmake [] + cmake [] cmake [] -S -B `Build a Project`_ @@ -33,37 +34,131 @@ Synopsis Description =========== -The **cmake** executable is the CMake command-line interface. It may be -used to configure projects in scripts. Project configuration settings -may be specified on the command line with the -D option. - -CMake is a cross-platform build system generator. Projects specify -their build process with platform-independent CMake listfiles included -in each directory of a source tree with the name CMakeLists.txt. -Users build a project by using CMake to generate a build system for a -native tool on their platform. +The **cmake** executable is the command-line interface of the cross-platform +buildsystem generator CMake. The above `Synopsis`_ lists various actions +the tool can perform as described in sections below. + +To build a software project with CMake, `Generate a Project Buildsystem`_. +Optionally use **cmake** to `Build a Project`_ or just run the +corresponding build tool (e.g. ``make``) directly. **cmake** can also +be used to `View Help`_. + +The other actions are meant for use by software developers writing +scripts in the :manual:`CMake language ` to support +their builds. + +For graphical user interfaces that may be used in place of **cmake**, +see :manual:`ccmake ` and :manual:`cmake-gui `. +For command-line interfaces to the CMake testing and packaging facilities, +see :manual:`ctest ` and :manual:`cpack `. + +For more information on CMake at large, `see also`_ the links at the end +of this manual. + + +Introduction to CMake Buildsystems +================================== + +A *buildsystem* describes how to build a project's executables and libraries +from its source code using a *build tool* to automate the process. For +example, a buildsystem may be a ``Makefile`` for use with a command-line +``make`` tool or a project file for an Integrated Development Environment +(IDE). In order to avoid maintaining multiple such buildsystems, a project +may specify its buildsystem abstractly using files written in the +:manual:`CMake language `. From these files CMake +generates a preferred buildsystem locally for each user through a backend +called a *generator*. + +To generate a buildsystem with CMake, the following must be selected: + +Source Tree + The top-level directory containing source files provided by the project. + The project specifies its buildsystem using files as described in the + :manual:`cmake-language(7)` manual, starting with a top-level file named + ``CMakeLists.txt``. These files specify build targets and their + dependencies as described in the :manual:`cmake-buildsystem(7)` manual. + +Build Tree + The top-level directory in which buildsystem files and build output + artifacts (e.g. executables and libraries) are to be stored. + CMake will write a ``CMakeCache.txt`` file to identify the directory + as a build tree and store persistent information such as buildsystem + configuration options. + + To maintain a pristine source tree, perform an *out-of-source* build + by using a separate dedicated build tree. An *in-source* build in + which the build tree is placed in the same directory as the source + tree is also supported, but discouraged. + +Generator + This chooses the kind of buildsystem to generate. See the + :manual:`cmake-generators(7)` manual for documentation of all generators. + Run ``cmake --help`` to see a list of generators available locally. + Optionally use the ``-G`` option below to specify a generator, or simply + accept the default CMake chooses for the current platform. + + When using one of the :ref:`Command-Line Build Tool Generators` + CMake expects that the environment needed by the compiler toolchain + is already configured in the shell. When using one of the + :ref:`IDE Build Tool Generators`, no particular environment is needed. Generate a Project Buildsystem ============================== -.. code-block:: shell +Run CMake with one of the following command signatures to specify the +source and build trees and generate a buildsystem: - cmake [] { | } - cmake [] -S -B +``cmake [] `` + Uses the current working directory as the build tree, and + ```` as the source tree. The specified path may + be absolute or relative to the current working directory. + The source tree must contain a ``CMakeLists.txt`` file and must + *not* contain a ``CMakeCache.txt`` file because the latter + identifies an existing build tree. For example: + + .. code-block:: console + + $ mkdir build ; cd build + $ cmake ../src + +``cmake [] `` + Uses ```` as the build tree, and loads the + path to the source tree from its ``CMakeCache.txt`` file, which must + have already been generated by a previous run of CMake. The specified + path may be absolute or relative to the current working directory. + For example: + + .. code-block:: console -The parameter ```` must be the relative or absolute path -of the source directory that contains the top-level ``CMakeLists.txt`` file. -Alternatively, if the named directory contains ``CMakeCache.txt`` it will -be treated as ```` and the path to the source will -be loaded from the cache. + $ cd build + $ cmake . -By default, **cmake** writes the generated Makefiles and all other output -to the directory from where it was invoked. This behavior can be changed -by the variant with the parameter ````. +``cmake [] -S -B `` + Uses ```` as the build tree and ```` + as the source tree. The specified paths may be absolute or relative + to the current working directory. The source tree must contain a + ``CMakeLists.txt`` file. The build tree will be created automatically + if it does not already exist. For example: + + .. code-block:: console + + $ cmake -S src -B build In all cases the ```` may be zero or more of the `Options`_ below. +After generating a buildsystem one may use the corresponding native +build tool to build the project. For example, after using the +:generator:`Unix Makefiles` generator one may run ``make`` directly: + + .. code-block:: console + + $ make + $ make install + +Alternatively, one may use **cmake** to `Build a Project`_ by +automatically choosing and invoking the appropriate native build tool. + .. _`CMake Options`: Options https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8b3a537c29974da62f4a46f4631bbec1550a2a23 commit 8b3a537c29974da62f4a46f4631bbec1550a2a23 Author: Joachim Wuttke (l) AuthorDate: Thu Nov 15 10:49:42 2018 +0100 Commit: Craig Scott CommitDate: Tue Nov 27 21:13:32 2018 +1100 Help: Improve cmake(1) manual organization Extend the Synposis, and provide links to manual sections. Add sections for `cmake --open` and `cmake --help-*`. Introduce a new section for buildsystem generation to distinguish it from the other functionality. Populate it with minimal placeholder text for now. It will be extended later. Co-Author: Brad King diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index d8b71a9..c7f3537 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -8,13 +8,27 @@ Synopsis .. parsed-literal:: - cmake [] { | } - cmake [] -S -B - cmake [{-D =}...] -P - cmake --build [...] [-- ...] - cmake --open - cmake -E [...] - cmake --find-package ... + `Generate a Project Buildsystem`_ + cmake [] { | } + cmake [] -S -B + + `Build a Project`_ + cmake --build [] [-- ] + + `Open a Project`_ + cmake --open + + `Run a Script`_ + cmake [{-D =}...] -P + + `Run a Command-Line Tool`_ + cmake -E [] + + `Run the Find-Package Tool`_ + cmake --find-package [] + + `View Help`_ + cmake --help[-] Description =========== @@ -29,16 +43,34 @@ in each directory of a source tree with the name CMakeLists.txt. Users build a project by using CMake to generate a build system for a native tool on their platform. + +Generate a Project Buildsystem +============================== + +.. code-block:: shell + + cmake [] { | } + cmake [] -S -B + +The parameter ```` must be the relative or absolute path +of the source directory that contains the top-level ``CMakeLists.txt`` file. +Alternatively, if the named directory contains ``CMakeCache.txt`` it will +be treated as ```` and the path to the source will +be loaded from the cache. + +By default, **cmake** writes the generated Makefiles and all other output +to the directory from where it was invoked. This behavior can be changed +by the variant with the parameter ````. + +In all cases the ```` may be zero or more of the `Options`_ below. + .. _`CMake Options`: Options -======= +------- .. include:: OPTIONS_BUILD.txt -``-E [...]`` - See `Command-Line Tool Mode`_. - ``-L[A][H]`` List non-advanced cached variables. @@ -50,30 +82,12 @@ Options display also advanced variables. If H is specified, it will also display help for each variable. -``--build `` - See `Build Tool Mode`_. - -``--open `` - Open the generated project in the associated application. This is - only supported by some generators. - ``-N`` View mode only. Only load the cache. Do not actually run configure and generate steps. -``-P `` - Process script mode. - - Process the given cmake file as a script written in the CMake - language. No configure or generate step is performed and the cache - is not modified. If variables are defined using -D, this must be - done before the -P argument. - -``--find-package`` - See `Find-Package Tool Mode`_. - ``--graphviz=[file]`` Generate graphviz of dependencies, see :module:`CMakeGraphVizOptions` for more. @@ -142,17 +156,17 @@ Options in CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. This flag tells CMake to warn about other files as well. -.. include:: OPTIONS_HELP.txt - .. _`Build Tool Mode`: -Build Tool Mode +Build a Project =============== CMake provides a command-line signature to build an already-generated -project binary tree:: +project binary tree: + +.. code-block:: shell - cmake --build [...] [-- ...] + cmake --build [] [-- ] This abstracts a native build tool's command-line interface with the following options: @@ -185,12 +199,41 @@ following options: Run ``cmake --build`` with no options for quick help. -Command-Line Tool Mode -====================== -CMake provides builtin command-line tools through the signature:: +Open a Project +============== - cmake -E [...] +.. code-block:: shell + + cmake --open + +Open the generated project in the associated application. This is only +supported by some generators. + + +.. _`Script Processing Mode`: + +Run a Script +============ + +.. code-block:: shell + + cmake [{-D =}...] -P + +Process the given cmake file as a script written in the CMake +language. No configure or generate step is performed and the cache +is not modified. If variables are defined using -D, this must be +done before the -P argument. + + +Run a Command-Line Tool +======================= + +CMake provides builtin command-line tools through the signature + +.. code-block:: shell + + cmake -E [] Run ``cmake -E`` or ``cmake -E help`` for a summary of commands. Available commands are: @@ -326,7 +369,7 @@ Available commands are: ``sleep ...`` Sleep for given number of seconds. -``tar [cxt][vf][zjJ] file.tar [...] [--] [...]`` +``tar [cxt][vf][zjJ] file.tar [] [--] [...]`` Create or extract a tar or zip archive. Options are: ``--`` @@ -379,24 +422,40 @@ The following ``cmake -E`` commands are available only on Windows: ``write_regv `` Write Windows registry value. -Find-Package Tool Mode -====================== -CMake provides a helper for Makefile-based projects with the signature:: +Run the Find-Package Tool +========================= + +CMake provides a pkg-config like helper for Makefile-based projects: - cmake --find-package ... +.. code-block:: shell -This runs in a pkg-config like mode. + cmake --find-package [] -Search a package using :command:`find_package()` and print the resulting flags -to stdout. This can be used to use cmake instead of pkg-config to find -installed libraries in plain Makefile-based projects or in autoconf-based -projects (via ``share/aclocal/cmake.m4``). +It searches a package using :command:`find_package()` and prints the +resulting flags to stdout. This can be used instead of pkg-config +to find installed libraries in plain Makefile-based projects or in +autoconf-based projects (via ``share/aclocal/cmake.m4``). .. note:: This mode is not well-supported due to some technical limitations. It is kept for compatibility but should not be used in new projects. + +View Help +========= + +To print selected pages from the CMake documentation, use + +.. code-block:: shell + + cmake --help[-] + +with one of the following options: + +.. include:: OPTIONS_HELP.txt + + See Also ======== diff --git a/Help/variable/CMAKE_ARGC.rst b/Help/variable/CMAKE_ARGC.rst index aec9711..30db2a2 100644 --- a/Help/variable/CMAKE_ARGC.rst +++ b/Help/variable/CMAKE_ARGC.rst @@ -3,6 +3,6 @@ CMAKE_ARGC Number of command line arguments passed to CMake in script mode. -When run in :ref:`-P ` script mode, CMake sets this variable to -the number of command line arguments. See also :variable:`CMAKE_ARGV0`, -``1``, ``2`` ... +When run in :ref:`-P