Skip to content

Commit 0ee47d9

Browse files
committedJul 25, 2017
Introduce -nostdlib++ flag to disable linking the C++ standard library.
Projects that want to statically link their own C++ standard library currently need to pass -nostdlib or -nodefaultlibs, which also disables linking of the builtins library, -lm, and so on. Alternatively, they could use `clang` instead of `clang++`, but that already disables implicit addition of -lm on some toolchains. Add a dedicated flag -nostdlib++ that disables just linking of libc++ / libstdc++. This is analogous to -nostdinc++. https://reviews.llvm.org/D35780 llvm-svn: 308997
1 parent f5ecb5e commit 0ee47d9

23 files changed

+81
-51
lines changed
 

‎clang/include/clang/Driver/Options.td

+1
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,7 @@ def nostdlibinc : Flag<["-"], "nostdlibinc">;
21442144
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
21452145
HelpText<"Disable standard #include directories for the C++ standard library">;
21462146
def nostdlib : Flag<["-"], "nostdlib">;
2147+
def nostdlibxx : Flag<["-"], "nostdlib++">;
21472148
def object : Flag<["-"], "object">;
21482149
def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
21492150
HelpText<"Write output to <file>">, MetaVarName<"<file>">;

‎clang/include/clang/Driver/ToolChain.h

+4
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ class ToolChain {
432432
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
433433
llvm::opt::ArgStringList &CC1Args) const;
434434

435+
/// Returns if the C++ standard library should be linked in.
436+
/// Note that e.g. -lm should still be linked even if this returns false.
437+
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
438+
435439
/// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
436440
/// for the given C++ standard library type.
437441
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,

‎clang/lib/Driver/ToolChain.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,16 @@ void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
648648
DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
649649
}
650650

651+
bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
652+
return getDriver().CCCIsCXX() &&
653+
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
654+
options::OPT_nostdlibxx);
655+
}
656+
651657
void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
652658
ArgStringList &CmdArgs) const {
659+
assert(!Args.hasArg(options::OPT_nostdlibxx) &&
660+
"should not have called this");
653661
CXXStdlibType Type = GetCXXStdlibType(Args);
654662

655663
switch (Type) {

‎clang/lib/Driver/ToolChains/Ananas.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,10 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9191

9292
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
9393

94-
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
95-
if (D.CCCIsCXX())
96-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
94+
if (ToolChain.ShouldLinkCXXStdlib(Args))
95+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
96+
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
9797
CmdArgs.push_back("-lc");
98-
}
9998

10099
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
101100
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));

‎clang/lib/Driver/ToolChains/BareMetal.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,9 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
192192
options::OPT_e, options::OPT_s, options::OPT_t,
193193
options::OPT_Z_Flag, options::OPT_r});
194194

195+
if (TC.ShouldLinkCXXStdlib(Args))
196+
TC.AddCXXStdlibLibArgs(Args, CmdArgs);
195197
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
196-
if (C.getDriver().CCCIsCXX())
197-
TC.AddCXXStdlibLibArgs(Args, CmdArgs);
198-
199198
CmdArgs.push_back("-lc");
200199
CmdArgs.push_back("-lm");
201200

‎clang/lib/Driver/ToolChains/CloudABI.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
8080

8181
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
8282

83+
if (ToolChain.ShouldLinkCXXStdlib(Args))
84+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
8385
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
84-
if (D.CCCIsCXX())
85-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
8686
CmdArgs.push_back("-lc");
8787
CmdArgs.push_back("-lcompiler_rt");
8888
}

‎clang/lib/Driver/ToolChains/CommonArgs.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,12 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
600600
static void addLibFuzzerRuntime(const ToolChain &TC,
601601
const ArgList &Args,
602602
ArgStringList &CmdArgs) {
603-
StringRef ParentDir = llvm::sys::path::parent_path(TC.getDriver().InstalledDir);
604-
SmallString<128> P(ParentDir);
605-
llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
606-
CmdArgs.push_back(Args.MakeArgString(P));
603+
StringRef ParentDir =
604+
llvm::sys::path::parent_path(TC.getDriver().InstalledDir);
605+
SmallString<128> P(ParentDir);
606+
llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
607+
CmdArgs.push_back(Args.MakeArgString(P));
608+
if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx))
607609
TC.AddCXXStdlibLibArgs(Args, CmdArgs);
608610
}
609611

‎clang/lib/Driver/ToolChains/CrossWindows.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ void tools::CrossWindows::Linker::ConstructJob(
160160
TC.AddFilePathLibArgs(Args, CmdArgs);
161161
AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
162162

163-
if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
164-
!Args.hasArg(options::OPT_nodefaultlibs)) {
163+
if (TC.ShouldLinkCXXStdlib(Args)) {
165164
bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
166165
!Args.hasArg(options::OPT_static);
167166
if (StaticCXX)

‎clang/lib/Driver/ToolChains/Darwin.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -549,10 +549,9 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
549549
Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism)));
550550
}
551551

552+
if (getToolChain().ShouldLinkCXXStdlib(Args))
553+
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
552554
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
553-
if (getToolChain().getDriver().CCCIsCXX())
554-
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
555-
556555
// link_ssp spec is empty.
557556

558557
// Let the tool chain choose which runtime library to link.

‎clang/lib/Driver/ToolChains/DragonFly.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
127127
}
128128

129129
if (D.CCCIsCXX()) {
130-
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
130+
if (getToolChain().ShouldLinkCXXStdlib(Args))
131+
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
131132
CmdArgs.push_back("-lm");
132133
}
133134

‎clang/lib/Driver/ToolChains/FreeBSD.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
240240
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
241241
addOpenMPRuntime(CmdArgs, ToolChain, Args);
242242
if (D.CCCIsCXX()) {
243-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
243+
if (ToolChain.ShouldLinkCXXStdlib(Args))
244+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
244245
if (Args.hasArg(options::OPT_pg))
245246
CmdArgs.push_back("-lm_p");
246247
else

‎clang/lib/Driver/ToolChains/Fuchsia.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,15 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
107107
CmdArgs.push_back("-Bdynamic");
108108

109109
if (D.CCCIsCXX()) {
110-
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
111-
!Args.hasArg(options::OPT_static);
112-
if (OnlyLibstdcxxStatic)
113-
CmdArgs.push_back("-Bstatic");
114-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
115-
if (OnlyLibstdcxxStatic)
116-
CmdArgs.push_back("-Bdynamic");
110+
if (ToolChain.ShouldLinkCXXStdlib(Args)) {
111+
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
112+
!Args.hasArg(options::OPT_static);
113+
if (OnlyLibstdcxxStatic)
114+
CmdArgs.push_back("-Bstatic");
115+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
116+
if (OnlyLibstdcxxStatic)
117+
CmdArgs.push_back("-Bdynamic");
118+
}
117119
CmdArgs.push_back("-lm");
118120
}
119121

‎clang/lib/Driver/ToolChains/Gnu.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,15 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
560560

561561
if (D.CCCIsCXX() &&
562562
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
563-
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
564-
!Args.hasArg(options::OPT_static);
565-
if (OnlyLibstdcxxStatic)
566-
CmdArgs.push_back("-Bstatic");
567-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
568-
if (OnlyLibstdcxxStatic)
569-
CmdArgs.push_back("-Bdynamic");
563+
if (ToolChain.ShouldLinkCXXStdlib(Args)) {
564+
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
565+
!Args.hasArg(options::OPT_static);
566+
if (OnlyLibstdcxxStatic)
567+
CmdArgs.push_back("-Bstatic");
568+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
569+
if (OnlyLibstdcxxStatic)
570+
CmdArgs.push_back("-Bdynamic");
571+
}
570572
CmdArgs.push_back("-lm");
571573
}
572574
// Silence warnings when linking C code with a C++ '-stdlib' argument.

‎clang/lib/Driver/ToolChains/Hexagon.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
248248
//----------------------------------------------------------------------------
249249
if (IncStdLib && IncDefLibs) {
250250
if (D.CCCIsCXX()) {
251-
HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
251+
if (HTC.ShouldLinkCXXStdlib(Args))
252+
HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
252253
CmdArgs.push_back("-lm");
253254
}
254255

‎clang/lib/Driver/ToolChains/MinGW.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
185185

186186
// TODO: Add profile stuff here
187187

188-
if (D.CCCIsCXX() &&
189-
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
188+
if (TC.ShouldLinkCXXStdlib(Args)) {
190189
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
191190
!Args.hasArg(options::OPT_static);
192191
if (OnlyLibstdcxxStatic)

‎clang/lib/Driver/ToolChains/Minix.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7272

7373
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7474
if (D.CCCIsCXX()) {
75-
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
75+
if (getToolChain().ShouldLinkCXXStdlib(Args))
76+
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
7677
CmdArgs.push_back("-lm");
7778
}
7879
}

‎clang/lib/Driver/ToolChains/NaCl.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,15 @@ void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
133133

134134
if (D.CCCIsCXX() &&
135135
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
136-
bool OnlyLibstdcxxStatic =
137-
Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
138-
if (OnlyLibstdcxxStatic)
139-
CmdArgs.push_back("-Bstatic");
140-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
141-
if (OnlyLibstdcxxStatic)
142-
CmdArgs.push_back("-Bdynamic");
136+
if (ToolChain.ShouldLinkCXXStdlib(Args)) {
137+
bool OnlyLibstdcxxStatic =
138+
Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
139+
if (OnlyLibstdcxxStatic)
140+
CmdArgs.push_back("-Bstatic");
141+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
142+
if (OnlyLibstdcxxStatic)
143+
CmdArgs.push_back("-Bdynamic");
144+
}
143145
CmdArgs.push_back("-lm");
144146
}
145147

‎clang/lib/Driver/ToolChains/NetBSD.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
278278
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
279279
addOpenMPRuntime(CmdArgs, getToolChain(), Args);
280280
if (D.CCCIsCXX()) {
281-
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
281+
if (getToolChain().ShouldLinkCXXStdlib(Args))
282+
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
282283
CmdArgs.push_back("-lm");
283284
}
284285
if (NeedsSanitizerDeps)

‎clang/lib/Driver/ToolChains/OpenBSD.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
177177

178178
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
179179
if (D.CCCIsCXX()) {
180-
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
180+
if (getToolChain().ShouldLinkCXXStdlib(Args))
181+
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
181182
if (Args.hasArg(options::OPT_pg))
182183
CmdArgs.push_back("-lm_p");
183184
else

‎clang/lib/Driver/ToolChains/PS4CPU.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
227227
// libraries for both C and C++ compilations.
228228
CmdArgs.push_back("-lkernel");
229229
if (D.CCCIsCXX()) {
230-
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
230+
if (ToolChain.ShouldLinkCXXStdlib(Args))
231+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
231232
if (Args.hasArg(options::OPT_pg))
232233
CmdArgs.push_back("-lm_p");
233234
else

‎clang/lib/Driver/ToolChains/Solaris.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
100100
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
101101

102102
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
103-
if (getToolChain().getDriver().CCCIsCXX())
103+
if (getToolChain().ShouldLinkCXXStdlib(Args))
104104
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
105105
CmdArgs.push_back("-lgcc_s");
106106
CmdArgs.push_back("-lc");

‎clang/lib/Driver/ToolChains/WebAssembly.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
3838
const char *LinkingOutput) const {
3939

4040
const ToolChain &ToolChain = getToolChain();
41-
const Driver &D = ToolChain.getDriver();
4241
const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
4342
ArgStringList CmdArgs;
4443
CmdArgs.push_back("-flavor");
@@ -77,7 +76,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7776
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
7877

7978
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
80-
if (D.CCCIsCXX())
79+
if (ToolChain.ShouldLinkCXXStdlib(Args))
8180
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
8281

8382
if (Args.hasArg(options::OPT_pthread))

‎clang/test/Driver/nostdlibxx.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clangxx -target i686-pc-linux-gnu -### -nostdlib++ %s 2> %t
2+
// RUN: FileCheck < %t %s
3+
4+
// We should still have -lm and the C standard libraries, but not -lstdc++.
5+
6+
// CHECK-NOT: -lstdc++
7+
// CHECK-NOT: -lc++
8+
// CHECK: -lm

0 commit comments

Comments
 (0)
Please sign in to comment.