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