summaryrefslogtreecommitdiff
path: root/tools/llvm-mt/llvm-mt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-mt/llvm-mt.cpp')
-rw-r--r--tools/llvm-mt/llvm-mt.cpp46
1 files changed, 44 insertions, 2 deletions
diff --git a/tools/llvm-mt/llvm-mt.cpp b/tools/llvm-mt/llvm-mt.cpp
index 05c9238c7c64..944af22cf9c8 100644
--- a/tools/llvm-mt/llvm-mt.cpp
+++ b/tools/llvm-mt/llvm-mt.cpp
@@ -16,12 +16,15 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/WindowsManifest/WindowsManifestMerger.h"
#include <system_error>
@@ -67,6 +70,22 @@ LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
exit(1);
}
+static void reportError(StringRef Input, std::error_code EC) {
+ reportError(Twine(Input) + ": " + EC.message());
+}
+
+void error(std::error_code EC) {
+ if (EC)
+ reportError(EC.message());
+}
+
+void error(Error EC) {
+ if (EC)
+ handleAllErrors(std::move(EC), [&](const ErrorInfoBase &EI) {
+ reportError(EI.message());
+ });
+}
+
int main(int argc, const char **argv) {
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
@@ -77,7 +96,6 @@ int main(int argc, const char **argv) {
SpecificBumpPtrAllocator<char> ArgAllocator;
ExitOnErr(errorCodeToError(sys::Process::GetArgumentVector(
argv_buf, makeArrayRef(argv, argc), ArgAllocator)));
-
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
CvtResOptTable T;
@@ -85,6 +103,9 @@ int main(int argc, const char **argv) {
ArrayRef<const char *> ArgsArr = makeArrayRef(argv + 1, argc);
opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC);
+ for (auto *Arg : InputArgs.filtered(OPT_INPUT))
+ reportError(Twine("invalid option ") + Arg->getSpelling());
+
for (auto &Arg : InputArgs) {
if (Arg->getOption().matches(OPT_unsupported)) {
outs() << "llvm-mt: ignoring unsupported '" << Arg->getOption().getName()
@@ -104,7 +125,6 @@ int main(int argc, const char **argv) {
}
StringRef OutputFile;
-
if (InputArgs.hasArg(OPT_out)) {
OutputFile = InputArgs.getLastArgValue(OPT_out);
} else if (InputFiles.size() == 1) {
@@ -113,5 +133,27 @@ int main(int argc, const char **argv) {
reportError("no output file specified");
}
+ windows_manifest::WindowsManifestMerger Merger;
+
+ for (const auto &File : InputFiles) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> ManifestOrErr =
+ MemoryBuffer::getFile(File);
+ if (!ManifestOrErr)
+ reportError(File, ManifestOrErr.getError());
+ MemoryBuffer &Manifest = *ManifestOrErr.get();
+ error(Merger.merge(Manifest));
+ }
+
+ std::unique_ptr<MemoryBuffer> OutputBuffer = Merger.getMergedManifest();
+ if (!OutputBuffer)
+ reportError("empty manifest not written");
+ Expected<std::unique_ptr<FileOutputBuffer>> FileOrErr =
+ FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize());
+ if (!FileOrErr)
+ reportError(OutputFile, errorToErrorCode(FileOrErr.takeError()));
+ std::unique_ptr<FileOutputBuffer> FileBuffer = std::move(*FileOrErr);
+ std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(),
+ FileBuffer->getBufferStart());
+ error(FileBuffer->commit());
return 0;
}