1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileCommand_ReadMacho.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(CMake_USE_MACH_PARSER)
# include "cmMachO.h"
#endif
#include <cmext/string_view>
bool HandleReadMachoCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
if (args.size() < 4) {
status.SetError("READ_MACHO must be called with at least three additional "
"arguments.");
return false;
}
std::string const& fileNameArg = args[1];
struct Arguments
{
std::string Architectures;
std::string Error;
};
static auto const parser =
cmArgumentParser<Arguments>{}
.Bind("ARCHITECTURES"_s, &Arguments::Architectures)
.Bind("CAPTURE_ERROR"_s, &Arguments::Error);
Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2),
/*unparsedArguments=*/nullptr);
if (!arguments.Architectures.empty()) {
// always return something sensible for ARCHITECTURES
status.GetMakefile().AddDefinition(arguments.Architectures, "unknown"_s);
}
if (!cmSystemTools::FileExists(fileNameArg, true)) {
if (arguments.Error.empty()) {
status.SetError(cmStrCat("READ_MACHO given FILE \"", fileNameArg,
"\" that does not exist."));
return false;
}
status.GetMakefile().AddDefinition(
arguments.Error, cmStrCat(fileNameArg, " does not exist"));
return true;
}
#if defined(CMake_USE_MACH_PARSER)
cmMachO macho(fileNameArg.c_str());
if (!macho) {
if (arguments.Error.empty()) {
status.SetError(cmStrCat("READ_MACHO given FILE:\n ", fileNameArg,
"\nthat is not a valid Macho-O file."));
return false;
}
status.GetMakefile().AddDefinition(
arguments.Error, cmStrCat(fileNameArg, " is not a valid Macho-O file"));
return true;
} else if (!macho.GetErrorMessage().empty()) {
if (arguments.Error.empty()) {
status.SetError(cmStrCat(
"READ_MACHO given FILE:\n ", fileNameArg,
"\nthat is not a supported Macho-O file: ", macho.GetErrorMessage()));
return false;
}
status.GetMakefile().AddDefinition(
arguments.Error,
cmStrCat(fileNameArg,
" is not a supported Macho-O file: ", macho.GetErrorMessage()));
return true;
}
std::string output;
if (!arguments.Architectures.empty()) {
auto archs = macho.GetArchitectures();
output = cmJoin(archs, ";");
// Save the output in a makefile variable.
status.GetMakefile().AddDefinition(arguments.Architectures, output);
}
#else
if (arguments.Error.empty()) {
status.SetError("READ_MACHO support not available on this platform.");
return false;
}
status.GetMakefile().AddDefinition(
arguments.Error, "READ_MACHO support not available on this platform.");
#endif // CMake_USE_MACH_PARSER
return true;
}
|