| /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying | 
 |    file Copyright.txt or https://cmake.org/licensing for details.  */ | 
 | #include "cmTargetPrecompileHeadersCommand.h" | 
 |  | 
 | #include <utility> | 
 |  | 
 | #include "cmGeneratorExpression.h" | 
 | #include "cmList.h" | 
 | #include "cmListFileCache.h" | 
 | #include "cmMakefile.h" | 
 | #include "cmMessageType.h" | 
 | #include "cmStringAlgorithms.h" | 
 | #include "cmSystemTools.h" | 
 | #include "cmTarget.h" | 
 | #include "cmTargetPropCommandBase.h" | 
 |  | 
 | namespace { | 
 |  | 
 | std::vector<std::string> ConvertToAbsoluteContent( | 
 |   const std::vector<std::string>& content, std::string const& baseDir) | 
 | { | 
 |   std::vector<std::string> absoluteContent; | 
 |   absoluteContent.reserve(content.size()); | 
 |   for (std::string const& src : content) { | 
 |     std::string absoluteSrc; | 
 |     // Use '<foo.h>' and '"foo.h"' includes and absolute paths as-is. | 
 |     // Interpret relative paths with respect to the source directory. | 
 |     // If the path starts in a generator expression, assume it is absolute. | 
 |     if (cmHasLiteralPrefix(src, "<") || cmHasLiteralPrefix(src, "\"") || | 
 |         cmSystemTools::FileIsFullPath(src) || | 
 |         cmGeneratorExpression::Find(src) == 0) { | 
 |       absoluteSrc = src; | 
 |     } else { | 
 |       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)), | 
 |                         this->Makefile->GetBacktrace()); | 
 |     return true; | 
 |   } | 
 |  | 
 |   void HandleInterfaceContent(cmTarget* tgt, | 
 |                               const std::vector<std::string>& content, | 
 |                               bool prepend, bool system) override | 
 |   { | 
 |     std::string const& base = this->Makefile->GetCurrentSourceDirectory(); | 
 |     this->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 cmList::to_string(content); | 
 |   } | 
 | }; | 
 |  | 
 | } // namespace | 
 |  | 
 | bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args, | 
 |                                       cmExecutionStatus& status) | 
 | { | 
 |   return TargetPrecompileHeadersImpl(status).HandleArguments( | 
 |     args, "PRECOMPILE_HEADERS", | 
 |     TargetPrecompileHeadersImpl::PROCESS_REUSE_FROM); | 
 | } |