mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-11 10:26:44 +00:00
[llvm-lib] Add /WX, warn by default on empty inputs, add opt-out
lib.exe by default exits successfully without writing an output file when no inputs are passed. llvm-lib has the same behavior, for compatibility. This behavior interacts poorly with build systems: If a static library target had no inputs, llvm-lib would not produce an output file, causing ninja (or make, or a similar system) to successfully run that step, but then re-run it on the next build. After this patch, llvm-lib emits a warning in this case, that with /WX can be turned into an error. That way, ninja (or make, or...) will mark the initial build as failed. People who don't like the warning can use /ignore:emptyoutput to suppress it. The warning also points out the existing flag /llvmlibempty which forces creation of an empty .lib file (this is an extension to lib.exe). Differential Revision: https://reviews.llvm.org/D123517
This commit is contained in:
parent
76192182d0
commit
75196b99fb
@ -166,7 +166,8 @@ def force_multiple : F<"force:multiple">,
|
||||
HelpText<"Allow multiply defined symbols when creating executables">;
|
||||
def force_multipleres : F<"force:multipleres">,
|
||||
HelpText<"Allow multiply defined resources when creating executables">;
|
||||
defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
|
||||
defm WX : B<"WX", "Treat warnings as errors",
|
||||
"Don't treat warnings as errors (default)">;
|
||||
|
||||
defm allowbind : B<"allowbind", "Enable DLL binding (default)",
|
||||
"Disable DLL binding">;
|
||||
|
@ -229,10 +229,11 @@ static void appendFile(std::vector<NewArchiveMember> &Members,
|
||||
(Magic == file_magic::coff_object) ? getCOFFFileMachine(MB)
|
||||
: getBitcodeFileMachine(MB);
|
||||
if (!MaybeFileMachine) {
|
||||
handleAllErrors(MaybeFileMachine.takeError(), [&](const ErrorInfoBase &EIB) {
|
||||
llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
|
||||
<< "\n";
|
||||
});
|
||||
handleAllErrors(MaybeFileMachine.takeError(),
|
||||
[&](const ErrorInfoBase &EIB) {
|
||||
llvm::errs() << MB.getBufferIdentifier() << ": "
|
||||
<< EIB.message() << "\n";
|
||||
});
|
||||
exit(1);
|
||||
}
|
||||
COFF::MachineTypes FileMachine = *MaybeFileMachine;
|
||||
@ -291,10 +292,25 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse /ignore:
|
||||
llvm::StringSet<> IgnoredWarnings;
|
||||
for (auto *Arg : Args.filtered(OPT_ignore))
|
||||
IgnoredWarnings.insert(Arg->getValue());
|
||||
|
||||
// If no input files and not told otherwise, silently do nothing to match
|
||||
// lib.exe
|
||||
if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty))
|
||||
if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty)) {
|
||||
if (!IgnoredWarnings.contains("emptyoutput")) {
|
||||
llvm::errs() << "warning: no input files, not writing output file\n";
|
||||
llvm::errs() << " pass /llvmlibempty to write empty .lib file,\n";
|
||||
llvm::errs() << " pass /ignore:emptyoutput to suppress warning\n";
|
||||
if (Args.hasFlag(OPT_WX, OPT_WX_no, false)) {
|
||||
llvm::errs() << "treating warning as error due to /WX\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Args.hasArg(OPT_lst)) {
|
||||
doList(Args);
|
||||
|
@ -9,6 +9,14 @@ class F<string name> : Flag<["/", "-", "/?", "-?"], name>;
|
||||
class P<string name, string help> :
|
||||
Joined<["/", "-", "/?", "-?"], name#":">, HelpText<help>;
|
||||
|
||||
// Boolean flag which can be suffixed by ":no". Using it unsuffixed turns the
|
||||
// flag on and using it suffixed by ":no" turns it off.
|
||||
multiclass B<string name, string help_on, string help_off> {
|
||||
def "" : F<name>, HelpText<help_on>;
|
||||
def _no : F<name#":no">, HelpText<help_off>;
|
||||
}
|
||||
|
||||
def ignore : P<"ignore", "Specify warning codes to ignore">;
|
||||
def libpath: P<"libpath", "Object file search path">;
|
||||
|
||||
// Can't be called "list" since that's a keyword.
|
||||
@ -23,6 +31,9 @@ def llvmlibempty : F<"llvmlibempty">,
|
||||
|
||||
def machine: P<"machine", "Specify target platform">;
|
||||
|
||||
defm WX : B<"WX", "Treat warnings as errors",
|
||||
"Don't treat warnings as errors (default)">;
|
||||
|
||||
def help : F<"help">;
|
||||
|
||||
// /?? and -?? must be before /? and -? to not confuse lib/Options.
|
||||
@ -32,7 +43,4 @@ def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias<help>;
|
||||
// The flags below do nothing. They are defined only for lib.exe compatibility.
|
||||
//==============================================================================
|
||||
|
||||
class QF<string name> : Joined<["/", "-", "/?", "-?"], name#":">;
|
||||
|
||||
def ignore : QF<"ignore">;
|
||||
def nologo : F<"nologo">;
|
||||
|
@ -1,7 +1,22 @@
|
||||
RUN: rm -f %t.lib
|
||||
RUN: llvm-lib -out:%t.lib
|
||||
RUN: llvm-lib -out:%t.lib 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
|
||||
RUN: test ! -e %t.lib
|
||||
RUN: not llvm-lib -out:%t.lib /WX 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
|
||||
RUN: test ! -e %t.lib
|
||||
RUN: llvm-lib -out:%t.lib /WX /WX:no 2>&1 \
|
||||
RUN: | FileCheck --check-prefix=EMPTYWARN %s
|
||||
RUN: test ! -e %t.lib
|
||||
RUN: llvm-lib /ignore:emptyoutput -out:%t.lib 2>&1 \
|
||||
RUN: | FileCheck --check-prefix=NOEMPTYWARN --allow-empty %s
|
||||
RUN: test ! -e %t.lib
|
||||
RUN: llvm-lib /ignore:emptyoutput /WX -out:%t.lib 2>&1 \
|
||||
RUN: | FileCheck --check-prefix=NOEMPTYWARN --allow-empty %s
|
||||
RUN: test ! -e %t.lib
|
||||
|
||||
RUN: llvm-lib /llvmlibempty -out:%t.lib
|
||||
EMPTYWARN: warning: no input files, not writing output file
|
||||
NOEMPTYWARN-NOT: warning: no input files, not writing output file
|
||||
|
||||
RUN: llvm-lib /llvmlibempty -out:%t.lib 2>&1 \
|
||||
RUN: | FileCheck --check-prefix=NOEMPTYWARN --allow-empty %s
|
||||
RUN: FileCheck %s < %t.lib
|
||||
CHECK: !<arch>
|
||||
|
Loading…
x
Reference in New Issue
Block a user