| /* 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; |
| } |