Skip to content

Commit 9b7cfd3

Browse files
committed
auto merge of #13513 : alexcrichton/rust/up-llvm, r=brson
This is a bit of an interesting upgrade to LLVM. Upstream LLVM has started using C++11 features, so they require a C++11 compiler to build. I've updated all the bots to have a C++11 compiler, and they appear to be building LLVM successfully: * Linux bots - I added gcc/g++ 4.7 (good enough) * Android bots - same as the linux ones * Mac bots - I installed the most recent command line tools for Lion which gives us clang 3.2, but LLVM wouldn't build unless it was explicitly asked to link to `libc++` instead of `libstdc++`. This involved tweaking `mklldeps.py` and the `configure` script to get things to work out * Windows bots - mingw-w64 has gcc 4.8.1 which is sufficient for building LLVM (hurray!) * BSD bots - I updated FreeBSD to 10.0 which brought with it a relevant version of clang. The largest fallout I've seen so far is that the test suite doesn't work at all on FreeBSD 10. We've already stopped gating on FreeBSD due to #13427 (we used to be on freebsd 9), so I don't think this puts us in too bad of a situation. I will continue to attempt to fix FreeBSD and the breakage on there. The LLVM update brings with it all of the recently upstreamed LLVM patches. We only have one local patch now which is just an optimization, and isn't required to use upstream LLVM. I want to maintain compatibility with LLVM 3.3 and 3.4 while we can, and this upgrade is keeping us up to date with the 3.5 release. Once 3.5 is release we will in theory no longer require a bundled LLVM.
2 parents b75683c + 426d701 commit 9b7cfd3

17 files changed

+199
-83
lines changed

configure

+28-23
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
388388
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
389389
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)"
390390
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
391+
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
391392
opt rpath 1 "build rpaths into rustc itself"
392393
opt nightly 0 "build nightly packages"
393394
opt verify-install 1 "verify installed binaries work"
@@ -579,26 +580,32 @@ then
579580
CFG_ENABLE_CLANG=1
580581
putvar CFG_ENABLE_CLANG
581582
else
582-
# on OS X, with xcode 5 and newer, certain developers may have
583-
# cc, gcc and g++ point to a mixture of clang and gcc
584-
# if so, this will create very strange build errors
585-
# this last stanza is to detect some such problems and save the future rust
586-
# contributor some time solving that issue.
587-
# this detection could be generalized to other OSes aside from OS X
588-
# but the issue seems most likely to happen on OS X
589-
590-
chk_cc () {
591-
$1 --version 2> /dev/null | grep -q $2
592-
}
593-
# check that gcc, cc and g++ all point to the same compiler.
594-
# note that for xcode 5, g++ points to clang, not clang++
595-
if !((chk_cc gcc clang && chk_cc g++ clang) ||
596-
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))) then
597-
err "the gcc and g++ in your path point to different compilers.
598-
Check which versions are in your path with cc --version and g++ --version.
599-
To resolve this problem, either fix your PATH or run configure with --enable-clang"
600-
fi
583+
if [ $("$CFG_GCC" --version 2>&1 | grep -c ' 4\.[0-6]') -ne 0 ]; then
584+
step_msg "older GCC found, using clang instead"
585+
CFG_ENABLE_CLANG=1
586+
putvar CFG_ENABLE_CLANG
587+
else
588+
# on OS X, with xcode 5 and newer, certain developers may have
589+
# cc, gcc and g++ point to a mixture of clang and gcc
590+
# if so, this will create very strange build errors
591+
# this last stanza is to detect some such problems and save the future rust
592+
# contributor some time solving that issue.
593+
# this detection could be generalized to other OSes aside from OS X
594+
# but the issue seems most likely to happen on OS X
595+
596+
chk_cc () {
597+
$1 --version 2> /dev/null | grep -q $2
598+
}
599+
# check that gcc, cc and g++ all point to the same compiler.
600+
# note that for xcode 5, g++ points to clang, not clang++
601+
if !((chk_cc gcc clang && chk_cc g++ clang) ||
602+
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))) then
603+
err "the gcc and g++ in your path point to different compilers.
604+
Check which versions are in your path with cc --version and g++ --version.
605+
To resolve this problem, either fix your PATH or run configure with --enable-clang"
606+
fi
601607

608+
fi
602609
fi
603610
fi
604611

@@ -921,10 +928,6 @@ do
921928
LLVM_OPTS="$LLVM_OPTS --disable-terminfo"
922929
# Try to have LLVM pull in as few dependencies as possible (#9397)
923930
LLVM_OPTS="$LLVM_OPTS --disable-zlib --disable-libffi"
924-
# LLVM says it needs a "new" clang/gcc, but we seem to get by ok with
925-
# older versions on the bots. Get by for a little longer by asking it to
926-
# not do version detection
927-
LLVM_OPTS="$LLVM_OPTS --disable-compiler-version-checks"
928931

929932
# Use win32 native thread/lock apis instead of pthread wrapper.
930933
# (llvm's configure tries to find pthread first, so we have to disable it explicitly.)
@@ -942,13 +945,15 @@ do
942945

943946
LLVM_CXX_64="ccache clang++ -Qunused-arguments"
944947
LLVM_CC_64="ccache clang -Qunused-arguments"
948+
LLVM_OPTS="$LLVM_OPTS --enable-libcpp"
945949
;;
946950
("clang")
947951
LLVM_CXX_32="clang++ -m32 -Qunused-arguments"
948952
LLVM_CC_32="clang -m32 -Qunused-arguments"
949953

950954
LLVM_CXX_64="clang++ -Qunused-arguments"
951955
LLVM_CC_64="clang -Qunused-arguments"
956+
LLVM_OPTS="$LLVM_OPTS --enable-libcpp"
952957
;;
953958
("ccache gcc")
954959
LLVM_CXX_32="ccache g++ -m32"

mk/llvm.mk

+13-4
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,25 @@ $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
4242
@$$(call E, make: done cleaning llvm)
4343
touch $$@
4444

45+
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
46+
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
47+
-print-file-name=libstdc++.a)
48+
else
49+
LLVM_STDCPP_LOCATION_$(1) =
50+
endif
51+
4552
endef
4653

4754
$(foreach host,$(CFG_HOST), \
48-
$(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host))))
55+
$(eval $(call DEF_LLVM_RULES,$(host))))
4956

5057
$(foreach host,$(CFG_HOST), \
51-
$(eval $(call DEF_LLVM_RULES,$(host))))
58+
$(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host))))
5259

5360
$(S)src/librustc/lib/llvmdeps.rs: \
5461
$(LLVM_CONFIGS) \
55-
$(S)src/etc/mklldeps.py
62+
$(S)src/etc/mklldeps.py \
63+
$(MKFILE_DEPS)
5664
$(Q)$(CFG_PYTHON) $(S)src/etc/mklldeps.py \
57-
"$@" "$(LLVM_COMPONENTS)" $(LLVM_CONFIGS)
65+
"$@" "$(LLVM_COMPONENTS)" "$(CFG_ENABLE_LLVM_STATIC_STDCPP)" \
66+
$(LLVM_CONFIGS)

mk/target.mk

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
8383
$$(WFLAGS_ST$(1)) \
8484
-L "$$(RT_OUTPUT_DIR_$(2))" \
8585
-L "$$(LLVM_LIBDIR_$(2))" \
86+
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
8687
--out-dir $$(@D) $$<
8788
@touch $$@
8889
$$(call LIST_ALL_OLD_GLOB_MATCHES,\

src/etc/mklldeps.py

+46-25
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
import os
1212
import sys
1313
import subprocess
14+
import itertools
15+
from os import path
1416

1517
f = open(sys.argv[1], 'wb')
1618

1719
components = sys.argv[2].split(' ')
1820
components = [i for i in components if i] # ignore extra whitespaces
21+
enable_static = sys.argv[3]
1922

2023
f.write("""// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2124
// file at the top-level directory of this distribution and at
@@ -31,11 +34,20 @@
3134
// take a look at src/etc/mklldeps.py if you're interested
3235
""")
3336

34-
for llconfig in sys.argv[3:]:
37+
def run(args):
38+
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
39+
out, err = proc.communicate()
40+
41+
if err:
42+
print("failed to run llconfig: args = `{}`".format(args))
43+
print(err)
44+
sys.exit(1)
45+
return out
46+
47+
for llconfig in sys.argv[4:]:
3548
f.write("\n")
3649

37-
proc = subprocess.Popen([llconfig, '--host-target'], stdout = subprocess.PIPE)
38-
out, err = proc.communicate()
50+
out = run([llconfig, '--host-target'])
3951
arch, os = out.split('-', 1)
4052
arch = 'x86' if arch == 'i686' or arch == 'i386' else arch
4153
if 'darwin' in os:
@@ -55,35 +67,44 @@
5567

5668
f.write("#[cfg(" + ', '.join(cfg) + ")]\n")
5769

70+
version = run([llconfig, '--version']).strip()
71+
5872
# LLVM libs
59-
args = [llconfig, '--libs']
73+
if version < '3.5':
74+
args = [llconfig, '--libs']
75+
else:
76+
args = [llconfig, '--libs', '--system-libs']
6077
args.extend(components)
61-
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
62-
out, err = proc.communicate()
63-
64-
if err:
65-
print("failed to run llconfig: args = `{}`".format(args))
66-
sys.exit(1)
78+
out = run(args)
79+
for lib in out.strip().replace("\n", ' ').split(' '):
80+
lib = lib.strip()[2:] # chop of the leading '-l'
81+
f.write("#[link(name = \"" + lib + "\"")
82+
# LLVM libraries are all static libraries
83+
if 'LLVM' in lib:
84+
f.write(", kind = \"static\"")
85+
f.write(")]\n")
6786

68-
for lib in out.strip().split(' '):
69-
lib = lib[2:] # chop of the leading '-l'
70-
f.write("#[link(name = \"" + lib + "\", kind = \"static\")]\n")
87+
# llvm-config before 3.5 didn't have a system-libs flag
88+
if version < '3.5':
89+
if os == 'win32':
90+
f.write("#[link(name = \"imagehlp\")]")
7191

7292
# LLVM ldflags
73-
args = [llconfig, '--ldflags']
74-
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
75-
out, err = proc.communicate()
76-
77-
if err:
78-
print("failed to run llconfig: args = `{}`".format(args))
79-
sys.exit(1)
80-
93+
out = run([llconfig, '--ldflags'])
8194
for lib in out.strip().split(' '):
8295
if lib[:2] == "-l":
8396
f.write("#[link(name = \"" + lib[2:] + "\")]\n")
8497

85-
#extra
86-
f.write("#[link(name = \"stdc++\")]\n")
87-
if os == 'win32':
88-
f.write("#[link(name = \"imagehlp\")]\n")
98+
# C++ runtime library
99+
out = run([llconfig, '--cxxflags'])
100+
if enable_static == '1':
101+
assert('stdlib=libc++' not in out)
102+
f.write("#[link(name = \"stdc++\", kind = \"static\")]\n")
103+
else:
104+
if 'stdlib=libc++' in out:
105+
f.write("#[link(name = \"c++\")]\n")
106+
else:
107+
f.write("#[link(name = \"stdc++\")]\n")
108+
109+
# Attach everything to an extern block
89110
f.write("extern {}\n")

src/librustc/back/link.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1298,9 +1298,22 @@ fn add_local_native_libraries(args: &mut Vec<~str>, sess: &Session) {
12981298
args.push("-L" + path.as_str().unwrap().to_owned());
12991299
}
13001300

1301+
// Some platforms take hints about whether a library is static or dynamic.
1302+
// For those that support this, we ensure we pass the option if the library
1303+
// was flagged "static" (most defaults are dynamic) to ensure that if
1304+
// libfoo.a and libfoo.so both exist that the right one is chosen.
1305+
let takes_hints = sess.targ_cfg.os != abi::OsMacos;
1306+
13011307
for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
13021308
match kind {
13031309
cstore::NativeUnknown | cstore::NativeStatic => {
1310+
if takes_hints {
1311+
if kind == cstore::NativeStatic {
1312+
args.push("-Wl,-Bstatic".to_owned());
1313+
} else {
1314+
args.push("-Wl,-Bdynamic".to_owned());
1315+
}
1316+
}
13041317
args.push("-l" + *l);
13051318
}
13061319
cstore::NativeFramework => {
@@ -1309,6 +1322,9 @@ fn add_local_native_libraries(args: &mut Vec<~str>, sess: &Session) {
13091322
}
13101323
}
13111324
}
1325+
if takes_hints {
1326+
args.push("-Wl,-Bdynamic".to_owned());
1327+
}
13121328
}
13131329

13141330
// # Rust Crate linking

src/librustc/lib/llvm.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,8 @@ pub mod llvm {
12611261
LHS: ValueRef,
12621262
CMP: ValueRef,
12631263
RHS: ValueRef,
1264-
Order: AtomicOrdering)
1264+
Order: AtomicOrdering,
1265+
FailureOrder: AtomicOrdering)
12651266
-> ValueRef;
12661267
pub fn LLVMBuildAtomicRMW(B: BuilderRef,
12671268
Op: AtomicBinOp,
@@ -1586,7 +1587,8 @@ pub mod llvm {
15861587
Scope: DIDescriptor,
15871588
File: DIFile,
15881589
Line: c_uint,
1589-
Col: c_uint)
1590+
Col: c_uint,
1591+
Discriminator: c_uint)
15901592
-> DILexicalBlock;
15911593

15921594
pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,

src/librustc/middle/trans/base.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,8 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
445445
}
446446

447447
// Add the no-split-stack attribute if requested
448-
if contains_name(attrs, "no_split_stack") {
449-
set_no_split_stack(llfn);
448+
if !contains_name(attrs, "no_split_stack") {
449+
set_split_stack(llfn);
450450
}
451451

452452
if contains_name(attrs, "cold") {
@@ -458,8 +458,8 @@ pub fn set_always_inline(f: ValueRef) {
458458
lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
459459
}
460460

461-
pub fn set_no_split_stack(f: ValueRef) {
462-
"no-split-stack".with_c_str(|buf| {
461+
pub fn set_split_stack(f: ValueRef) {
462+
"split-stack".with_c_str(|buf| {
463463
unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
464464
})
465465
}

src/librustc/middle/trans/build.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,9 @@ pub fn Resume(cx: &Block, exn: ValueRef) -> ValueRef {
814814
// Atomic Operations
815815
pub fn AtomicCmpXchg(cx: &Block, dst: ValueRef,
816816
cmp: ValueRef, src: ValueRef,
817-
order: AtomicOrdering) -> ValueRef {
818-
B(cx).atomic_cmpxchg(dst, cmp, src, order)
817+
order: AtomicOrdering,
818+
failure_order: AtomicOrdering) -> ValueRef {
819+
B(cx).atomic_cmpxchg(dst, cmp, src, order, failure_order)
819820
}
820821
pub fn AtomicRMW(cx: &Block, op: AtomicBinOp,
821822
dst: ValueRef, src: ValueRef,

src/librustc/middle/trans/builder.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -949,9 +949,11 @@ impl<'a> Builder<'a> {
949949
// Atomic Operations
950950
pub fn atomic_cmpxchg(&self, dst: ValueRef,
951951
cmp: ValueRef, src: ValueRef,
952-
order: AtomicOrdering) -> ValueRef {
952+
order: AtomicOrdering,
953+
failure_order: AtomicOrdering) -> ValueRef {
953954
unsafe {
954-
llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order)
955+
llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src,
956+
order, failure_order)
955957
}
956958
}
957959
pub fn atomic_rmw(&self, op: AtomicBinOp,

src/librustc/middle/trans/debuginfo.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ pub fn finalize(cx: &CrateContext) {
278278
if cx.sess().targ_cfg.os == abi::OsMacos {
279279
"Dwarf Version".with_c_str(
280280
|s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
281+
} else {
282+
// FIXME(#13611) this is a kludge fix because the linux bots have
283+
// gdb 7.4 which doesn't understand dwarf4, we should
284+
// do something more graceful here.
285+
"Dwarf Version".with_c_str(
286+
|s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 3));
281287
}
282288

283289
// Prevent bitcode readers from deleting the debug info.
@@ -2421,7 +2427,8 @@ fn populate_scope_map(cx: &CrateContext,
24212427
parent_scope,
24222428
file_metadata,
24232429
loc.line as c_uint,
2424-
loc.col.to_uint() as c_uint)
2430+
loc.col.to_uint() as c_uint,
2431+
0)
24252432
};
24262433

24272434
scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, ident: None });
@@ -2538,7 +2545,8 @@ fn populate_scope_map(cx: &CrateContext,
25382545
parent_scope,
25392546
file_metadata,
25402547
loc.line as c_uint,
2541-
loc.col.to_uint() as c_uint)
2548+
loc.col.to_uint() as c_uint,
2549+
0)
25422550
};
25432551

25442552
scope_stack.push(ScopeStackEntry {

src/librustc/middle/trans/intrinsic.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,23 @@ pub fn trans_intrinsic(ccx: &CrateContext,
223223

224224
match *split.get(1) {
225225
"cxchg" => {
226+
// See include/llvm/IR/Instructions.h for their implementation
227+
// of this, I assume that it's good enough for us to use for
228+
// now.
229+
let strongest_failure_ordering = match order {
230+
lib::llvm::NotAtomic | lib::llvm::Unordered =>
231+
ccx.sess().fatal("cmpxchg must be atomic"),
232+
lib::llvm::Monotonic | lib::llvm::Release =>
233+
lib::llvm::Monotonic,
234+
lib::llvm::Acquire | lib::llvm::AcquireRelease =>
235+
lib::llvm::Acquire,
236+
lib::llvm::SequentiallyConsistent =>
237+
lib::llvm::SequentiallyConsistent,
238+
};
226239
let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
227240
get_param(decl, first_real_arg + 1u),
228241
get_param(decl, first_real_arg + 2u),
229-
order);
242+
order, strongest_failure_ordering);
230243
Ret(bcx, old);
231244
}
232245
"load" => {

0 commit comments

Comments
 (0)