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