diff options
Diffstat (limited to 'Source/cmFileCommand.cxx')
-rw-r--r-- | Source/cmFileCommand.cxx | 167 |
1 files changed, 138 insertions, 29 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index dc97e37..ff6e2b7 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2,23 +2,19 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileCommand.h" +#include "cm_kwiml.h" +#include "cmsys/Directory.hxx" +#include "cmsys/FStream.hxx" +#include "cmsys/Glob.hxx" +#include "cmsys/RegularExpression.hxx" +#include "cmsys/String.hxx" #include <algorithm> #include <assert.h> -#include <cm_kwiml.h> -#include <cmsys/Directory.hxx> -#include <cmsys/FStream.hxx> -#include <cmsys/Glob.hxx> -#include <cmsys/RegularExpression.hxx> -#include <cmsys/String.hxx> -#include <list> #include <sstream> #include <stdio.h> #include <stdlib.h> #include <string.h> - -#include <sys/types.h> -// include sys/stat.h after sys/types.h -#include <sys/stat.h> +#include <vector> #include "cmAlgorithms.h" #include "cmCommandArgumentsHelper.h" @@ -35,11 +31,17 @@ #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cm_auto_ptr.hxx" +#include "cm_sys_stat.h" #include "cmake.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cmCurl.h" #include "cmFileLockResult.h" +#include "cm_curl.h" +#endif + +#if defined(CMAKE_USE_ELF_PARSER) +#include "cmELF.h" #endif #if defined(_WIN32) @@ -170,6 +172,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args, if (subCommand == "RPATH_REMOVE") { return this->HandleRPathRemoveCommand(args); } + if (subCommand == "READ_ELF") { + return this->HandleReadElfCommand(args); + } if (subCommand == "RELATIVE_PATH") { return this->HandleRelativePathCommand(args); } @@ -612,8 +617,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) continue; } - else if ((c >= 0x20 && c < 0x7F) || c == '\t' || - (c == '\n' && newline_consume)) { + if ((c >= 0x20 && c < 0x7F) || c == '\t' || + (c == '\n' && newline_consume)) { // This is an ASCII character that may be part of a string. // Cast added to avoid compiler warning. Cast is ok because // c is guaranteed to fit in char by the above if... @@ -1028,8 +1033,6 @@ protected: { } }; - struct MatchRule; - friend struct MatchRule; struct MatchRule { cmsys::RegularExpression Regex; @@ -1148,6 +1151,7 @@ protected: bool UseGivenPermissionsDir; bool UseSourcePermissions; std::string Destination; + std::string FilesFromDir; std::vector<std::string> Files; int Doing; @@ -1157,6 +1161,7 @@ protected: DoingNone, DoingError, DoingDestination, + DoingFilesFromDir, DoingFiles, DoingPattern, DoingRegex, @@ -1252,6 +1257,12 @@ bool cmFileCopier::CheckKeyword(std::string const& arg) } else { this->Doing = DoingDestination; } + } else if (arg == "FILES_FROM_DIR") { + if (this->CurrentMatchRule) { + this->NotAfterMatch(arg); + } else { + this->Doing = DoingFilesFromDir; + } } else if (arg == "PATTERN") { this->Doing = DoingPattern; } else if (arg == "REGEX") { @@ -1315,13 +1326,7 @@ bool cmFileCopier::CheckValue(std::string const& arg) { switch (this->Doing) { case DoingFiles: - if (arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str())) { - this->Files.push_back(arg); - } else { - std::string file = this->Makefile->GetCurrentSourceDirectory(); - file += "/" + arg; - this->Files.push_back(file); - } + this->Files.push_back(arg); break; case DoingDestination: if (arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str())) { @@ -1332,6 +1337,16 @@ bool cmFileCopier::CheckValue(std::string const& arg) } this->Doing = DoingNone; break; + case DoingFilesFromDir: + if (cmSystemTools::FileIsFullPath(arg.c_str())) { + this->FilesFromDir = arg; + } else { + this->FilesFromDir = this->Makefile->GetCurrentSourceDirectory(); + this->FilesFromDir += "/" + arg; + } + cmSystemTools::ConvertToUnixSlashes(this->FilesFromDir); + this->Doing = DoingNone; + break; case DoingPattern: { // Convert the pattern to a regular expression. Require a // leading slash and trailing end-of-string in the matched @@ -1391,17 +1406,41 @@ bool cmFileCopier::Run(std::vector<std::string> const& args) return false; } - std::vector<std::string> const& files = this->Files; - for (std::vector<std::string>::size_type i = 0; i < files.size(); ++i) { + for (std::vector<std::string>::const_iterator i = this->Files.begin(); + i != this->Files.end(); ++i) { + std::string file; + if (!i->empty() && !cmSystemTools::FileIsFullPath(*i)) { + if (!this->FilesFromDir.empty()) { + file = this->FilesFromDir; + } else { + file = this->Makefile->GetCurrentSourceDirectory(); + } + file += "/"; + file += *i; + } else if (!this->FilesFromDir.empty()) { + this->FileCommand->SetError("option FILES_FROM_DIR requires all files " + "to be specified as relative paths."); + return false; + } else { + file = *i; + } + // Split the input file into its directory and name components. std::vector<std::string> fromPathComponents; - cmSystemTools::SplitPath(files[i], fromPathComponents); + cmSystemTools::SplitPath(file, fromPathComponents); std::string fromName = *(fromPathComponents.end() - 1); std::string fromDir = cmSystemTools::JoinPath( fromPathComponents.begin(), fromPathComponents.end() - 1); // Compute the full path to the destination file. std::string toFile = this->Destination; + if (!this->FilesFromDir.empty()) { + std::string dir = cmSystemTools::GetFilenamePath(*i); + if (!dir.empty()) { + toFile += "/"; + toFile += dir; + } + } std::string const& toName = this->ToName(fromName); if (!toName.empty()) { toFile += "/"; @@ -1486,6 +1525,9 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile) // Remove the destination file so we can always create the symlink. cmSystemTools::RemoveFile(toFile); + // Create destination directory if it doesn't exist + cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(toFile)); + // Create the symlink. if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { std::ostringstream e; @@ -1749,6 +1791,11 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) } if (!this->Rename.empty()) { + if (!this->FilesFromDir.empty()) { + this->FileCommand->SetError("INSTALL option RENAME may not be " + "combined with FILES_FROM_DIR."); + return false; + } if (this->InstallType != cmInstallType_FILES && this->InstallType != cmInstallType_PROGRAMS) { this->FileCommand->SetError("INSTALL option RENAME may be used " @@ -2181,6 +2228,68 @@ bool cmFileCommand::HandleRPathCheckCommand( return true; } +bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args) +{ + if (args.size() < 4) { + this->SetError("READ_ELF must be called with at least three additional " + "arguments."); + return false; + } + + cmCommandArgumentsHelper argHelper; + cmCommandArgumentGroup group; + + cmCAString readArg(&argHelper, "READ_ELF"); + cmCAString fileNameArg(&argHelper, CM_NULLPTR); + + cmCAString rpathArg(&argHelper, "RPATH", &group); + cmCAString runpathArg(&argHelper, "RUNPATH", &group); + cmCAString errorArg(&argHelper, "CAPTURE_ERROR", &group); + + readArg.Follows(CM_NULLPTR); + fileNameArg.Follows(&readArg); + group.Follows(&fileNameArg); + argHelper.Parse(&args, CM_NULLPTR); + + if (!cmSystemTools::FileExists(fileNameArg.GetString(), true)) { + std::ostringstream e; + e << "READ_ELF given FILE \"" << fileNameArg.GetString() + << "\" that does not exist."; + this->SetError(e.str()); + return false; + } + +#if defined(CMAKE_USE_ELF_PARSER) + cmELF elf(fileNameArg.GetCString()); + + if (!rpathArg.GetString().empty()) { + if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) { + std::string rpath(se_rpath->Value); + std::replace(rpath.begin(), rpath.end(), ':', ';'); + this->Makefile->AddDefinition(rpathArg.GetString(), rpath.c_str()); + } + } + if (!runpathArg.GetString().empty()) { + if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) { + std::string runpath(se_runpath->Value); + std::replace(runpath.begin(), runpath.end(), ':', ';'); + this->Makefile->AddDefinition(runpathArg.GetString(), runpath.c_str()); + } + } + + return true; +#else + std::string error = "ELF parser not available on this platform."; + if (errorArg.GetString().empty()) { + this->SetError(error); + return false; + } else { + this->Makefile->AddDefinition(errorArg.GetString(), error.c_str()); + return true; + } +#endif +} + bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args) { cmFileInstaller installer(this); @@ -2513,7 +2622,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) bool showProgress = false; std::string userpwd; - std::list<std::string> curl_headers; + std::vector<std::string> curl_headers; while (i != args.end()) { if (*i == "TIMEOUT") { @@ -2757,7 +2866,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } struct curl_slist* headers = CM_NULLPTR; - for (std::list<std::string>::const_iterator h = curl_headers.begin(); + for (std::vector<std::string>::const_iterator h = curl_headers.begin(); h != curl_headers.end(); ++h) { headers = ::curl_slist_append(headers, h->c_str()); } @@ -2847,7 +2956,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) bool showProgress = false; std::string userpwd; - std::list<std::string> curl_headers; + std::vector<std::string> curl_headers; while (i != args.end()) { if (*i == "TIMEOUT") { @@ -3015,7 +3124,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) } struct curl_slist* headers = CM_NULLPTR; - for (std::list<std::string>::const_iterator h = curl_headers.begin(); + for (std::vector<std::string>::const_iterator h = curl_headers.begin(); h != curl_headers.end(); ++h) { headers = ::curl_slist_append(headers, h->c_str()); } |