[lld] 75196b9 - [llvm-lib] Add /WX, warn by default on empty inputs, add opt-out

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 10:15:43 PDT 2022


Author: Nico Weber
Date: 2022-04-11T13:15:30-04:00
New Revision: 75196b99fbd3397ccb7960b6e7ad7c40efef2315

URL: https://github.com/llvm/llvm-project/commit/75196b99fbd3397ccb7960b6e7ad7c40efef2315
DIFF: https://github.com/llvm/llvm-project/commit/75196b99fbd3397ccb7960b6e7ad7c40efef2315.diff

LOG: [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

Added: 
    

Modified: 
    lld/COFF/Options.td
    llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
    llvm/lib/ToolDrivers/llvm-lib/Options.td
    llvm/test/tools/llvm-lib/no-inputs.test

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 7593b99dc05a7..331da34a7a90f 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -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">;

diff  --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 8f69282d3443c..7ecde3ce284ad 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -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);

diff  --git a/llvm/lib/ToolDrivers/llvm-lib/Options.td b/llvm/lib/ToolDrivers/llvm-lib/Options.td
index 5891e238a328d..7d9668396e4b5 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/Options.td
+++ b/llvm/lib/ToolDrivers/llvm-lib/Options.td
@@ -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">;

diff  --git a/llvm/test/tools/llvm-lib/no-inputs.test b/llvm/test/tools/llvm-lib/no-inputs.test
index 22e096f78ce07..26fcf08710b57 100644
--- a/llvm/test/tools/llvm-lib/no-inputs.test
+++ b/llvm/test/tools/llvm-lib/no-inputs.test
@@ -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
+
+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
+RUN: llvm-lib /llvmlibempty -out:%t.lib 2>&1 \
+RUN:     | FileCheck --check-prefix=NOEMPTYWARN --allow-empty %s
 RUN: FileCheck %s < %t.lib
 CHECK: !<arch>


        


More information about the llvm-commits mailing list