@@ -40,7 +40,7 @@ fn main() {
40
40
// mangling names though we assume that we're also in test mode so we don't
41
41
// build anything and we rely on the upstream implementation of compiler-rt
42
42
// functions
43
- if !cfg ! ( feature = "mangled-names" ) && cfg ! ( feature = "c" ) {
43
+ if !cfg ! ( feature = "mangled-names" ) && cfg ! ( any ( feature = "c-vendor" , feature = "c-system" ) ) {
44
44
// Don't use a C compiler for these targets:
45
45
//
46
46
// * wasm32 - clang 8 for wasm is somewhat hard to come by and it's
@@ -50,8 +50,10 @@ fn main() {
50
50
// compiler nor is cc-rs ready for compilation to riscv (at this
51
51
// time). This can probably be removed in the future
52
52
if !target. contains ( "wasm32" ) && !target. contains ( "nvptx" ) && !target. starts_with ( "riscv" ) {
53
- #[ cfg( feature = "c" ) ]
54
- c:: compile ( & llvm_target) ;
53
+ #[ cfg( feature = "c-vendor" ) ]
54
+ c_vendor:: compile ( & llvm_target) ;
55
+ #[ cfg( feature = "c-system" ) ]
56
+ c_system:: compile ( & llvm_target) ;
55
57
}
56
58
}
57
59
@@ -73,17 +75,14 @@ fn main() {
73
75
}
74
76
}
75
77
76
- #[ cfg( feature = "c" ) ]
77
- mod c {
78
- extern crate cc;
79
-
78
+ #[ cfg( any( feature = "c-vendor" , feature = "c-system" ) ) ]
79
+ mod sources {
80
80
use std:: collections:: BTreeMap ;
81
81
use std:: env;
82
- use std:: path:: PathBuf ;
83
82
84
- struct Sources {
83
+ pub struct Sources {
85
84
// SYMBOL -> PATH TO SOURCE
86
- map : BTreeMap < & ' static str , & ' static str > ,
85
+ pub map : BTreeMap < & ' static str , & ' static str > ,
87
86
}
88
87
89
88
impl Sources {
@@ -120,39 +119,11 @@ mod c {
120
119
}
121
120
}
122
121
123
- /// Compile intrinsics from the compiler-rt C source code
124
- pub fn compile ( llvm_target : & [ & str ] ) {
122
+ pub fn get_sources ( llvm_target : & [ & str ] ) -> Sources {
125
123
let target_arch = env:: var ( "CARGO_CFG_TARGET_ARCH" ) . unwrap ( ) ;
126
124
let target_env = env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) ;
127
125
let target_os = env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap ( ) ;
128
126
let target_vendor = env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ;
129
- let cfg = & mut cc:: Build :: new ( ) ;
130
-
131
- cfg. warnings ( false ) ;
132
-
133
- if target_env == "msvc" {
134
- // Don't pull in extra libraries on MSVC
135
- cfg. flag ( "/Zl" ) ;
136
-
137
- // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
138
- cfg. define ( "__func__" , Some ( "__FUNCTION__" ) ) ;
139
- } else {
140
- // Turn off various features of gcc and such, mostly copying
141
- // compiler-rt's build system already
142
- cfg. flag ( "-fno-builtin" ) ;
143
- cfg. flag ( "-fvisibility=hidden" ) ;
144
- cfg. flag ( "-ffreestanding" ) ;
145
- // Avoid the following warning appearing once **per file**:
146
- // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]
147
- //
148
- // Note that compiler-rt's build system also checks
149
- //
150
- // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`
151
- //
152
- // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.
153
- cfg. flag_if_supported ( "-fomit-frame-pointer" ) ;
154
- cfg. define ( "VISIBILITY_HIDDEN" , None ) ;
155
- }
156
127
157
128
let mut sources = Sources :: new ( ) ;
158
129
sources. extend ( & [
@@ -414,6 +385,48 @@ mod c {
414
385
sources. remove ( & [ "__aeabi_cdcmp" , "__aeabi_cfcmp" ] ) ;
415
386
}
416
387
388
+ sources
389
+ }
390
+ }
391
+
392
+ #[ cfg( feature = "c-vendor" ) ]
393
+ mod c_vendor {
394
+ extern crate cc;
395
+
396
+ use std:: env;
397
+ use std:: path:: PathBuf ;
398
+ use sources;
399
+
400
+ /// Compile intrinsics from the compiler-rt C source code
401
+ pub fn compile ( llvm_target : & [ & str ] ) {
402
+ let target_env = env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) ;
403
+ let cfg = & mut cc:: Build :: new ( ) ;
404
+ cfg. warnings ( false ) ;
405
+
406
+ if target_env == "msvc" {
407
+ // Don't pull in extra libraries on MSVC
408
+ cfg. flag ( "/Zl" ) ;
409
+
410
+ // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
411
+ cfg. define ( "__func__" , Some ( "__FUNCTION__" ) ) ;
412
+ } else {
413
+ // Turn off various features of gcc and such, mostly copying
414
+ // compiler-rt's build system already
415
+ cfg. flag ( "-fno-builtin" ) ;
416
+ cfg. flag ( "-fvisibility=hidden" ) ;
417
+ cfg. flag ( "-ffreestanding" ) ;
418
+ // Avoid the following warning appearing once **per file**:
419
+ // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]
420
+ //
421
+ // Note that compiler-rt's build system also checks
422
+ //
423
+ // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`
424
+ //
425
+ // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.
426
+ cfg. flag_if_supported ( "-fomit-frame-pointer" ) ;
427
+ cfg. define ( "VISIBILITY_HIDDEN" , None ) ;
428
+ }
429
+
417
430
// When compiling the C code we require the user to tell us where the
418
431
// source code is, and this is largely done so when we're compiling as
419
432
// part of rust-lang/rust we can use the same llvm-project repository as
@@ -431,6 +444,7 @@ mod c {
431
444
// use of that macro in lib/builtins/int_util.h in compiler-rt.
432
445
cfg. flag_if_supported ( & format ! ( "-ffile-prefix-map={}=." , root. display( ) ) ) ;
433
446
447
+ let sources = sources:: get_sources ( llvm_target) ;
434
448
let src_dir = root. join ( "lib/builtins" ) ;
435
449
for ( sym, src) in sources. map . iter ( ) {
436
450
let src = src_dir. join ( src) ;
@@ -442,3 +456,41 @@ mod c {
442
456
cfg. compile ( "libcompiler-rt.a" ) ;
443
457
}
444
458
}
459
+
460
+ #[ cfg( feature = "c-system" ) ]
461
+ mod c_system {
462
+ use std:: env;
463
+ use std:: process:: Command ;
464
+ use std:: str;
465
+ use sources;
466
+
467
+ /// Link against system clang runtime libraries
468
+ pub fn compile ( llvm_target : & [ & str ] ) {
469
+ let target_os = env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap ( ) ;
470
+
471
+ let llvm_config = env:: var ( "LLVM_CONFIG" ) . expect ( "LLVM_CONFIG not set" ) ;
472
+ let ( subpath, libname) = match target_os. as_str ( ) {
473
+ "linux" => ( "linux" , format ! ( "clang_rt.builtins-{}" , llvm_target[ 0 ] ) ) ,
474
+ "macos" => ( "darwin" , "clang_rt.builtins_osx_dynamic" . to_string ( ) ) ,
475
+ _ => panic ! ( "unsupported target os: {}" , target_os) ,
476
+ } ;
477
+ let cmd = format ! ( "ls -1d $({} --libdir)/clang/*/lib/{}" , llvm_config, subpath) ;
478
+ let output = Command :: new ( "sh" )
479
+ . args ( & [ "-ec" , & cmd] )
480
+ . output ( )
481
+ . expect ( "failed to find clang lib dir" ) ;
482
+ let status = output. status ;
483
+ if !status. success ( ) {
484
+ panic ! ( format!( "failed to find clang lib dir: {:?}" , status. code( ) ) ) ;
485
+ }
486
+ for search_dir in str:: from_utf8 ( & output. stdout ) . unwrap ( ) . lines ( ) {
487
+ println ! ( "cargo:rustc-link-search=native={}" , search_dir) ;
488
+ }
489
+ println ! ( "cargo:rustc-link-lib=static={}" , libname) ;
490
+
491
+ let sources = sources:: get_sources ( llvm_target) ;
492
+ for ( sym, _src) in sources. map . iter ( ) {
493
+ println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " , sym) ;
494
+ }
495
+ }
496
+ }
0 commit comments