diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -169,6 +169,11 @@ bool deadStrip = false; bool errorForArchMismatch = false; bool ignoreAutoLink = false; + // ld64 allows invalid auto link options as long as the link succeeds. LLD + // does not, but there are cases in the wild where the invalid linker options + // exist. This allows users to ignore the specific invalid options in the case + // they can't easily fix them. + llvm::StringSet<> ignoreAutoLinkOptions; PlatformInfo platformInfo; llvm::Optional secondaryPlatformInfo; NamespaceKind namespaceKind = NamespaceKind::twolevel; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -478,11 +478,15 @@ unsigned i = 0; StringRef arg = argv[i]; if (arg.consume_front("-l")) { + if (config->ignoreAutoLinkOptions.contains(arg)) + return; addLibrary(arg, /*isNeeded=*/false, /*isWeak=*/false, /*isReexport=*/false, /*isHidden=*/false, /*isExplicit=*/false, LoadType::LCLinkerOption); } else if (arg == "-framework") { StringRef name = argv[++i]; + if (config->ignoreAutoLinkOptions.contains(name)) + return; addFramework(name, /*isNeeded=*/false, /*isWeak=*/false, /*isReexport=*/false, /*isExplicit=*/false, LoadType::LCLinkerOption); @@ -1543,6 +1547,8 @@ getenv("LD_DYLIB_CPU_SUBTYPES_MUST_MATCH"); config->objcStubsMode = getObjCStubsMode(args); config->ignoreAutoLink = args.hasArg(OPT_ignore_auto_link); + for (const Arg *arg : args.filtered(OPT_ignore_auto_link_option)) + config->ignoreAutoLinkOptions.insert(arg->getValue()); for (const Arg *arg : args.filtered(OPT_alias)) { config->aliasedSymbols.push_back( diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -95,6 +95,12 @@ def print_symbol_order_eq: Joined<["--"], "print-symbol-order=">, HelpText<"Print a symbol order specified by --call-graph-profile-sort into the specified file">, Group; +def ignore_auto_link_option : Separate<["--"], "ignore-auto-link-option">, + Group; +def ignore_auto_link_option_eq : Joined<["--"], "ignore-auto-link-option=">, + Alias(ignore_auto_link_option)>, + HelpText<"Ignore a single auto-linked library or framework. Useful to ignore invalid options that ld64 ignores">, + Group; // This is a complete Options.td compiled from Apple's ld(1) manpage // dated 2018-03-07 and cross checked with ld64 source code in repo diff --git a/lld/test/MachO/lc-linker-option.ll b/lld/test/MachO/lc-linker-option.ll --- a/lld/test/MachO/lc-linker-option.ll +++ b/lld/test/MachO/lc-linker-option.ll @@ -13,6 +13,8 @@ ; FRAME-NEXT: name /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation ; RUN: not %lld %t/framework.o -o %t/frame_no_autolink -ignore_auto_link 2>&1 | FileCheck --check-prefix=NO_AUTOLINK %s +; RUN: not %lld %t/framework.o -o %t/frame_no_autolink --ignore-auto-link-option CoreFoundation 2>&1 | FileCheck --check-prefix=NO_AUTOLINK %s +; RUN: not %lld %t/framework.o -o %t/frame_no_autolink --ignore-auto-link-option=CoreFoundation 2>&1 | FileCheck --check-prefix=NO_AUTOLINK %s ; NO_AUTOLINK: error: undefined symbol: __CFBigNumGetInt128 ; RUN: llvm-as %t/l.ll -o %t/l.o