@@ -38,6 +38,25 @@ fn main() {
3838
3939 println ! ( "cargo:rerun-if-changed={}" , llvm_config. display( ) ) ;
4040
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+
4160 let optional_components = [ "x86" , "arm" , "aarch64" , "mips" , "powerpc" ,
4261 "pnacl" ] ;
4362
@@ -69,6 +88,10 @@ fn main() {
6988 let cxxflags = output ( & mut cmd) ;
7089 let mut cfg = gcc:: Config :: new ( ) ;
7190 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+ }
7295 cfg. flag ( flag) ;
7396 }
7497 cfg. file ( "../rustllvm/ExecutionEngineWrapper.cpp" )
@@ -79,9 +102,16 @@ fn main() {
79102 . cpp_link_stdlib ( None ) // we handle this below
80103 . compile ( "librustllvm.a" ) ;
81104
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.
83108 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+
85115 for lib in output ( & mut cmd) . split_whitespace ( ) {
86116 let name = if lib. starts_with ( "-l" ) {
87117 & lib[ 2 ..]
@@ -105,10 +135,20 @@ fn main() {
105135 }
106136
107137 // 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!
108143 let mut cmd = Command :: new ( & llvm_config) ;
109144 cmd. arg ( "--ldflags" ) ;
110145 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" ) {
112152 println ! ( "cargo:rustc-link-lib={}" , & lib[ 2 ..] ) ;
113153 } else if lib. starts_with ( "-L" ) {
114154 println ! ( "cargo:rustc-link-search=native={}" , & lib[ 2 ..] ) ;
0 commit comments