|
|
@@ -0,0 +1,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;
|
|
|
+}
|