You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cmake/Source/cmFileCommand_ReadMacho.cxx

100 lines
3.1 KiB

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