1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
4 #include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h"
8 #include <cmsys/RegularExpression.hxx>
10 #include "cmRuntimeDependencyArchive.h"
11 #include "cmUVProcessChain.h"
13 cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::
14 cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool(
15 cmRuntimeDependencyArchive* archive)
16 : cmBinUtilsMacOSMachOGetRuntimeDependenciesTool(archive)
20 bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
21 std::string const& file, std::vector<std::string>& libs,
22 std::vector<std::string>& rpaths)
24 std::vector<std::string> command;
25 if (!this->Archive->GetGetRuntimeDependenciesCommand("otool", command)) {
26 this->SetError("Could not find otool");
29 command.emplace_back("-l");
30 command.emplace_back(file);
32 cmUVProcessChainBuilder builder;
33 builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
36 auto process = builder.Start();
37 if (!process.Valid()) {
39 e << "Failed to start otool process for:\n " << file;
40 this->SetError(e.str());
45 static const cmsys::RegularExpression rpathRegex("^ *cmd LC_RPATH$");
46 static const cmsys::RegularExpression loadDylibRegex(
47 "^ *cmd LC_LOAD_DYLIB$");
48 static const cmsys::RegularExpression pathRegex(
49 "^ *path (.*) \\(offset [0-9]+\\)$");
50 static const cmsys::RegularExpression nameRegex(
51 "^ *name (.*) \\(offset [0-9]+\\)$");
52 while (std::getline(*process.OutputStream(), line)) {
53 cmsys::RegularExpressionMatch cmdMatch;
54 if (rpathRegex.find(line.c_str(), cmdMatch)) {
55 if (!std::getline(*process.OutputStream(), line) ||
56 !std::getline(*process.OutputStream(), line)) {
57 this->SetError("Invalid output from otool");
61 cmsys::RegularExpressionMatch pathMatch;
62 if (pathRegex.find(line.c_str(), pathMatch)) {
63 rpaths.push_back(pathMatch.match(1));
65 this->SetError("Invalid output from otool");
68 } else if (loadDylibRegex.find(line.c_str(), cmdMatch)) {
69 if (!std::getline(*process.OutputStream(), line) ||
70 !std::getline(*process.OutputStream(), line)) {
71 this->SetError("Invalid output from otool");
75 cmsys::RegularExpressionMatch nameMatch;
76 if (nameRegex.find(line.c_str(), nameMatch)) {
77 libs.push_back(nameMatch.match(1));
79 this->SetError("Invalid output from otool");
85 if (!process.Wait()) {
87 e << "Failed to wait on otool process for:\n " << file;
88 this->SetError(e.str());
91 auto status = process.GetStatus();
92 if (!status[0] || status[0]->ExitStatus != 0) {
94 e << "Failed to run otool on:\n " << file;
95 this->SetError(e.str());