diff options
34 files changed, 414 insertions, 430 deletions
diff --git a/Help/policy/CMP0091.rst b/Help/policy/CMP0091.rst index 5b7c4e3..1a5878a 100644 --- a/Help/policy/CMP0091.rst +++ b/Help/policy/CMP0091.rst @@ -20,7 +20,9 @@ CMake 3.15 and above prefer to leave the MSVC runtime library selection flags out of the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values and instead offer a first-class abstraction. The :variable:`CMAKE_MSVC_RUNTIME_LIBRARY` variable and :prop_tgt:`MSVC_RUNTIME_LIBRARY` target property may be set to -select the MSVC runtime library. +select the MSVC runtime library. If they are not set then CMake uses the +default value ``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` which is +equivalent to the original flags. This policy provides compatibility with projects that have not been updated to be aware of the abstraction. The policy setting takes effect as of the diff --git a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst index 1e3f5e9..73792de 100644 --- a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst +++ b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst @@ -19,6 +19,9 @@ support per-configuration specification. For example, the code: selects for the target ``foo`` a multi-threaded statically-linked runtime library with or without debug information depending on the configuration. +If this property is not set then CMake uses the default value +``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` to select a MSVC runtime library. + .. note:: This property has effect only when policy :policy:`CMP0091` is set to ``NEW`` diff --git a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst index 6ed68c9..8b54e7e 100644 --- a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst +++ b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst @@ -20,6 +20,11 @@ support per-configuration specification. For example, the code: selects for all following targets a multi-threaded statically-linked runtime library with or without debug information depending on the configuration. +If this variable is not set then the :prop_tgt:`MSVC_RUNTIME_LIBRARY` target +property will not be set automatically. If that property is not set then +CMake uses the default value ``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` +to select a MSVC runtime library. + .. note:: This variable has effect only when policy :policy:`CMP0091` is set to ``NEW`` diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index f6510b9..58b0813 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake @@ -23,7 +23,13 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows AND NOT CMAKE_SYSTEM_NAME STREQUAL Dar endif() set(CMAKE_Swift_COMPILE_OPTIONS_TARGET "-target ") -set(CMAKE_Swift_COMPILER_ARG1 -frontend) +set(CMAKE_Swift_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "-tools-directory ") +# NOTE(compnerd) the `-sdk` support is not yet ready in the compiler; when that +# is fully working, we should be able to enable this. +# set(CMAKE_Swift_COMPILE_OPTIONS_SYSROOT "-sdk ") +# NOTE(compnerd) do not setup `-frontend` as we use the compiler as the driver +# during the link phase and use that to drive the compilation +set(CMAKE_Swift_COMPILER_ARG1 "") set(CMAKE_Swift_DEFINE_FLAG -D) set(CMAKE_Swift_FRAMEWORK_SEARCH_FLAG "-F ") set(CMAKE_Swift_LIBRARY_PATH_FLAG "-L ") @@ -57,11 +63,7 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$") endif() if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY) - if(CMAKE_Swift_COMPILER_TARGET) - set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_SONAME> <LINK_LIBRARIES>") - else() - set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_SONAME> <LINK_LIBRARIES>") - endif() + set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_SONAME> <LINK_LIBRARIES>") endif() if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) @@ -69,19 +71,11 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) endif() if(NOT CMAKE_Swift_LINK_EXECUTABLE) - if(CMAKE_Swift_COMPILER_TARGET) - set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") - else() - set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") - endif() + set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") endif() if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY) - if(CMAKE_Swift_COMPILER_TARGET) - set(CMAKE_Swift_CREATE_STATIC_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") - else() - set(CMAKE_Swift_CREATE_STATIC_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") - endif() + set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>") set(CMAKE_Swift_ARCHIVE_FINISH "") diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 670352c..2d45965 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -526,6 +526,11 @@ if(Protobuf_INCLUDE_DIR) INTERFACE_COMPILE_FEATURES cxx_std_11 ) endif() + if (MSVC AND NOT Protobuf_USE_STATIC_LIBS) + set_property(TARGET protobuf::libprotobuf APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS" + ) + endif() if(UNIX AND TARGET Threads::Threads) set_property(TARGET protobuf::libprotobuf APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads) @@ -554,6 +559,11 @@ if(Protobuf_INCLUDE_DIR) set_target_properties(protobuf::libprotobuf-lite PROPERTIES IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}") endif() + if (MSVC AND NOT Protobuf_USE_STATIC_LIBS) + set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS" + ) + endif() if(UNIX AND TARGET Threads::Threads) set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads) @@ -587,6 +597,11 @@ if(Protobuf_INCLUDE_DIR) INTERFACE_COMPILE_FEATURES cxx_std_11 ) endif() + if (MSVC AND NOT Protobuf_USE_STATIC_LIBS) + set_property(TARGET protobuf::libprotoc APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS" + ) + endif() if(UNIX AND TARGET Threads::Threads) set_property(TARGET protobuf::libprotoc APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads) diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake index ae8d72d..55da55f 100644 --- a/Modules/FindVulkan.cmake +++ b/Modules/FindVulkan.cmake @@ -5,7 +5,7 @@ FindVulkan ---------- -Find Vulkan, which isis a low-overhead, cross-platform 3D graphics +Find Vulkan, which is a low-overhead, cross-platform 3D graphics and computing API. IMPORTED Targets diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a9ce61a..cf21839 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 15) -set(CMake_VERSION_PATCH 20190718) +set(CMake_VERSION_PATCH 20190719) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 861bd06..85040dd 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -4,13 +4,6 @@ #include "cmsys/Directory.hxx" #include "cmsys/Process.h" -#include <map> -#include <ratio> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <utility> #include "cm_memory.hxx" @@ -41,6 +34,15 @@ #include "cmSystemTools.h" #include "cmake.h" +#include <map> +#include <memory> +#include <ratio> +#include <sstream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> + #ifdef _WIN32 # include <windows.h> #else @@ -372,9 +374,11 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) #endif // always add a function blocker to update the elapsed time - cmCTestScriptFunctionBlocker* f = new cmCTestScriptFunctionBlocker(); - f->CTestScriptHandler = this; - this->Makefile->AddFunctionBlocker(f); + { + auto fb = cm::make_unique<cmCTestScriptFunctionBlocker>(); + fb->CTestScriptHandler = this; + this->Makefile->AddFunctionBlocker(std::move(fb)); + } /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and CMakeSystemSpecificInformation, so diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 1fa7988..54c4bae 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -266,15 +266,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( } } - upload_as += "&MD5="; - - if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) { - upload_as += "bad_md5sum"; - } else { - upload_as += - cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5); - } - // Generate Done.xml right before it is submitted. // The reason for this is two-fold: // 1) It must be generated after some other part has been submitted @@ -286,6 +277,15 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( this->CTest->GenerateDoneFile(); } + upload_as += "&MD5="; + + if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) { + upload_as += "bad_md5sum"; + } else { + upload_as += + cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5); + } + if (!cmSystemTools::FileExists(local_file)) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: " << local_file << std::endl); diff --git a/Source/cmCommand.h b/Source/cmCommand.h index cdd2aba..b210f27 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -61,19 +61,6 @@ public: cmExecutionStatus&) = 0; /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - virtual void FinalPass() {} - - /** - * Does this command have a final pass? Query after InitialPass. - */ - virtual bool HasFinalPass() const { return false; } - - /** * This is a virtual constructor for the command. */ virtual std::unique_ptr<cmCommand> Clone() = 0; diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h index eed59ca..e07f255 100644 --- a/Source/cmDisallowedCommand.h +++ b/Source/cmDisallowedCommand.h @@ -38,10 +38,6 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - void FinalPass() override { this->Command->FinalPass(); } - - bool HasFinalPass() const override { return this->Command->HasFinalPass(); } - private: std::unique_ptr<cmCommand> Command; cmPolicies::PolicyID Policy; diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 51eb814..096016d 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -4,6 +4,7 @@ #include "cmAlgorithms.h" #include "cm_kwiml.h" +#include "cm_memory.hxx" #include "cmsys/FStream.hxx" #include <map> #include <memory> @@ -109,10 +110,10 @@ public: }; // Construct and take ownership of the file stream object. - cmELFInternal(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, + cmELFInternal(cmELF* external, std::unique_ptr<std::istream> fin, ByteOrderType order) : External(external) - , Stream(*fin.release()) + , Stream(std::move(fin)) , ByteOrder(order) , ELFType(cmELF::FileTypeInvalid) { @@ -132,7 +133,7 @@ public: } // Destruct and delete the file stream object. - virtual ~cmELFInternal() { delete &this->Stream; } + virtual ~cmELFInternal() = default; // Forward to the per-class implementation. virtual unsigned int GetNumberOfSections() const = 0; @@ -171,7 +172,7 @@ protected: cmELF* External; // The stream from which to read. - std::istream& Stream; + std::unique_ptr<std::istream> Stream; // The byte order of the ELF file. ByteOrderType ByteOrder; @@ -233,7 +234,7 @@ public: typedef typename Types::tagtype tagtype; // Construct with a stream and byte swap indicator. - cmELFInternalImpl(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, + cmELFInternalImpl(cmELF* external, std::unique_ptr<std::istream> fin, ByteOrderType order); // Return the number of sections as specified by the ELF header. @@ -352,7 +353,7 @@ private: bool Read(ELF_Ehdr& x) { // Read the header from the file. - if (!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) { + if (!this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))) { return false; } @@ -382,26 +383,26 @@ private: } bool Read(ELF_Shdr& x) { - if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { ByteSwap(x); } - return !this->Stream.fail(); + return !this->Stream->fail(); } bool Read(ELF_Dyn& x) { - if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { ByteSwap(x); } - return !this->Stream.fail(); + return !this->Stream->fail(); } bool LoadSectionHeader(ELF_Half i) { // Read the section header from the file. - this->Stream.seekg(this->ELFHeader.e_shoff + - this->ELFHeader.e_shentsize * i); + this->Stream->seekg(this->ELFHeader.e_shoff + + this->ELFHeader.e_shentsize * i); if (!this->Read(this->SectionHeaders[i])) { return false; } @@ -426,9 +427,10 @@ private: }; template <class Types> -cmELFInternalImpl<Types>::cmELFInternalImpl( - cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, ByteOrderType order) - : cmELFInternal(external, fin, order) +cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external, + std::unique_ptr<std::istream> fin, + ByteOrderType order) + : cmELFInternal(external, std::move(fin), order) { // Read the main header. if (!this->Read(this->ELFHeader)) { @@ -510,7 +512,7 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection() // Read each entry. for (int j = 0; j < n; ++j) { // Seek to the beginning of the section entry. - this->Stream.seekg(sec.sh_offset + sec.sh_entsize * j); + this->Stream->seekg(sec.sh_offset + sec.sh_entsize * j); ELF_Dyn& dyn = this->DynamicSectionEntries[j]; // Try reading the entry. @@ -630,7 +632,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val); unsigned long last = first; unsigned long end = static_cast<unsigned long>(strtab.sh_size); - this->Stream.seekg(strtab.sh_offset + first); + this->Stream->seekg(strtab.sh_offset + first); // Read the string. It may be followed by more than one NULL // terminator. Count the total size of the region allocated to @@ -639,7 +641,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( // assumption. bool terminated = false; char c; - while (last != end && this->Stream.get(c) && !(terminated && c)) { + while (last != end && this->Stream->get(c) && !(terminated && c)) { ++last; if (c) { se.Value += c; @@ -649,7 +651,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( } // Make sure the whole value was read. - if (!this->Stream) { + if (!(*this->Stream)) { this->SetErrorMessage("Dynamic section specifies unreadable RPATH."); se.Value = ""; return nullptr; @@ -679,10 +681,9 @@ const long cmELF::TagMipsRldMapRel = 0; #endif cmELF::cmELF(const char* fname) - : Internal(nullptr) { // Try to open the file. - std::unique_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname)); + auto fin = cm::make_unique<cmsys::ifstream>(fname); // Quit now if the file could not be opened. if (!fin || !*fin) { @@ -725,12 +726,14 @@ cmELF::cmELF(const char* fname) // parser implementation. if (ident[EI_CLASS] == ELFCLASS32) { // 32-bit ELF - this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order); + this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>( + this, std::move(fin), order); } #ifndef _SCO_DS else if (ident[EI_CLASS] == ELFCLASS64) { // 64-bit ELF - this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order); + this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>( + this, std::move(fin), order); } #endif else { @@ -739,10 +742,7 @@ cmELF::cmELF(const char* fname) } } -cmELF::~cmELF() -{ - delete this->Internal; -} +cmELF::~cmELF() = default; bool cmELF::Valid() const { diff --git a/Source/cmELF.h b/Source/cmELF.h index 987f0c3..afef654 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> +#include <memory> #include <string> #include <utility> #include <vector> @@ -108,7 +109,7 @@ public: private: friend class cmELFInternal; bool Valid() const; - cmELFInternal* Internal; + std::unique_ptr<cmELFInternal> Internal; std::string ErrorMessage; }; diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index 87ef2a9..8f2fff5 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -19,57 +19,31 @@ class cmExecutionStatus; -bool cmExportLibraryDependenciesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) -{ - if (args.empty()) { - this->SetError("called with incorrect number of arguments"); - return false; - } - - // store the arguments for the final pass - this->Filename = args[0]; - this->Append = false; - if (args.size() > 1) { - if (args[1] == "APPEND") { - this->Append = true; - } - } - return true; -} - -void cmExportLibraryDependenciesCommand::FinalPass() -{ - // export_library_dependencies() shouldn't modify anything - // ensure this by calling a const method - this->ConstFinalPass(); -} - -void cmExportLibraryDependenciesCommand::ConstFinalPass() const +static void FinalAction(cmMakefile& makefile, std::string const& filename, + bool append) { // Use copy-if-different if not appending. std::unique_ptr<cmsys::ofstream> foutPtr; - if (this->Append) { + if (append) { const auto openmodeApp = std::ios::app; - foutPtr = - cm::make_unique<cmsys::ofstream>(this->Filename.c_str(), openmodeApp); + foutPtr = cm::make_unique<cmsys::ofstream>(filename.c_str(), openmodeApp); } else { std::unique_ptr<cmGeneratedFileStream> ap( - new cmGeneratedFileStream(this->Filename, true)); + new cmGeneratedFileStream(filename, true)); ap->SetCopyIfDifferent(true); foutPtr = std::move(ap); } std::ostream& fout = *foutPtr; if (!fout) { - cmSystemTools::Error("Error Writing " + this->Filename); + cmSystemTools::Error("Error Writing " + filename); cmSystemTools::ReportLastSystemError(""); return; } // Collect dependency information about all library targets built in // the project. - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = makefile.GetCMakeInstance(); cmGlobalGenerator* global = cm->GetGlobalGenerator(); const std::vector<cmMakefile*>& locals = global->GetMakefiles(); std::map<std::string, std::string> libDepsOld; @@ -166,3 +140,20 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const } fout << "endif()\n"; } + +bool cmExportLibraryDependenciesCommand::InitialPass( + std::vector<std::string> const& args, cmExecutionStatus&) +{ + if (args.empty()) { + this->SetError("called with incorrect number of arguments"); + return false; + } + + std::string const& filename = args[0]; + bool const append = args.size() > 1 && args[1] == "APPEND"; + this->Makefile->AddFinalAction([filename, append](cmMakefile& makefile) { + FinalAction(makefile, filename, append); + }); + + return true; +} diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h index 5255d63..4817162 100644 --- a/Source/cmExportLibraryDependenciesCommand.h +++ b/Source/cmExportLibraryDependenciesCommand.h @@ -23,14 +23,6 @@ public: } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - std::string Filename; - bool Append = false; - void ConstFinalPass() const; }; #endif diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 89629c7..70800b4 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -13,6 +13,23 @@ class cmExecutionStatus; class cmTarget; +static void FinalAction(cmMakefile& makefile, std::string const& name) +{ + // people should add the srcs to the target themselves, but the old command + // didn't support that, so check and see if they added the files in and if + // they didn;t then print a warning and add then anyhow + cmTarget* target = makefile.FindLocalNonAliasTarget(name); + if (!target) { + std::string msg = + "FLTK_WRAP_UI was called with a target that was never created: "; + msg += name; + msg += ". The problem was found while processing the source directory: "; + msg += makefile.GetCurrentSourceDirectory(); + msg += ". This FLTK_WRAP_UI call will be ignored."; + cmSystemTools::Message(msg, "Warning"); + } +} + // cmFLTKWrapUICommand bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) @@ -27,8 +44,8 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, std::string const& fluid_exe = this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE"); - // get parameter for the command - this->Target = args[0]; // Target that will use the generated files + // Target that will use the generated files + std::string const& target = args[0]; // get the list of GUI files from which .cxx and .h will be generated std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory(); @@ -41,6 +58,9 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, this->Makefile->AddIncludeDirectories(outputDirectories); } + // List of produced files. + std::vector<cmSourceFile*> generatedSourcesClasses; + for (std::string const& arg : cmMakeRange(args).advance(1)) { cmSourceFile* curr = this->Makefile->GetSource(arg); // if we should use the source GUI @@ -84,40 +104,23 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, cmSourceFile* sf = this->Makefile->GetSource(cxxres); sf->AddDepend(hname); sf->AddDepend(origname); - this->GeneratedSourcesClasses.push_back(sf); + generatedSourcesClasses.push_back(sf); } } // create the variable with the list of sources in it - size_t lastHeadersClass = this->GeneratedSourcesClasses.size(); + size_t lastHeadersClass = generatedSourcesClasses.size(); std::string sourceListValue; for (size_t classNum = 0; classNum < lastHeadersClass; classNum++) { if (classNum) { sourceListValue += ";"; } - sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath(); + sourceListValue += generatedSourcesClasses[classNum]->GetFullPath(); } - std::string varName = this->Target; - varName += "_FLTK_UI_SRCS"; + std::string const varName = target + "_FLTK_UI_SRCS"; this->Makefile->AddDefinition(varName, sourceListValue.c_str()); + this->Makefile->AddFinalAction( + [target](cmMakefile& makefile) { FinalAction(makefile, target); }); return true; } - -void cmFLTKWrapUICommand::FinalPass() -{ - // people should add the srcs to the target themselves, but the old command - // didn't support that, so check and see if they added the files in and if - // they didn;t then print a warning and add then anyhow - cmTarget* target = this->Makefile->FindLocalNonAliasTarget(this->Target); - if (!target) { - std::string msg = - "FLTK_WRAP_UI was called with a target that was never created: "; - msg += this->Target; - msg += ". The problem was found while processing the source directory: "; - msg += this->Makefile->GetCurrentSourceDirectory(); - msg += ". This FLTK_WRAP_UI call will be ignored."; - cmSystemTools::Message(msg, "Warning"); - return; - } -} diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index bff4f01..ea8d401 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -13,7 +13,6 @@ #include "cmCommand.h" class cmExecutionStatus; -class cmSourceFile; /** \class cmFLTKWrapUICommand * \brief Create .h and .cxx files rules for FLTK user interfaces files @@ -38,27 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - /** - * List of produced files. - */ - std::vector<cmSourceFile*> GeneratedSourcesClasses; - - /** - * List of Fluid files that provide the source - * generating .cxx and .h files - */ - std::string Target; }; #endif diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 94c1b1a..a30ebe1 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -5,6 +5,7 @@ #include <sstream> #include <stdio.h> #include <stdlib.h> +#include <utility> #include "cm_memory.hxx" @@ -121,7 +122,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, } // create a function blocker - auto f = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile); if (args.size() > 1) { if (args[1] == "RANGE") { int start = 0; @@ -168,23 +169,22 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, break; } } - f->Args = range; + fb->Args = range; } else { - f->Args = args; + fb->Args = args; } } else { - f->Args = args; + fb->Args = args; } - this->Makefile->AddFunctionBlocker(f.release()); + this->Makefile->AddFunctionBlocker(std::move(fb)); return true; } bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) { - std::unique_ptr<cmForEachFunctionBlocker> f( - new cmForEachFunctionBlocker(this->Makefile)); - f->Args.push_back(args[0]); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile); + fb->Args.push_back(args[0]); enum Doing { @@ -195,7 +195,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) Doing doing = DoingNone; for (unsigned int i = 2; i < args.size(); ++i) { if (doing == DoingItems) { - f->Args.push_back(args[i]); + fb->Args.push_back(args[i]); } else if (args[i] == "LISTS") { doing = DoingLists; } else if (args[i] == "ITEMS") { @@ -203,7 +203,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) } else if (doing == DoingLists) { const char* value = this->Makefile->GetDefinition(args[i]); if (value && *value) { - cmSystemTools::ExpandListArgument(value, f->Args, true); + cmSystemTools::ExpandListArgument(value, fb->Args, true); } } else { std::ostringstream e; @@ -214,7 +214,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) } } - this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass unique_ptr + this->Makefile->AddFunctionBlocker(std::move(fb)); return true; } diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 8e003ad..6d06531 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -179,8 +179,10 @@ bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args, } // create a function blocker - cmFunctionFunctionBlocker* f = new cmFunctionFunctionBlocker(); - cmAppend(f->Args, args); - this->Makefile->AddFunctionBlocker(f); + { + auto fb = cm::make_unique<cmFunctionFunctionBlocker>(); + cmAppend(fb->Args, args); + this->Makefile->AddFunctionBlocker(std::move(fb)); + } return true; } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 69a7da9..7e81a54 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -639,7 +639,9 @@ void cmGlobalNinjaGenerator::EnableLanguage( (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang")))) { + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") || + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "QCC") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "QCC")))) { this->UsingGCCOnWindows = true; } #endif diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index c58ad06..625dd45 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIfCommand.h" +#include "cm_memory.hxx" + #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" #include "cmExpandedCommandArgument.h" @@ -11,6 +13,8 @@ #include "cmSystemTools.h" #include "cmake.h" +#include <utility> + static std::string cmIfCommandError( std::vector<cmExpandedCommandArgument> const& args) { @@ -200,15 +204,17 @@ bool cmIfCommand::InvokeInitialPass( this->Makefile->IssueMessage(status, err); } - cmIfFunctionBlocker* f = new cmIfFunctionBlocker(); - // if is isn't true block the commands - f->ScopeDepth = 1; - f->IsBlocking = !isTrue; - if (isTrue) { - f->HasRun = true; + { + auto fb = cm::make_unique<cmIfFunctionBlocker>(); + // if is isn't true block the commands + fb->ScopeDepth = 1; + fb->IsBlocking = !isTrue; + if (isTrue) { + fb->HasRun = true; + } + fb->Args = args; + this->Makefile->AddFunctionBlocker(std::move(fb)); } - f->Args = args; - this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index efbcb67..4522669 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallFilesCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -13,7 +12,13 @@ class cmExecutionStatus; -// cmExecutableCommand +static std::string FindInstallSource(cmMakefile& makefile, const char* name); +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector<std::string> const& files); +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args); + bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { @@ -25,18 +30,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; + std::string const& dest = args[0]; if ((args.size() > 1) && (args[1] == "FILES")) { - this->IsFilesForm = true; + std::vector<std::string> files; for (std::string const& arg : cmMakeRange(args).advance(2)) { // Find the source location for each file listed. - this->Files.push_back(this->FindInstallSource(arg.c_str())); + files.push_back(FindInstallSource(*this->Makefile, arg.c_str())); } - this->CreateInstallGenerator(); + CreateInstallGenerator(*this->Makefile, dest, files); } else { - this->IsFilesForm = false; - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); + std::vector<std::string> finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); } this->Makefile->GetGlobalGenerator()->AddInstallComponent( @@ -45,23 +52,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, return true; } -void cmInstallFilesCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args) { - // No final pass for "FILES" form of arguments. - if (this->IsFilesForm) { - return; - } - std::string testf; - std::string const& ext = this->FinalArgs[0]; + std::string const& ext = args[0]; + std::vector<std::string> installFiles; // two different options - if (this->FinalArgs.size() > 1) { + if (args.size() > 1) { // now put the files into the list - std::vector<std::string>::iterator s = this->FinalArgs.begin(); + std::vector<std::string>::const_iterator s = args.begin(); ++s; // for each argument, get the files - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // replace any variables std::string const& temps = *s; if (!cmSystemTools::GetFilenamePath(temps).empty()) { @@ -72,30 +76,31 @@ void cmInstallFilesCommand::FinalPass() } // add to the result - this->Files.push_back(this->FindInstallSource(testf.c_str())); + installFiles.push_back(FindInstallSource(makefile, testf.c_str())); } } else // reg exp list { std::vector<std::string> files; - std::string const& regex = this->FinalArgs[0]; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex, - files); + std::string const& regex = args[0]; + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files); std::vector<std::string>::iterator s = files.begin(); // for each argument, get the files for (; s != files.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + installFiles.push_back(FindInstallSource(makefile, s->c_str())); } } - this->CreateInstallGenerator(); + CreateInstallGenerator(makefile, dest, installFiles); } -void cmInstallFilesCommand::CreateInstallGenerator() const +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector<std::string> const& files) { // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -106,12 +111,12 @@ void cmInstallFilesCommand::CreateInstallGenerator() const const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), false, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), false, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -121,7 +126,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallFilesCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -130,10 +135,10 @@ std::string cmInstallFilesCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); + std::string tb = makefile.GetCurrentBinaryDirectory(); tb += "/"; tb += name; - std::string ts = this->Makefile->GetCurrentSourceDirectory(); + std::string ts = makefile.GetCurrentSourceDirectory(); ts += "/"; ts += name; diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index e068b0e..f9b84fd 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -37,25 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return !this->IsFilesForm; } - -protected: - void CreateInstallGenerator() const; - std::string FindInstallSource(const char* name) const; - -private: - std::vector<std::string> FinalArgs; - bool IsFilesForm = false; - std::string Destination; - std::vector<std::string> Files; }; #endif diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index a58f875..6ec02e7 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallProgramsCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -12,6 +11,10 @@ class cmExecutionStatus; +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args); +static std::string FindInstallSource(cmMakefile& makefile, const char* name); + // cmExecutableCommand bool cmInstallProgramsCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) @@ -24,51 +27,55 @@ bool cmInstallProgramsCommand::InitialPass( // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; - - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); - this->Makefile->GetGlobalGenerator()->AddInstallComponent( this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + std::string const& dest = args[0]; + std::vector<std::string> const finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); return true; } -void cmInstallProgramsCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args) { bool files_mode = false; - if (!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES") { + if (!args.empty() && args[0] == "FILES") { files_mode = true; } + std::vector<std::string> files; + // two different options - if (this->FinalArgs.size() > 1 || files_mode) { + if (args.size() > 1 || files_mode) { // for each argument, get the programs - std::vector<std::string>::iterator s = this->FinalArgs.begin(); + std::vector<std::string>::const_iterator s = args.begin(); if (files_mode) { // Skip the FILES argument in files mode. ++s; } - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // add to the result - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } else // reg exp list { std::vector<std::string> programs; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), - this->FinalArgs[0], programs); + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0], + programs); std::vector<std::string>::iterator s = programs.begin(); // for each argument, get the programs for (; s != programs.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -79,12 +86,12 @@ void cmInstallProgramsCommand::FinalPass() const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), true, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), true, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -94,7 +101,7 @@ void cmInstallProgramsCommand::FinalPass() * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -103,10 +110,10 @@ std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); + std::string tb = makefile.GetCurrentBinaryDirectory(); tb += "/"; tb += name; - std::string ts = this->Makefile->GetCurrentSourceDirectory(); + std::string ts = makefile.GetCurrentSourceDirectory(); ts += "/"; ts += name; diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h index 3242365..ccd621d 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -37,24 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - - bool HasFinalPass() const override { return true; } - -protected: - std::string FindInstallSource(const char* name) const; - -private: - std::vector<std::string> FinalArgs; - std::string Destination; - std::vector<std::string> Files; }; #endif diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 235dcd4..f5da2ee 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -25,21 +25,89 @@ class cmExecutionStatus; # include <malloc.h> /* for malloc/free on QNX */ #endif -extern "C" void TrapsForSignalsCFunction(int sig); +namespace { + +const char* LastName = nullptr; + +extern "C" void TrapsForSignals(int sig) +{ + fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", + LastName, sig); +} + +struct SignalHandlerGuard +{ + explicit SignalHandlerGuard(const char* name) + { + LastName = name != nullptr ? name : "????"; + + signal(SIGSEGV, TrapsForSignals); +#ifdef SIGBUS + signal(SIGBUS, TrapsForSignals); +#endif + signal(SIGILL, TrapsForSignals); + } + + ~SignalHandlerGuard() + { + signal(SIGSEGV, nullptr); +#ifdef SIGBUS + signal(SIGBUS, nullptr); +#endif + signal(SIGILL, nullptr); + } + + SignalHandlerGuard(SignalHandlerGuard const&) = delete; + SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete; +}; + +struct LoadedCommandImpl : cmLoadedCommandInfo +{ + explicit LoadedCommandImpl(CM_INIT_FUNCTION init) + : cmLoadedCommandInfo{ 0, 0, &cmStaticCAPI, 0, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr } + { + init(this); + } + + ~LoadedCommandImpl() + { + if (this->Destructor) { + SignalHandlerGuard guard(this->Name); + this->Destructor(this); + } + if (this->Error != nullptr) { + free(this->Error); + } + } + + LoadedCommandImpl(LoadedCommandImpl const&) = delete; + LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete; + + int DoInitialPass(cmMakefile* mf, int argc, char* argv[]) + { + SignalHandlerGuard guard(this->Name); + return this->InitialPass(this, mf, argc, argv); + } + + void DoFinalPass(cmMakefile* mf) + { + SignalHandlerGuard guard(this->Name); + this->FinalPass(this, mf); + } +}; // a class for loadabple commands class cmLoadedCommand : public cmCommand { public: - cmLoadedCommand() + cmLoadedCommand() = default; + explicit cmLoadedCommand(CM_INIT_FUNCTION init) + : Impl(std::make_shared<LoadedCommandImpl>(init)) { - memset(&this->info, 0, sizeof(this->info)); - this->info.CAPI = &cmStaticCAPI; } - //! clean up any memory allocated by the plugin - ~cmLoadedCommand() override; - /** * This is a virtual constructor for the command. */ @@ -47,8 +115,8 @@ public: { auto newC = cm::make_unique<cmLoadedCommand>(); // we must copy when we clone - memcpy(&newC->info, &this->info, sizeof(info)); - return std::unique_ptr<cmLoadedCommand>(std::move(newC)); + newC->Impl = this->Impl; + return std::unique_ptr<cmCommand>(std::move(newC)); } /** @@ -58,66 +126,20 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) override; - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override - { - return this->info.FinalPass != nullptr; - } - - static const char* LastName; - static void TrapsForSignals(int sig) - { - fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", - cmLoadedCommand::LastName, sig); - } - static void InstallSignalHandlers(const char* name, int remove = 0) - { - cmLoadedCommand::LastName = name; - if (!name) { - cmLoadedCommand::LastName = "????"; - } - - if (!remove) { - signal(SIGSEGV, TrapsForSignalsCFunction); -#ifdef SIGBUS - signal(SIGBUS, TrapsForSignalsCFunction); -#endif - signal(SIGILL, TrapsForSignalsCFunction); - } else { - signal(SIGSEGV, nullptr); -#ifdef SIGBUS - signal(SIGBUS, nullptr); -#endif - signal(SIGILL, nullptr); - } - } - - cmLoadedCommandInfo info; +private: + std::shared_ptr<LoadedCommandImpl> Impl; }; -extern "C" void TrapsForSignalsCFunction(int sig) -{ - cmLoadedCommand::TrapsForSignals(sig); -} - -const char* cmLoadedCommand::LastName = nullptr; - bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { - if (!info.InitialPass) { + if (!this->Impl->InitialPass) { return true; } // clear the error string - if (this->info.Error) { - free(this->info.Error); + if (this->Impl->Error) { + free(this->Impl->Error); } // create argc and argv and then invoke the command @@ -130,42 +152,26 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, for (i = 0; i < argc; ++i) { argv[i] = strdup(args[i].c_str()); } - cmLoadedCommand::InstallSignalHandlers(info.Name); - int result = info.InitialPass(&info, this->Makefile, argc, argv); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + int result = this->Impl->DoInitialPass(this->Makefile, argc, argv); cmFreeArguments(argc, argv); if (result) { + if (this->Impl->FinalPass) { + auto impl = this->Impl; + this->Makefile->AddFinalAction( + [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); }); + } return true; } /* Initial Pass must have failed so set the error string */ - if (this->info.Error) { - this->SetError(this->info.Error); + if (this->Impl->Error) { + this->SetError(this->Impl->Error); } return false; } -void cmLoadedCommand::FinalPass() -{ - if (this->info.FinalPass) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.FinalPass(&this->info, this->Makefile); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } -} - -cmLoadedCommand::~cmLoadedCommand() -{ - if (this->info.Destructor) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.Destructor(&this->info); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } - if (this->info.Error) { - free(this->info.Error); - } -} +} // namespace // cmLoadCommandCommand bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, @@ -240,10 +246,8 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, // if the symbol is found call it to set the name on the // function blocker if (initFunction) { - // create a function blocker and set it up - auto f = cm::make_unique<cmLoadedCommand>(); - (*initFunction)(&f->info); - this->Makefile->GetState()->AddScriptedCommand(args[0], std::move(f)); + this->Makefile->GetState()->AddScriptedCommand( + args[0], cm::make_unique<cmLoadedCommand>(initFunction)); return true; } this->SetError("Attempt to load command failed. " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 7ba3471..8154f3e 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -703,8 +703,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( } Options targetOptions(this, t, table, gg->ExtraFlagTable); targetOptions.FixExceptionHandlingDefault(); - std::string asmLocation = configName + "/"; - targetOptions.AddFlag("AssemblerListingLocation", asmLocation); + targetOptions.AddFlag("AssemblerListingLocation", "$(IntDir)\\"); targetOptions.Parse(flags); targetOptions.Parse(defineFlags); targetOptions.ParseFinish(); diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 3d553b7..6e65c6b 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -213,8 +213,10 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, } // create a function blocker - cmMacroFunctionBlocker* f = new cmMacroFunctionBlocker(); - cmAppend(f->Args, args); - this->Makefile->AddFunctionBlocker(f); + { + auto fb = cm::make_unique<cmMacroFunctionBlocker>(); + cmAppend(fb->Args, args); + this->Makefile->AddFunctionBlocker(std::move(fb)); + } return true; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 501ea69..1723c5a 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -118,7 +118,6 @@ cmMakefile::~cmMakefile() cmDeleteAll(this->SourceFiles); cmDeleteAll(this->Tests); cmDeleteAll(this->ImportedTargetsOwned); - cmDeleteAll(this->FunctionBlockers); cmDeleteAll(this->EvaluationFiles); } @@ -415,9 +414,6 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, if (this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) { cmSystemTools::SetFatalErrorOccured(); } - } else if (pcmd->HasFinalPass()) { - // use the command - this->FinalPassCommands.push_back(std::move(pcmd)); } } } else { @@ -768,6 +764,11 @@ struct file_not_persistent }; } +void cmMakefile::AddFinalAction(FinalAction action) +{ + this->FinalActions.push_back(std::move(action)); +} + void cmMakefile::FinalPass() { // do all the variable expansions here @@ -775,8 +776,8 @@ void cmMakefile::FinalPass() // give all the commands a chance to do something // after the file has been parsed before generation - for (auto& command : this->FinalPassCommands) { - command->FinalPass(); + for (FinalAction& action : this->FinalActions) { + action(*this); } // go through all configured files and see which ones still exist. @@ -3076,13 +3077,13 @@ bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status) { // if there are no blockers get out of here - if (this->FunctionBlockers.begin() == this->FunctionBlockers.end()) { + if (this->FunctionBlockers.empty()) { return false; } // loop over all function blockers to see if any block this command // evaluate in reverse, this is critical for balanced IF statements etc - for (cmFunctionBlocker* pos : cmReverseRange(this->FunctionBlockers)) { + for (auto const& pos : cmReverseRange(this->FunctionBlockers)) { if (pos->IsFunctionBlocked(lff, *this, status)) { return true; } @@ -3102,7 +3103,8 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) FunctionBlockersType::size_type barrier = this->FunctionBlockerBarriers.back(); while (this->FunctionBlockers.size() > barrier) { - std::unique_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back()); + std::unique_ptr<cmFunctionBlocker> fb( + std::move(this->FunctionBlockers.back())); this->FunctionBlockers.pop_back(); if (reportError) { // Report the context in which the unclosed block was opened. @@ -3227,14 +3229,14 @@ bool cmMakefile::ExpandArguments( return !cmSystemTools::GetFatalErrorOccured(); } -void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb) +void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb) { if (!this->ExecutionStatusStack.empty()) { // Record the context in which the blocker is created. fb->SetStartingContext(this->GetExecutionContext()); } - this->FunctionBlockers.push_back(fb); + this->FunctionBlockers.push_back(std::move(fb)); } std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker( @@ -3250,9 +3252,8 @@ std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker( // Search for the function blocker whose scope this command ends. for (FunctionBlockersType::size_type i = this->FunctionBlockers.size(); i > barrier; --i) { - std::vector<cmFunctionBlocker*>::iterator pos = - this->FunctionBlockers.begin() + (i - 1); - if (*pos == fb) { + auto pos = this->FunctionBlockers.begin() + (i - 1); + if (pos->get() == fb) { // Warn if the arguments do not match, but always remove. if (!(*pos)->ShouldRemove(lff, *this)) { cmListFileContext const& lfc = fb->GetStartingContext(); @@ -3268,9 +3269,9 @@ std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker( /* clang-format on */ this->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); } - cmFunctionBlocker* b = *pos; + std::unique_ptr<cmFunctionBlocker> b = std::move(*pos); this->FunctionBlockers.erase(pos); - return std::unique_ptr<cmFunctionBlocker>(b); + return b; } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1b4ead7..1eca18c 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -7,6 +7,7 @@ #include "cmsys/RegularExpression.hxx" #include <deque> +#include <functional> #include <map> #include <memory> #include <set> @@ -17,6 +18,7 @@ #include <vector> #include "cmAlgorithms.h" +#include "cmFunctionBlocker.h" #include "cmListFileCache.h" #include "cmMessageType.h" #include "cmNewLineStyle.h" @@ -30,13 +32,11 @@ # include "cmSourceGroup.h" #endif -class cmCommand; class cmCompiledGeneratorExpression; class cmCustomCommandLines; class cmExecutionStatus; class cmExpandedCommandArgument; class cmExportBuildFileGenerator; -class cmFunctionBlocker; class cmGeneratorExpressionEvaluationFile; class cmGlobalGenerator; class cmInstallGenerator; @@ -95,7 +95,7 @@ public: /** * Add a function blocker to this makefile */ - void AddFunctionBlocker(cmFunctionBlocker* fb); + void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb); /// @return whether we are processing the top CMakeLists.txt file. bool IsRootMakefile() const; @@ -125,6 +125,13 @@ public: bool EnforceUniqueName(std::string const& name, std::string& msg, bool isCustom = false) const; + using FinalAction = std::function<void(cmMakefile&)>; + + /** + * Register an action that is executed during FinalPass + */ + void AddFinalAction(FinalAction action); + /** * Perform FinalPass, Library dependency analysis etc before output of the * makefile. @@ -132,7 +139,7 @@ public: void ConfigureFinalPass(); /** - * run the final pass on all commands. + * run all FinalActions. */ void FinalPass(); @@ -937,7 +944,7 @@ protected: size_t ObjectLibrariesSourceGroupIndex; #endif - std::vector<std::unique_ptr<cmCommand>> FinalPassCommands; + std::vector<FinalAction> FinalActions; cmGlobalGenerator* GlobalGenerator; bool IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status); @@ -955,7 +962,7 @@ private: bool EnforceUniqueDir(const std::string& srcPath, const std::string& binPath) const; - typedef std::vector<cmFunctionBlocker*> FunctionBlockersType; + typedef std::vector<std::unique_ptr<cmFunctionBlocker>> FunctionBlockersType; FunctionBlockersType FunctionBlockers; std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers; void PushFunctionBlockerBarrier(); diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 5fe55bd..afc0b76 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -3,6 +3,7 @@ #include "cmVariableWatchCommand.h" #include <sstream> +#include <utility> #include "cmExecutionStatus.h" #include "cmListFileCache.h" @@ -84,15 +85,39 @@ static void deleteVariableWatchCallbackData(void* client_data) delete data; } -cmVariableWatchCommand::cmVariableWatchCommand() = default; - -cmVariableWatchCommand::~cmVariableWatchCommand() +/** This command does not really have a final pass but it needs to + stay alive since it owns variable watch callback information. */ +class FinalAction { - for (std::string const& wv : this->WatchedVariables) { - this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( - wv, cmVariableWatchCommandVariableAccessed); +public: + FinalAction(cmMakefile* makefile, std::string variable) + : Action(std::make_shared<Impl>(makefile, std::move(variable))) + { } -} + + void operator()(cmMakefile&) const {} + +private: + struct Impl + { + Impl(cmMakefile* makefile, std::string variable) + : Makefile(makefile) + , Variable(std::move(variable)) + { + } + + ~Impl() + { + this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( + this->Variable, cmVariableWatchCommandVariableAccessed); + } + + cmMakefile* Makefile; + std::string Variable; + }; + + std::shared_ptr<Impl const> Action; +}; bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) @@ -118,7 +143,6 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, data->InCallback = false; data->Command = command; - this->WatchedVariables.insert(variable); if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch( variable, cmVariableWatchCommandVariableAccessed, data, deleteVariableWatchCallbackData)) { @@ -126,5 +150,6 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, return false; } + this->Makefile->AddFinalAction(FinalAction(this->Makefile, variable)); return true; } diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index 0dbb0cb..221269f 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -5,7 +5,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> @@ -30,25 +29,12 @@ public: return cm::make_unique<cmVariableWatchCommand>(); } - //! Default constructor - cmVariableWatchCommand(); - - //! Destructor. - ~cmVariableWatchCommand() override; - /** * This is called when the command is first encountered in * the CMakeLists.txt file. */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** This command does not really have a final pass but it needs to - stay alive since it owns variable watch callback information. */ - bool HasFinalPass() const override { return true; } - -protected: - std::set<std::string> WatchedVariables; }; #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ae347fe..4a151b3 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2649,8 +2649,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("UseFullPaths", "false"); } clOptions.AddFlag("PrecompiledHeader", "NotUsing"); - std::string asmLocation = configName + "/"; - clOptions.AddFlag("AssemblerListingLocation", asmLocation); + clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)"); } } diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 31a878d..a902964 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmWhileCommand.h" +#include "cm_memory.hxx" + #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" #include "cmExpandedCommandArgument.h" @@ -9,6 +11,8 @@ #include "cmMessageType.h" #include "cmSystemTools.h" +#include <utility> + cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf) : Makefile(mf) , Depth(0) @@ -134,9 +138,10 @@ bool cmWhileCommand::InvokeInitialPass( } // create a function blocker - cmWhileFunctionBlocker* f = new cmWhileFunctionBlocker(this->Makefile); - f->Args = args; - this->Makefile->AddFunctionBlocker(f); - + { + auto fb = cm::make_unique<cmWhileFunctionBlocker>(this->Makefile); + fb->Args = args; + this->Makefile->AddFunctionBlocker(std::move(fb)); + } return true; } |