Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2491,6 +2491,7 @@ def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, HelpText<"Support POSIX threads in generated code">; def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; +def lpthread : Flag<["-"], "lpthread">; def p : Flag<["-"], "p">; def pie : Flag<["-"], "pie">; def read__only__relocs : Separate<["-"], "read_only_relocs">; @@ -2602,6 +2603,8 @@ def weak__library : Separate<["-"], "weak_library">, Flags<[LinkerInput]>; def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">; def whatsloaded : Flag<["-"], "whatsloaded">; +def whole_archive : Flag<["--"], "whole-archive">, Group; +def no_whole_archive : Flag<["--"], "no-whole-archive">, Group; def whyload : Flag<["-"], "whyload">; def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>; def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>, Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -501,6 +501,7 @@ bool WantPthread = Args.hasArg(options::OPT_pthread) || Args.hasArg(options::OPT_pthreads); + bool WantLPthread = Args.hasArg(options::OPT_lpthread); // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that // require librt. Most modern Linux platforms do, but some may not. @@ -513,8 +514,35 @@ AddRunTimeLibs(ToolChain, D, CmdArgs, Args); - if (WantPthread && !isAndroid) - CmdArgs.push_back("-lpthread"); + if ((WantPthread || WantLPthread) && !isAndroid) { + if (Triple.isMIPS() && Args.hasArg(options::OPT_static)) { + // When -pthread option is used in combination with -static, + // we want to avoid problems which weak symbols may cause, + // and therefore we include whole lpthread library + bool wholeArchiveFlag = false; + bool lpthreadAsWholeArchive = false; + for (Arg *A : Args) { + if (A->getOption().matches(options::OPT_whole_archive)) + wholeArchiveFlag = true; + if (A->getOption().matches(options::OPT_no_whole_archive)) + wholeArchiveFlag = false; + if (wholeArchiveFlag) { + if (A->getOption().matches(options::OPT_lpthread)) { + lpthreadAsWholeArchive = true; + break; + } + } + } + + if (!lpthreadAsWholeArchive) { + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("--no-whole-archive"); + } + } else { + CmdArgs.push_back("-lpthread"); + } + } if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("--wrap=pthread_create");