Index: llvm/trunk/test/CMakeLists.txt =================================================================== --- llvm/trunk/test/CMakeLists.txt +++ llvm/trunk/test/CMakeLists.txt @@ -58,6 +58,7 @@ llvm-mc llvm-mcmarkup llvm-modextract + llvm-mt llvm-nm llvm-objdump llvm-opt-report Index: llvm/trunk/test/tools/llvm-mt/help.test =================================================================== --- llvm/trunk/test/tools/llvm-mt/help.test +++ llvm/trunk/test/tools/llvm-mt/help.test @@ -0,0 +1,7 @@ +RUN: llvm-mt /? | FileCheck %s -check-prefix=HELP + +RUN: llvm-mt /inputresource:foo.res /manifest foo.manifest | FileCheck %s -check-prefix=NOT_SUPPORTED + +HELP: OVERVIEW: Manifest Tool + +NOT_SUPPORTED: llvm-mt: ignoring unsupported 'inputresource:' option Index: llvm/trunk/tools/llvm-mt/CMakeLists.txt =================================================================== --- llvm/trunk/tools/llvm-mt/CMakeLists.txt +++ llvm/trunk/tools/llvm-mt/CMakeLists.txt @@ -0,0 +1,13 @@ +set(LLVM_LINK_COMPONENTS + Option + Support + ) + +set(LLVM_TARGET_DEFINITIONS Opts.td) + +tablegen(LLVM Opts.inc -gen-opt-parser-defs) +add_public_tablegen_target(MtTableGen) + +add_llvm_tool(llvm-mt + llvm-mt.cpp + ) Index: llvm/trunk/tools/llvm-mt/LLVMBuild.txt =================================================================== --- llvm/trunk/tools/llvm-mt/LLVMBuild.txt +++ llvm/trunk/tools/llvm-mt/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-mt/LLVMBuild.txt ---------------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = llvm-mt +parent = Tools +required_libraries = Option Support Index: llvm/trunk/tools/llvm-mt/Opts.td =================================================================== --- llvm/trunk/tools/llvm-mt/Opts.td +++ llvm/trunk/tools/llvm-mt/Opts.td @@ -0,0 +1,29 @@ +include "llvm/Option/OptParser.td" + +def unsupported : OptionGroup<"unsupported">; +def manifest : Separate<["/", "-"], "manifest">, HelpText<"Used to specify each manifest that need to be processed">, MetaVarName<"manifest">; +def identity : Joined<["/", "-"], "identity:">, HelpText<"Not supported">, MetaVarName<"identity">, Group; +def rgs : Joined<["/", "-"], "rgs:">, HelpText<"Not supported">, MetaVarName<"script">, Group; +def tlb : Joined<["/", "-"], "tlb:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def dll : Joined<["/", "-"], "dll:">, HelpText<"Not supported">, MetaVarName<"dll">, Group; +def replacements : Joined<["/", "-"], "replacements:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def managed_assembly_name : Joined<["/", "-"], "managedassemblyname:">, HelpText<"Not supported">, MetaVarName<"assembly">, Group; +def no_dependency : Flag<["/", "-"], "nodependency">, HelpText<"Not supported">, Group; +def category : Flag<["/", "-"], "category">, HelpText<"Not supported">, Group; +def no_logo : Flag<["/", "-"], "nologo">, HelpText<"No effect as this tool never writes copyright data. Included for parity">; +def out : Joined<["/", "-"], "out:">, HelpText<"Name of the output manifest. If this is skipped and only one manifest is being operated upon by the tool, that manifest is modified in place">, MetaVarName<"manifest">; +def input_resource : Joined<["/", "-"], "inputresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def output_resource : Joined<["/", "-"], "outputresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def output_resource_flag : Flag<["/", "-"], "outputresource">, Alias, HelpText<"Not supported">, Group; +def update_resource : Joined<["/", "-"], "updateresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def hash_update : Joined<["/", "-"], "hashupdate:">, HelpText<"Not supported">, MetaVarName<"file">, Group; +def hash_update_flag : Flag<["/", "-"], "hashupdate">, Alias, HelpText<"Not supported">, Group; +def validate_manifest : Flag<["/", "-"], "validate_manifest">, HelpText<"Not supported">, Group; +def validate_file_hashes : Joined<["/", "-"], "validate_file_hashes:">, HelpText<"Not supported">, MetaVarName<"">, Group; +def canonicalize : Flag<["/", "-"], "canonicalize:">, HelpText<"Not supported">, Group; +def check_for_duplicates : Flag<["/", "-"], "check_for_duplicates:">, HelpText<"Not supported">, Group; +def make_cdfs : Flag<["/", "-"], "makecdfs:">, HelpText<"Not supported">, Group; +def verbose : Flag<["/", "-"], "verbose">, HelpText<"Not supported">, Group; +def help : Flag<["/", "-"], "?">; +def help_long : Flag<["/", "-"], "help">, Alias; +def h : Flag<["/", "-"], "h">, Alias; Index: llvm/trunk/tools/llvm-mt/llvm-mt.cpp =================================================================== --- llvm/trunk/tools/llvm-mt/llvm-mt.cpp +++ llvm/trunk/tools/llvm-mt/llvm-mt.cpp @@ -0,0 +1,117 @@ +//===- llvm-mt.cpp - Merge .manifest files ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// Merge .manifest files. This is intended to be a platform-independent port +// of Microsoft's mt.exe. +// +//===---------------------------------------------------------------------===// + +#include "llvm/Option/Arg.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ManagedStatic.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 + +using namespace llvm; + +namespace { + +enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + OPT_##ID, +#include "Opts.inc" +#undef OPTION +}; + +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "Opts.inc" +#undef PREFIX + +static const opt::OptTable::Info InfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ +{ \ + PREFIX, NAME, HELPTEXT, \ + METAVAR, OPT_##ID, opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, \ + OPT_##ALIAS, ALIASARGS, VALUES}, +#include "Opts.inc" +#undef OPTION +}; + +class CvtResOptTable : public opt::OptTable { +public: + CvtResOptTable() : OptTable(InfoTable, true) {} +}; + +static ExitOnError ExitOnErr; +} // namespace + +LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) { + errs() << "llvm-mt error: " << Msg << "\n"; + exit(1); +} + +int main(int argc, const char **argv) { + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + + ExitOnErr.setBanner("llvm-mt: "); + + SmallVector argv_buf; + SpecificBumpPtrAllocator ArgAllocator; + ExitOnErr(errorCodeToError(sys::Process::GetArgumentVector( + argv_buf, makeArrayRef(argv, argc), ArgAllocator))); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + CvtResOptTable T; + unsigned MAI, MAC; + ArrayRef ArgsArr = makeArrayRef(argv + 1, argc); + opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC); + + for (auto &Arg : InputArgs) { + if (Arg->getOption().matches(OPT_unsupported)) { + outs() << "llvm-mt: ignoring unsupported '" << Arg->getOption().getName() + << "' option\n"; + } + } + + if (InputArgs.hasArg(OPT_help)) { + T.PrintHelp(outs(), "mt", "Manifest Tool", false); + return 0; + } + + std::vector InputFiles = InputArgs.getAllArgValues(OPT_manifest); + + if (InputFiles.size() == 0) { + reportError("no input file specified"); + } + + StringRef OutputFile; + + if (InputArgs.hasArg(OPT_out)) { + OutputFile = InputArgs.getLastArgValue(OPT_out); + } else if (InputFiles.size() == 1) { + OutputFile = InputFiles[0]; + } else { + reportError("no output file specified"); + } + + return 0; +}