resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3
4 #include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
5
6 #include <sstream>
7
8 #include <cmsys/RegularExpression.hxx>
9
10 #include "cmRuntimeDependencyArchive.h"
11 #include "cmSystemTools.h"
12 #include "cmUVProcessChain.h"
13
14 cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::
15   cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool(
16     cmRuntimeDependencyArchive* archive)
17   : cmBinUtilsLinuxELFGetRuntimeDependenciesTool(archive)
18 {
19 }
20
21 bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
22   std::string const& file, std::vector<std::string>& needed,
23   std::vector<std::string>& rpaths, std::vector<std::string>& runpaths)
24 {
25   cmUVProcessChainBuilder builder;
26   builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
27
28   std::vector<std::string> command;
29   if (!this->Archive->GetGetRuntimeDependenciesCommand("objdump", command)) {
30     this->SetError("Could not find objdump");
31     return false;
32   }
33   command.emplace_back("-p");
34   command.push_back(file);
35   builder.AddCommand(command);
36
37   auto process = builder.Start();
38   if (!process.Valid()) {
39     std::ostringstream e;
40     e << "Failed to start objdump process for:\n  " << file;
41     this->SetError(e.str());
42     return false;
43   }
44
45   std::string line;
46   static const cmsys::RegularExpression neededRegex("^ *NEEDED *([^\n]*)$");
47   static const cmsys::RegularExpression rpathRegex("^ *RPATH *([^\n]*)$");
48   static const cmsys::RegularExpression runpathRegex("^ *RUNPATH *([^\n]*)$");
49   while (std::getline(*process.OutputStream(), line)) {
50     cmsys::RegularExpressionMatch match;
51     if (neededRegex.find(line.c_str(), match)) {
52       needed.push_back(match.match(1));
53     } else if (rpathRegex.find(line.c_str(), match)) {
54       std::vector<std::string> rpathSplit =
55         cmSystemTools::SplitString(match.match(1), ':');
56       rpaths.reserve(rpaths.size() + rpathSplit.size());
57       for (auto const& rpath : rpathSplit) {
58         rpaths.push_back(rpath);
59       }
60     } else if (runpathRegex.find(line.c_str(), match)) {
61       std::vector<std::string> runpathSplit =
62         cmSystemTools::SplitString(match.match(1), ':');
63       runpaths.reserve(runpaths.size() + runpathSplit.size());
64       for (auto const& runpath : runpathSplit) {
65         runpaths.push_back(runpath);
66       }
67     }
68   }
69
70   if (!process.Wait()) {
71     std::ostringstream e;
72     e << "Failed to wait on objdump process for:\n  " << file;
73     this->SetError(e.str());
74     return false;
75   }
76   auto status = process.GetStatus();
77   if (!status[0] || status[0]->ExitStatus != 0) {
78     std::ostringstream e;
79     e << "Failed to run objdump on:\n  " << file;
80     this->SetError(e.str());
81     return false;
82   }
83
84   return true;
85 }