@@ -38,6 +38,25 @@ fn main() {
38
38
39
39
println ! ( "cargo:rerun-if-changed={}" , llvm_config. display( ) ) ;
40
40
41
+ // Test whether we're cross-compiling LLVM. This is a pretty rare case
42
+ // currently where we're producing an LLVM for a different platform than
43
+ // what this build script is currently running on.
44
+ //
45
+ // In that case, there's no guarantee that we can actually run the target,
46
+ // so the build system works around this by giving us the LLVM_CONFIG for
47
+ // the host platform. This only really works if the host LLVM and target
48
+ // LLVM are compiled the same way, but for us that's typically the case.
49
+ //
50
+ // We detect this cross compiling situation by asking llvm-config what it's
51
+ // host-target is. If that's not the TARGET, then we're cross compiling.
52
+ // This generally just means that we can't trust all the output of
53
+ // llvm-config becaues it might be targeted for the host rather than the
54
+ // target.
55
+ let target = env:: var ( "TARGET" ) . unwrap ( ) ;
56
+ let host = output ( Command :: new ( & llvm_config) . arg ( "--host-target" ) ) ;
57
+ let host = host. trim ( ) ;
58
+ let is_crossed = target != host;
59
+
41
60
let optional_components = [ "x86" , "arm" , "aarch64" , "mips" , "powerpc" ,
42
61
"pnacl" ] ;
43
62
@@ -69,6 +88,10 @@ fn main() {
69
88
let cxxflags = output ( & mut cmd) ;
70
89
let mut cfg = gcc:: Config :: new ( ) ;
71
90
for flag in cxxflags. split_whitespace ( ) {
91
+ // Ignore flags like `-m64` when we're doing a cross build
92
+ if is_crossed && flag. starts_with ( "-m" ) {
93
+ continue
94
+ }
72
95
cfg. flag ( flag) ;
73
96
}
74
97
cfg. file ( "../rustllvm/ExecutionEngineWrapper.cpp" )
@@ -79,9 +102,16 @@ fn main() {
79
102
. cpp_link_stdlib ( None ) // we handle this below
80
103
. compile ( "librustllvm.a" ) ;
81
104
82
- // Link in all LLVM libraries
105
+ // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then
106
+ // we don't pick up system libs because unfortunately they're for the host
107
+ // of llvm-config, not the target that we're attempting to link.
83
108
let mut cmd = Command :: new ( & llvm_config) ;
84
- cmd. arg ( "--libs" ) . arg ( "--system-libs" ) . args ( & components[ ..] ) ;
109
+ cmd. arg ( "--libs" ) ;
110
+ if !is_crossed {
111
+ cmd. arg ( "--system-libs" ) ;
112
+ }
113
+ cmd. args ( & components[ ..] ) ;
114
+
85
115
for lib in output ( & mut cmd) . split_whitespace ( ) {
86
116
let name = if lib. starts_with ( "-l" ) {
87
117
& lib[ 2 ..]
@@ -105,10 +135,20 @@ fn main() {
105
135
}
106
136
107
137
// LLVM ldflags
138
+ //
139
+ // If we're a cross-compile of LLVM then unfortunately we can't trust these
140
+ // ldflags (largely where all the LLVM libs are located). Currently just
141
+ // hack around this by replacing the host triple with the target and pray
142
+ // that those -L directories are the same!
108
143
let mut cmd = Command :: new ( & llvm_config) ;
109
144
cmd. arg ( "--ldflags" ) ;
110
145
for lib in output ( & mut cmd) . split_whitespace ( ) {
111
- if lib. starts_with ( "-l" ) {
146
+ if is_crossed {
147
+ if lib. starts_with ( "-L" ) {
148
+ println ! ( "cargo:rustc-link-search=native={}" ,
149
+ lib[ 2 ..] . replace( & host, & target) ) ;
150
+ }
151
+ } else if lib. starts_with ( "-l" ) {
112
152
println ! ( "cargo:rustc-link-lib={}" , & lib[ 2 ..] ) ;
113
153
} else if lib. starts_with ( "-L" ) {
114
154
println ! ( "cargo:rustc-link-search=native={}" , & lib[ 2 ..] ) ;
0 commit comments