diff --git a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst --- a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst +++ b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst @@ -68,6 +68,10 @@ Do not warn about files that have no symbols. +.. option:: -warnings_as_errors: + + Produce a non-zero exit status if any warnings are emitted. + .. option:: -o Specify the output file name. Must be specified exactly once. diff --git a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test --- a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test +++ b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test @@ -58,6 +58,14 @@ # DUPLICATE-INPUT-DAG: [[INPUTA]] # DUPLICATE-INPUT-DAG: [[INPUTB]] +# RUN: not llvm-libtool-darwin -warnings_as_errors -static -o %t.lib %t-input1.o %t-input2.o %t-input1.o 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERROR-DUPLICATE-INPUT -DFILE=%basename_t.tmp-input1.o \ +# RUN: -DINPUTA=%t-input1.o -DINPUTB=%t-input1.o + +# ERROR-DUPLICATE-INPUT: error: file '[[FILE]]' was specified multiple times. +# ERROR-DUPLICATE-INPUT-DAG: [[INPUTA]] +# ERROR-DUPLICATE-INPUT-DAG: [[INPUTB]] + ## Make sure we can combine object files with the same name if ## they are for different architectures. # RUN: mkdir -p %t/arm64 %t/armv7 diff --git a/llvm/test/tools/llvm-libtool-darwin/no-symbols-warning.test b/llvm/test/tools/llvm-libtool-darwin/no-symbols-warning.test --- a/llvm/test/tools/llvm-libtool-darwin/no-symbols-warning.test +++ b/llvm/test/tools/llvm-libtool-darwin/no-symbols-warning.test @@ -11,6 +11,11 @@ # WARNING: warning: '[[PREFIX]]-x86_64-empty.o': has no symbols for architecture x86_64 +# RUN: not llvm-libtool-darwin -static -warnings_as_errors -o %t-error.lib %t-x86_64-empty.o 2>&1 | \ +# RUN: FileCheck --check-prefix=ERROR %s -DPREFIX=%basename_t.tmp + +# ERROR: error: '[[PREFIX]]-x86_64-empty.o': has no symbols for architecture x86_64 + # RUN: llvm-libtool-darwin -no_warning_for_no_symbols -static -o %t.lib \ # RUN: %t-x86_64-empty.o 2>&1 | \ # RUN: FileCheck %s --allow-empty --implicit-check-not='warning:' diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -98,6 +98,11 @@ cl::desc("Do not warn about files that have no symbols"), cl::cat(LibtoolCategory), cl::init(false)); +static cl::opt WarningsAsErrors("warnings_as_errors", + cl::desc("Treat warnings as errors"), + cl::cat(LibtoolCategory), + cl::init(false)); + static const std::array StandardSearchDirs{ "/lib", "/usr/lib", @@ -370,10 +375,17 @@ return Error::success(); } - if (!NoWarningForNoSymbols && O->symbols().empty()) - WithColor::warning() << "'" + Member.MemberName + - "': has no symbols for architecture " + - O->getArchTriple().getArchName() + "\n"; + if (!NoWarningForNoSymbols && O->symbols().empty()) { + Error E = createFileError( + Member.MemberName, + createStringError(std::errc::invalid_argument, + "has no symbols for architecture %s", + O->getArchTriple().getArchName().str().c_str())); + + if (WarningsAsErrors) + return E; + WithColor::defaultWarningHandler(std::move(E)); + } uint64_t FileCPUID = getCPUID(FileCPUType, FileCPUSubtype); Builder.Data.MembersPerArchitecture[FileCPUID].push_back( @@ -581,8 +593,11 @@ const auto &NewMembers = DataOrError->MembersPerArchitecture; - if (Error E = checkForDuplicates(NewMembers)) + if (Error E = checkForDuplicates(NewMembers)) { + if (WarningsAsErrors) + return E; WithColor::defaultWarningHandler(std::move(E)); + } if (NewMembers.size() == 1) return writeArchive(OutputFile, NewMembers.begin()->second.getMembers(),