diff options
32 files changed, 629 insertions, 558 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d24c2c0..d9ca09b 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190925) +set(CMake_VERSION_PATCH 20190927) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 88d17f1..b1f7db7 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -246,26 +246,22 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("set_tests_properties", cmSetTestsPropertiesCommand); state->AddBuiltinCommand("subdirs", cmSubdirCommand); - state->AddBuiltinCommand( - "target_compile_definitions", - cm::make_unique<cmTargetCompileDefinitionsCommand>()); + state->AddBuiltinCommand("target_compile_definitions", + cmTargetCompileDefinitionsCommand); state->AddBuiltinCommand("target_compile_features", - cm::make_unique<cmTargetCompileFeaturesCommand>()); + cmTargetCompileFeaturesCommand); state->AddBuiltinCommand("target_compile_options", - cm::make_unique<cmTargetCompileOptionsCommand>()); - state->AddBuiltinCommand( - "target_include_directories", - cm::make_unique<cmTargetIncludeDirectoriesCommand>()); + cmTargetCompileOptionsCommand); + state->AddBuiltinCommand("target_include_directories", + cmTargetIncludeDirectoriesCommand); state->AddBuiltinCommand("target_link_libraries", cmTargetLinkLibrariesCommand); - state->AddBuiltinCommand("target_sources", - cm::make_unique<cmTargetSourcesCommand>()); + state->AddBuiltinCommand("target_sources", cmTargetSourcesCommand); state->AddBuiltinCommand("try_compile", cm::make_unique<cmTryCompileCommand>()); state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>()); - state->AddBuiltinCommand( - "target_precompile_headers", - cm::make_unique<cmTargetPrecompileHeadersCommand>()); + state->AddBuiltinCommand("target_precompile_headers", + cmTargetPrecompileHeadersCommand); #if !defined(CMAKE_BOOTSTRAP) state->AddBuiltinCommand("add_compile_definitions", @@ -280,10 +276,9 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("install_programs", cmInstallProgramsCommand); state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand); state->AddBuiltinCommand("link_libraries", cmLinkLibrariesCommand); - state->AddBuiltinCommand("target_link_options", - cm::make_unique<cmTargetLinkOptionsCommand>()); + state->AddBuiltinCommand("target_link_options", cmTargetLinkOptionsCommand); state->AddBuiltinCommand("target_link_directories", - cm::make_unique<cmTargetLinkDirectoriesCommand>()); + cmTargetLinkDirectoriesCommand); state->AddBuiltinCommand("load_cache", cmLoadCacheCommand); state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand); state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand); diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 96ea071..fbdb975 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -858,47 +858,69 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) fd.Flags.emplace_back(std::move(flags), JBTIndex()); } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) { - std::string flags; - lg->AppendCompileOptions( - flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS)); - fd.Flags.emplace_back(std::move(flags), JBTIndex()); + for (BT<std::string> tmpOpt : sf->GetCompileOptions()) { + tmpOpt.Value = genexInterpreter.Evaluate(tmpOpt.Value, COMPILE_OPTIONS); + // After generator evaluation we need to use the AppendCompileOptions + // method so we handle situations where backtrace entries have lists + // and properly escape flags. + std::string tmp; + lg->AppendCompileOptions(tmp, tmpOpt.Value); + BT<std::string> opt(tmp, tmpOpt.Backtrace); + fd.Flags.emplace_back(this->ToJBT(opt)); } // Add include directories from source file properties. { - std::vector<std::string> includes; const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) { - const std::string& evaluatedIncludes = - genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES); - lg->AppendIncludeDirectories(includes, evaluatedIncludes, *sf); - - for (std::string const& include : includes) { - bool const isSystemInclude = this->GT->IsSystemIncludeDirectory( - include, this->Config, fd.Language); - fd.Includes.emplace_back(include, isSystemInclude); + for (BT<std::string> tmpInclude : sf->GetIncludeDirectories()) { + tmpInclude.Value = + genexInterpreter.Evaluate(tmpInclude.Value, INCLUDE_DIRECTORIES); + + // After generator evaluation we need to use the AppendIncludeDirectories + // method so we handle situations where backtrace entries have lists. + std::vector<std::string> tmp; + lg->AppendIncludeDirectories(tmp, tmpInclude.Value, *sf); + for (std::string& i : tmp) { + bool const isSystemInclude = + this->GT->IsSystemIncludeDirectory(i, this->Config, fd.Language); + BT<std::string> include(i, tmpInclude.Backtrace); + fd.Includes.emplace_back(this->ToJBT(include), isSystemInclude); } } } const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - std::set<std::string> fileDefines; - if (const char* defs = sf->GetProperty(COMPILE_DEFINITIONS)) { - lg->AppendDefines(fileDefines, - genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS)); + std::set<BT<std::string>> fileDefines; + for (BT<std::string> tmpDef : sf->GetCompileDefinitions()) { + tmpDef.Value = + genexInterpreter.Evaluate(tmpDef.Value, COMPILE_DEFINITIONS); + + // After generator evaluation we need to use the AppendDefines method + // so we handle situations where backtrace entries have lists. + std::set<std::string> tmp; + lg->AppendDefines(tmp, tmpDef.Value); + for (const std::string& i : tmp) { + BT<std::string> def(i, tmpDef.Backtrace); + fileDefines.insert(def); + } } + std::set<std::string> configFileDefines; const std::string defPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config); if (const char* config_defs = sf->GetProperty(defPropName)) { lg->AppendDefines( - fileDefines, + configFileDefines, genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS)); } - fd.Defines.reserve(fileDefines.size()); - for (std::string const& d : fileDefines) { + fd.Defines.reserve(fileDefines.size() + configFileDefines.size()); + + for (BT<std::string> const& def : fileDefines) { + fd.Defines.emplace_back(this->ToJBT(def)); + } + + for (std::string const& d : configFileDefines) { fd.Defines.emplace_back(d, JBTIndex()); } diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index bd68d04..2a345eb 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -6,6 +6,7 @@ #include <utility> #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmProperty.h" @@ -28,6 +29,11 @@ std::string const& cmSourceFile::GetExtension() const const std::string cmSourceFile::propLANGUAGE = "LANGUAGE"; const std::string cmSourceFile::propLOCATION = "LOCATION"; const std::string cmSourceFile::propGENERATED = "GENERATED"; +const std::string cmSourceFile::propCOMPILE_DEFINITIONS = + "COMPILE_DEFINITIONS"; +const std::string cmSourceFile::propCOMPILE_OPTIONS = "COMPILE_OPTIONS"; +const std::string cmSourceFile::propINCLUDE_DIRECTORIES = + "INCLUDE_DIRECTORIES"; void cmSourceFile::SetObjectLibrary(std::string const& objlib) { @@ -226,7 +232,27 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc) void cmSourceFile::SetProperty(const std::string& prop, const char* value) { - this->Properties.SetProperty(prop, value); + if (prop == propINCLUDE_DIRECTORIES) { + this->IncludeDirectories.clear(); + if (value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->IncludeDirectories.emplace_back(value, lfbt); + } + } else if (prop == propCOMPILE_OPTIONS) { + this->CompileOptions.clear(); + if (value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->CompileOptions.emplace_back(value, lfbt); + } + } else if (prop == propCOMPILE_DEFINITIONS) { + this->CompileDefinitions.clear(); + if (value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->CompileDefinitions.emplace_back(value, lfbt); + } + } else { + this->Properties.SetProperty(prop, value); + } // Update IsGenerated flag if (prop == propGENERATED) { @@ -237,7 +263,24 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) void cmSourceFile::AppendProperty(const std::string& prop, const char* value, bool asString) { - this->Properties.AppendProperty(prop, value, asString); + if (prop == propINCLUDE_DIRECTORIES) { + if (value && *value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->IncludeDirectories.emplace_back(value, lfbt); + } + } else if (prop == propCOMPILE_OPTIONS) { + if (value && *value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->CompileOptions.emplace_back(value, lfbt); + } + } else if (prop == propCOMPILE_DEFINITIONS) { + if (value && *value) { + cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace(); + this->CompileDefinitions.emplace_back(value, lfbt); + } + } else { + this->Properties.AppendProperty(prop, value, asString); + } // Update IsGenerated flag if (prop == propGENERATED) { @@ -287,6 +330,37 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const return this->FullPath.c_str(); } + // Check for the properties with backtraces. + if (prop == propINCLUDE_DIRECTORIES) { + if (this->IncludeDirectories.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(this->IncludeDirectories, ";"); + return output.c_str(); + } + + if (prop == propCOMPILE_OPTIONS) { + if (this->CompileOptions.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(this->CompileOptions, ";"); + return output.c_str(); + } + + if (prop == propCOMPILE_DEFINITIONS) { + if (this->CompileDefinitions.empty()) { + return nullptr; + } + + static std::string output; + output = cmJoin(this->CompileDefinitions, ";"); + return output.c_str(); + } + const char* retVal = this->Properties.GetPropertyValue(prop); if (!retVal) { cmMakefile const* mf = this->Location.GetMakefile(); diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 3b18fdb..6ef4167 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCustomCommand.h" +#include "cmListFileCache.h" #include "cmPropertyMap.h" #include "cmSourceFileLocation.h" #include "cmSourceFileLocationKind.h" @@ -57,6 +58,21 @@ public: /// @return Equivalent to GetPropertyAsBool("GENERATED") bool GetIsGenerated() const { return this->IsGenerated; } + const std::vector<BT<std::string>>& GetCompileOptions() const + { + return this->CompileOptions; + } + + const std::vector<BT<std::string>>& GetCompileDefinitions() const + { + return this->CompileDefinitions; + } + + const std::vector<BT<std::string>>& GetIncludeDirectories() const + { + return this->IncludeDirectories; + } + /** * Resolves the full path to the file. Attempts to locate the file on disk * and finalizes its location. @@ -116,6 +132,9 @@ private: std::string FullPath; std::string ObjectLibrary; std::vector<std::string> Depends; + std::vector<BT<std::string>> CompileOptions; + std::vector<BT<std::string>> CompileDefinitions; + std::vector<BT<std::string>> IncludeDirectories; bool FindFullPathFailed = false; bool IsGenerated = false; @@ -126,6 +145,9 @@ private: static const std::string propLANGUAGE; static const std::string propLOCATION; static const std::string propGENERATED; + static const std::string propCOMPILE_DEFINITIONS; + static const std::string propCOMPILE_OPTIONS; + static const std::string propINCLUDE_DIRECTORIES; }; // TODO: Factor out into platform information modules. diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index 94e249f..edee167 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -6,43 +6,53 @@ #include "cmMessageType.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetCompileDefinitionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +class TargetCompileDefinitionsImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "COMPILE_DEFINITIONS"); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetCompileDefinitionsCommand::HandleMissingTarget( - const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify compile definitions for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile definitions for target \"", name, + "\" which is not built by this project.")); + } -std::string cmTargetCompileDefinitionsCommand::Join( - const std::vector<std::string>& content) -{ - std::string defs; - std::string sep; - for (std::string const& it : content) { - if (cmHasLiteralPrefix(it, "-D")) { - defs += sep + it.substr(2); - } else { - defs += sep + it; + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool /*prepend*/, bool /*system*/) override + { + tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str()); + return true; // Successfully handled. + } + + std::string Join(const std::vector<std::string>& content) override + { + std::string defs; + std::string sep; + for (std::string const& it : content) { + if (cmHasLiteralPrefix(it, "-D")) { + defs += sep + it.substr(2); + } else { + defs += sep + it; + } + sep = ";"; } - sep = ";"; + return defs; } - return defs; -} +}; + +} // namespace -bool cmTargetCompileDefinitionsCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) +bool cmTargetCompileDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str()); - return true; // Successfully handled. + return TargetCompileDefinitionsImpl(status).HandleArguments( + args, "COMPILE_DEFINITIONS"); } diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h index f85dc0a..05ff092 100644 --- a/Source/cmTargetCompileDefinitionsCommand.h +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -8,39 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetCompileDefinitionsCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetCompileDefinitionsCommand>(); - } - - /** - * 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; - -private: - void HandleMissingTarget(const std::string& name) override; - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - std::string Join(const std::vector<std::string>& content) override; -}; +bool cmTargetCompileDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index a22b94b..06be4f0 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -5,40 +5,51 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; class cmTarget; -bool cmTargetCompileFeaturesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) -{ - return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS); -} +namespace { -void cmTargetCompileFeaturesCommand::HandleMissingTarget( - const std::string& name) +class TargetCompileFeaturesImpl : public cmTargetPropCommandBase { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify compile features for target \"", name, - "\" which is not built by this project.")); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -std::string cmTargetCompileFeaturesCommand::Join( - const std::vector<std::string>& content) -{ - return cmJoin(content, ";"); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile features for target \"", name, + "\" which is not built by this project.")); + } -bool cmTargetCompileFeaturesCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) -{ - for (std::string const& it : content) { - std::string error; - if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) { - this->SetError(error); - return false; // Not (successfully) handled. + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool /*prepend*/, bool /*system*/) override + { + for (std::string const& it : content) { + std::string error; + if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) { + this->SetError(error); + return false; // Not (successfully) handled. + } } + return true; // Successfully handled. + } + + std::string Join(const std::vector<std::string>& content) override + { + return cmJoin(content, ";"); } - return true; // Successfully handled. +}; + +} // namespace + +bool cmTargetCompileFeaturesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return TargetCompileFeaturesImpl(status).HandleArguments(args, + "COMPILE_FEATURES"); } diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h index 39597ca..db0c04b 100644 --- a/Source/cmTargetCompileFeaturesCommand.h +++ b/Source/cmTargetCompileFeaturesCommand.h @@ -8,31 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase -{ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetCompileFeaturesCommand>(); - } - - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void HandleMissingTarget(const std::string& name) override; - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - std::string Join(const std::vector<std::string>& content) override; -}; +bool cmTargetCompileFeaturesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index ccc215a..e39b726 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -7,34 +7,44 @@ #include "cmMessageType.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetCompileOptionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +class TargetCompileOptionsImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetCompileOptionsCommand::HandleMissingTarget( - const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify compile options for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify compile options for target \"", name, + "\" which is not built by this project.")); + } -std::string cmTargetCompileOptionsCommand::Join( - const std::vector<std::string>& content) -{ - return cmJoin(content, ";"); -} + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool /*prepend*/, bool /*system*/) override + { + cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); + tgt->InsertCompileOption(this->Join(content), lfbt); + return true; // Successfully handled. + } + + std::string Join(const std::vector<std::string>& content) override + { + return cmJoin(content, ";"); + } +}; + +} // namespace -bool cmTargetCompileOptionsCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) +bool cmTargetCompileOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertCompileOption(this->Join(content), lfbt); - return true; // Successfully handled. + return TargetCompileOptionsImpl(status).HandleArguments( + args, "COMPILE_OPTIONS", TargetCompileOptionsImpl::PROCESS_BEFORE); } diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h index b328ba2..3ab1a89 100644 --- a/Source/cmTargetCompileOptionsCommand.h +++ b/Source/cmTargetCompileOptionsCommand.h @@ -8,39 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetCompileOptionsCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetCompileOptionsCommand>(); - } - - /** - * 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; - -private: - void HandleMissingTarget(const std::string& name) override; - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - std::string Join(const std::vector<std::string>& content) override; -}; +bool cmTargetCompileOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index 7801ee8..95b69f3 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -11,26 +11,36 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetIncludeDirectoriesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +class TargetIncludeDirectoriesImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "INCLUDE_DIRECTORIES", - ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM)); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetIncludeDirectoriesCommand::HandleMissingTarget( - const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify include directories for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify include directories for target \"", name, + "\" which is not built by this project.")); + } + + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override; + + void HandleInterfaceContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override; -std::string cmTargetIncludeDirectoriesCommand::Join( + std::string Join(const std::vector<std::string>& content) override; +}; + +std::string TargetIncludeDirectoriesImpl::Join( const std::vector<std::string>& content) { std::string dirs; @@ -48,7 +58,7 @@ std::string cmTargetIncludeDirectoriesCommand::Join( return dirs; } -bool cmTargetIncludeDirectoriesCommand::HandleDirectContent( +bool TargetIncludeDirectoriesImpl::HandleDirectContent( cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool system) { @@ -70,16 +80,27 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent( return true; // Successfully handled. } -void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent( +void TargetIncludeDirectoriesImpl::HandleInterfaceContent( cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool system) { cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend, system); - if (system) { std::string joined = this->Join(content); tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined.c_str()); } } + +} // namespace + +bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return TargetIncludeDirectoriesImpl(status).HandleArguments( + args, "INCLUDE_DIRECTORIES", + TargetIncludeDirectoriesImpl::ArgumentFlags( + TargetIncludeDirectoriesImpl::PROCESS_BEFORE | + TargetIncludeDirectoriesImpl::PROCESS_SYSTEM)); +} diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h index f6481db..9958f41 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.h +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -8,43 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetIncludeDirectoriesCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetIncludeDirectoriesCommand>(); - } - - /** - * 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; - -private: - void HandleMissingTarget(const std::string& name) override; - - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - void HandleInterfaceContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - std::string Join(const std::vector<std::string>& content) override; -}; +bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx index c2ef6c1..0c68d60 100644 --- a/Source/cmTargetLinkDirectoriesCommand.cxx +++ b/Source/cmTargetLinkDirectoriesCommand.cxx @@ -9,25 +9,37 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetLinkDirectoriesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +class TargetLinkDirectoriesImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "LINK_DIRECTORIES", PROCESS_BEFORE); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetLinkDirectoriesCommand::HandleMissingTarget( - const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify link directories for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify link directories for target \"", name, + "\" which is not built by this project.")); + } + + std::string Join(const std::vector<std::string>& content) override; -std::string cmTargetLinkDirectoriesCommand::Join( + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool /*system*/) override + { + cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); + tgt->InsertLinkDirectory(this->Join(content), lfbt, prepend); + return true; // Successfully handled. + } +}; + +std::string TargetLinkDirectoriesImpl::Join( const std::vector<std::string>& content) { std::vector<std::string> directories; @@ -48,12 +60,11 @@ std::string cmTargetLinkDirectoriesCommand::Join( return cmJoin(directories, ";"); } -bool cmTargetLinkDirectoriesCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool) -{ - cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); +} // namespace - tgt->InsertLinkDirectory(this->Join(content), lfbt, prepend); - - return true; // Successfully handled. +bool cmTargetLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return TargetLinkDirectoriesImpl(status).HandleArguments( + args, "LINK_DIRECTORIES", TargetLinkDirectoriesImpl::PROCESS_BEFORE); } diff --git a/Source/cmTargetLinkDirectoriesCommand.h b/Source/cmTargetLinkDirectoriesCommand.h index a651d73..3724d6c 100644 --- a/Source/cmTargetLinkDirectoriesCommand.h +++ b/Source/cmTargetLinkDirectoriesCommand.h @@ -8,39 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetLinkDirectoriesCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetLinkDirectoriesCommand>(); - } - - /** - * 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; - -private: - void HandleMissingTarget(const std::string& name) override; - std::string Join(const std::vector<std::string>& content) override; - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; -}; +bool cmTargetLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index dbd7bfe..df9416f 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -7,33 +7,44 @@ #include "cmMessageType.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetLinkOptionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +class TargetLinkOptionsImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "LINK_OPTIONS", PROCESS_BEFORE); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetLinkOptionsCommand::HandleMissingTarget(const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify link options for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify link options for target \"", name, + "\" which is not built by this project.")); + } -std::string cmTargetLinkOptionsCommand::Join( - const std::vector<std::string>& content) -{ - return cmJoin(content, ";"); -} + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool /*system*/) override + { + cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); + tgt->InsertLinkOption(this->Join(content), lfbt, prepend); + return true; // Successfully handled. + } + + std::string Join(const std::vector<std::string>& content) override + { + return cmJoin(content, ";"); + } +}; + +} // namespace -bool cmTargetLinkOptionsCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool) +bool cmTargetLinkOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertLinkOption(this->Join(content), lfbt, prepend); - return true; // Successfully handled. + return TargetLinkOptionsImpl(status).HandleArguments( + args, "LINK_OPTIONS", TargetLinkOptionsImpl::PROCESS_BEFORE); } diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h index 918a8d7..13fb40c 100644 --- a/Source/cmTargetLinkOptionsCommand.h +++ b/Source/cmTargetLinkOptionsCommand.h @@ -8,39 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetLinkOptionsCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetLinkOptionsCommand>(); - } - - /** - * 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; - -private: - void HandleMissingTarget(const std::string& name) override; - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - std::string Join(const std::vector<std::string>& content) override; -}; +bool cmTargetLinkOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx index 5751fff..887d973 100644 --- a/Source/cmTargetPrecompileHeadersCommand.cxx +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -8,51 +8,14 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" #include <utility> -bool cmTargetPrecompileHeadersCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) -{ - return this->HandleArguments(args, "PRECOMPILE_HEADERS", PROCESS_REUSE_FROM); -} - -void cmTargetPrecompileHeadersCommand::HandleInterfaceContent( - cmTarget* tgt, const std::vector<std::string>& content, bool prepend, - bool system) -{ - cmTargetPropCommandBase::HandleInterfaceContent( - tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); -} - -void cmTargetPrecompileHeadersCommand::HandleMissingTarget( - const std::string& name) -{ - const std::string e = - cmStrCat("Cannot specify precompile headers for target \"", name, - "\" which is not built by this project."); - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); -} - -std::string cmTargetPrecompileHeadersCommand::Join( - const std::vector<std::string>& content) -{ - return cmJoin(content, ";"); -} - -bool cmTargetPrecompileHeadersCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) -{ - tgt->AppendProperty( - "PRECOMPILE_HEADERS", - this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); - return true; -} +namespace { -std::vector<std::string> -cmTargetPrecompileHeadersCommand::ConvertToAbsoluteContent( - cmTarget* /*tgt*/, const std::vector<std::string>& content, - bool /*isInterfaceContent*/) +std::vector<std::string> ConvertToAbsoluteContent( + const std::vector<std::string>& content, std::string const& baseDir) { std::vector<std::string> absoluteContent; absoluteContent.reserve(content.size()); @@ -66,10 +29,59 @@ cmTargetPrecompileHeadersCommand::ConvertToAbsoluteContent( cmGeneratorExpression::Find(src) == 0) { absoluteSrc = src; } else { - absoluteSrc = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', src); + absoluteSrc = cmStrCat(baseDir, '/', src); } absoluteContent.emplace_back(std::move(absoluteSrc)); } return absoluteContent; } + +class TargetPrecompileHeadersImpl : public cmTargetPropCommandBase +{ +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; + +private: + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool /*prepend*/, bool /*system*/) override + { + std::string const& base = this->Makefile->GetCurrentSourceDirectory(); + tgt->AppendProperty( + "PRECOMPILE_HEADERS", + this->Join(ConvertToAbsoluteContent(content, base)).c_str()); + return true; + } + + void HandleInterfaceContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override + { + std::string const& base = this->Makefile->GetCurrentSourceDirectory(); + cmTargetPropCommandBase::HandleInterfaceContent( + tgt, ConvertToAbsoluteContent(content, base), prepend, system); + } + + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify precompile headers for target \"", name, + "\" which is not built by this project.")); + } + + std::string Join(const std::vector<std::string>& content) override + { + return cmJoin(content, ";"); + } +}; + +} // namespace + +bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return TargetPrecompileHeadersImpl(status).HandleArguments( + args, "PRECOMPILE_HEADERS", + TargetPrecompileHeadersImpl::PROCESS_REUSE_FROM); +} diff --git a/Source/cmTargetPrecompileHeadersCommand.h b/Source/cmTargetPrecompileHeadersCommand.h index 00dc928..8b0ac97 100644 --- a/Source/cmTargetPrecompileHeadersCommand.h +++ b/Source/cmTargetPrecompileHeadersCommand.h @@ -8,43 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetPrecompileHeadersCommand : public cmTargetPropCommandBase -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetPrecompileHeadersCommand>(); - } - - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - void HandleInterfaceContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - -private: - void HandleMissingTarget(const std::string& name) override; - - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - - std::string Join(const std::vector<std::string>& content) override; - std::vector<std::string> ConvertToAbsoluteContent( - cmTarget* tgt, const std::vector<std::string>& content, - bool isInterfaceContent); -}; +bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 4bc3125..bbc1e16 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -2,12 +2,24 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetPropCommandBase.h" +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmTarget.h" #include "cmake.h" +cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status) + : Makefile(&status.GetMakefile()) + , Status(status) +{ +} + +void cmTargetPropCommandBase::SetError(std::string const& e) +{ + this->Status.SetError(e); +} + bool cmTargetPropCommandBase::HandleArguments( std::vector<std::string> const& args, const std::string& prop, ArgumentFlags flags) diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h index b244417..601ad01 100644 --- a/Source/cmTargetPropCommandBase.h +++ b/Source/cmTargetPropCommandBase.h @@ -8,13 +8,18 @@ #include <string> #include <vector> -#include "cmCommand.h" - +class cmExecutionStatus; +class cmMakefile; class cmTarget; -class cmTargetPropCommandBase : public cmCommand +class cmTargetPropCommandBase { public: + cmTargetPropCommandBase(cmExecutionStatus& status); + virtual ~cmTargetPropCommandBase() = default; + + void SetError(std::string const& e); + enum ArgumentFlags { NO_FLAGS = 0x0, @@ -30,6 +35,7 @@ public: protected: std::string Property; cmTarget* Target = nullptr; + cmMakefile* Makefile; virtual void HandleInterfaceContent(cmTarget* tgt, const std::vector<std::string>& content, @@ -49,6 +55,8 @@ private: bool PopulateTargetProperies(const std::string& scope, const std::vector<std::string>& content, bool prepend, bool system); + + cmExecutionStatus& Status; }; #endif diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index 7c9d03c..c2e0b28 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -11,47 +11,54 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetPropCommandBase.h" -class cmExecutionStatus; +namespace { -bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +class TargetSourcesImpl : public cmTargetPropCommandBase { - return this->HandleArguments(args, "SOURCES"); -} +public: + using cmTargetPropCommandBase::cmTargetPropCommandBase; -void cmTargetSourcesCommand::HandleInterfaceContent( - cmTarget* tgt, const std::vector<std::string>& content, bool prepend, - bool system) -{ - cmTargetPropCommandBase::HandleInterfaceContent( - tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); -} +protected: + void HandleInterfaceContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override + { + cmTargetPropCommandBase::HandleInterfaceContent( + tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); + } -void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name) -{ - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Cannot specify sources for target \"", name, - "\" which is not built by this project.")); -} +private: + void HandleMissingTarget(const std::string& name) override + { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Cannot specify sources for target \"", name, + "\" which is not built by this project.")); + } -std::string cmTargetSourcesCommand::Join( - const std::vector<std::string>& content) -{ - return cmJoin(content, ";"); -} + bool HandleDirectContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool /*prepend*/, bool /*system*/) override + { + tgt->AppendProperty( + "SOURCES", + this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); + return true; // Successfully handled. + } -bool cmTargetSourcesCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) -{ - tgt->AppendProperty( - "SOURCES", - this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); - return true; // Successfully handled. -} + std::string Join(const std::vector<std::string>& content) override + { + return cmJoin(content, ";"); + } + + std::vector<std::string> ConvertToAbsoluteContent( + cmTarget* tgt, const std::vector<std::string>& content, + bool isInterfaceContent); +}; -std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent( +std::vector<std::string> TargetSourcesImpl::ConvertToAbsoluteContent( cmTarget* tgt, const std::vector<std::string>& content, bool isInterfaceContent) { @@ -120,3 +127,11 @@ std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent( return useAbsoluteContent ? absoluteContent : content; } + +} // namespace + +bool cmTargetSourcesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return TargetSourcesImpl(status).HandleArguments(args, "SOURCES"); +} diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h index 1cff8c3..5eecf34 100644 --- a/Source/cmTargetSourcesCommand.h +++ b/Source/cmTargetSourcesCommand.h @@ -8,49 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetPropCommandBase.h" - class cmExecutionStatus; -class cmTarget; - -class cmTargetSourcesCommand : public cmTargetPropCommandBase -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetSourcesCommand>(); - } - - /** - * 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; - -protected: - void HandleInterfaceContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - -private: - void HandleMissingTarget(const std::string& name) override; - - bool HandleDirectContent(cmTarget* tgt, - const std::vector<std::string>& content, - bool prepend, bool system) override; - - std::string Join(const std::vector<std::string>& content) override; - std::vector<std::string> ConvertToAbsoluteContent( - cmTarget* tgt, const std::vector<std::string>& content, - bool isInterfaceContent); -}; +bool cmTargetSourcesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index d28905a..176e790 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -4078,32 +4078,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) e2.Element("Name", name); this->WriteDotNetReferenceCustomTags(e2, name); - // If the dependency target is not managed (compiled with /clr or - // C# target) and not a WinRT component we cannot reference it and - // have to set 'ReferenceOutputAssembly' to false. - auto referenceNotManaged = - dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed; - // Workaround to check for manually set /clr flags. - if (referenceNotManaged) { - if (const auto* flags = dt->GetProperty("COMPILE_OPTIONS")) { - std::string flagsStr = flags; - if (flagsStr.find("clr") != std::string::npos) { - // There is a warning already issued when building the flags. - referenceNotManaged = false; - } - } - } - // Workaround for static library C# targets - if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) { - referenceNotManaged = !dt->IsCSharpOnly(); - } - - // Referencing WinRT components is okay. - if (referenceNotManaged) { - referenceNotManaged = !dt->GetPropertyAsBool("VS_WINRT_COMPONENT"); - } - - if (referenceNotManaged) { + // Don't reference targets that don't produce any output. + if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) { e2.Element("ReferenceOutputAssembly", "false"); e2.Element("CopyToOutputDirectory", "Never"); } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 78ae7aa..c284603 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2079,6 +2079,9 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH --build-config $<CONFIGURATION> --build-options -DCMAKE_SYSTEM_NAME=${systemName} -DCMAKE_SYSTEM_VERSION=${systemVersion} + --test-command + ${CMAKE_CMAKE_COMMAND} -DAPP_PACKAGE_DIR="${CMake_BINARY_DIR}/Tests/VSWinStorePhone/${name}" + -P "${CMake_SOURCE_DIR}/Tests/VSWinStorePhone/VerifyAppPackage.cmake" ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSWinStorePhone/${name}") endmacro() diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 52934f2..66c559d 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -4838,7 +4838,20 @@ def gen_check_targets(c, g, inSource): { "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$", "isSystem": None, - "backtrace": None, + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 10, + "command": "set_property", + "hasParent": True, + }, + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], }, { "path": "^.*/Tests/RunCMake/FileAPIExternalSource$", @@ -4862,11 +4875,37 @@ def gen_check_targets(c, g, inSource): "defines": [ { "define": "EMPTY_C=1", - "backtrace": None, + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 9, + "command": "set_property", + "hasParent": True, + }, + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], }, { "define": "SRC_DUMMY", - "backtrace": None, + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 9, + "command": "set_property", + "hasParent": True, + }, + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], }, { "define": "GENERATED_EXE=1", @@ -4903,7 +4942,25 @@ def gen_check_targets(c, g, inSource): ], }, ], - "compileCommandFragments": None, + "compileCommandFragments": [ + { + "fragment" : "SRC_COMPILE_OPTIONS_DUMMY", + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 13, + "command": "set_source_files_properties", + "hasParent": True, + }, + { + "file" : "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + } + ], }, { "language": "CXX", diff --git a/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt b/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt index f5670a7..b3ca660 100644 --- a/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt +++ b/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt @@ -10,3 +10,4 @@ set_property(SOURCE empty.c PROPERTY COMPILE_DEFINITIONS EMPTY_C=1 SRC_DUMMY) set_property(SOURCE empty.c PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}") target_include_directories(generated_exe SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") target_compile_definitions(generated_exe PRIVATE GENERATED_EXE=1 -DTGT_DUMMY) +set_source_files_properties(empty.c PROPERTIES COMPILE_OPTIONS SRC_COMPILE_OPTIONS_DUMMY) diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt index efc7760..b8e157d 100644 --- a/Tests/VSWinStorePhone/CMakeLists.txt +++ b/Tests/VSWinStorePhone/CMakeLists.txt @@ -9,6 +9,7 @@ elseif(MSVC_VERSION GREATER 1600) endif() add_subdirectory(WinRT) +add_subdirectory(CxxDLL) set (APP_MANIFEST_NAME Package.appxmanifest) if("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") @@ -151,4 +152,4 @@ if("${SHORT_VERSION}" STREQUAL "10.0") set_property(TARGET ${EXE_NAME} PROPERTY VS_SDK_REFERENCES "Microsoft.UniversalCRT.Debug, Version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") endif() -target_link_libraries(${EXE_NAME} d3d11 JusticeLeagueWinRT) +target_link_libraries(${EXE_NAME} d3d11 JusticeLeagueWinRT CxxDll) diff --git a/Tests/VSWinStorePhone/CxxDLL/CMakeLists.txt b/Tests/VSWinStorePhone/CxxDLL/CMakeLists.txt new file mode 100644 index 0000000..6bd32a2 --- /dev/null +++ b/Tests/VSWinStorePhone/CxxDLL/CMakeLists.txt @@ -0,0 +1,3 @@ +project(CxxDll CXX) + +add_library(CxxDll SHARED cxxdll.cpp) diff --git a/Tests/VSWinStorePhone/CxxDLL/cxxdll.cpp b/Tests/VSWinStorePhone/CxxDLL/cxxdll.cpp new file mode 100644 index 0000000..d82a792 --- /dev/null +++ b/Tests/VSWinStorePhone/CxxDLL/cxxdll.cpp @@ -0,0 +1,7 @@ +#include "cxxdll.h" +#include <iostream> + +void CxxDllClass::SomeMethod() +{ + std::cout << "CxxDllClass::SomeMethod\n"; +} diff --git a/Tests/VSWinStorePhone/CxxDLL/cxxdll.h b/Tests/VSWinStorePhone/CxxDLL/cxxdll.h new file mode 100644 index 0000000..86edceb --- /dev/null +++ b/Tests/VSWinStorePhone/CxxDLL/cxxdll.h @@ -0,0 +1,5 @@ +class __declspec(dllexport) CxxDllClass +{ +public: + static void SomeMethod(); +}; diff --git a/Tests/VSWinStorePhone/VerifyAppPackage.cmake b/Tests/VSWinStorePhone/VerifyAppPackage.cmake new file mode 100644 index 0000000..f9440d7 --- /dev/null +++ b/Tests/VSWinStorePhone/VerifyAppPackage.cmake @@ -0,0 +1,34 @@ +set(APP_PKG_NAME Direct3DApp1) + +# List of files that are expected to be present in the generated app package +set(EXPECTED_APP_PKG_CONTENT + ${APP_PKG_NAME}.exe + CxxDll.dll + JusticeLeagueWinRT.winmd + JusticeLeagueWinRT.dll +) + +# Windows app package formats can be either msix, appx or xap +file(GLOB_RECURSE ALL_APP_PKG_FILES ${APP_PACKAGE_DIR} ${APP_PKG_NAME}*.msix ${APP_PKG_NAME}*.appx ${APP_PKG_NAME}*.xap) + +# There can be only one generated app package +list(LENGTH ALL_APP_PKG_FILES APP_PKG_COUNT) +if(NOT APP_PKG_COUNT EQUAL 1) + message(FATAL_ERROR "Expected 1 generated app package, but detected ${APP_PKG_COUNT}: ${ALL_APP_PKG_FILES}") +endif() + +execute_process(COMMAND ${CMAKE_COMMAND} -E tar tf ${ALL_APP_PKG_FILES} + OUTPUT_VARIABLE APP_PKG_CONTENT_OUTPUT + ERROR_VARIABLE error + RESULT_VARIABLE result) + +if(NOT result EQUAL 0) + message(FATAL_ERROR "Listing app package content failed with: ${error}") +endif() + +foreach(app_pkg_item ${EXPECTED_APP_PKG_CONTENT}) + string(FIND ${APP_PKG_CONTENT_OUTPUT} ${app_pkg_item} _found) + if(_found EQUAL -1) + message(FATAL_ERROR "Generated app package is missing an expected item: ${app_pkg_item}") + endif() +endforeach() |