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.
100 lines
3.1 KiB
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;
|
|
}
|