1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Compiles the `compiler-rt` library, or at least the builtins part of it.
13 //! Note that while compiler-rt has a build system associated with it, we
14 //! specifically don't use it here. The compiler-rt build system, written in
15 //! CMake, is actually *very* difficult to work with in terms of getting it to
16 //! compile on all the relevant platforms we want it to compile on. In the end
17 //! it became so much pain to work with local patches, work around the oddities
18 //! of the build system, etc, that we're just building everything by hand now.
20 //! In general compiler-rt is just a bunch of intrinsics that are in practice
21 //! *very* stable. We just need to make sure that all the relevant functions and
22 //! such are compiled somewhere and placed in an object file somewhere.
23 //! Eventually, these should all be written in Rust!
25 //! So below you'll find a listing of every single file in the compiler-rt repo
26 //! that we're compiling. We just reach in and compile with the `gcc` crate
27 //! which should have all the relevant flags and such already configured.
29 //! The risk here is that if we update compiler-rt we may need to compile some
30 //! new intrinsics, but to be honest we surely don't use all of the intrinsics
31 //! listed below today so the likelihood of us actually needing a new intrinsic
32 //! is quite low. The failure case is also just that someone reports a link
33 //! error (if any) and then we just add it to the list. Overall, that cost is
34 //! far far less than working with compiler-rt's build system over time.
38 use std::collections::BTreeMap;
43 // SYMBOL -> PATH TO SOURCE
44 map: BTreeMap<&'static str, &'static str>,
49 Sources { map: BTreeMap::new() }
52 fn extend(&mut self, sources: &[&'static str]) {
53 // NOTE Some intrinsics have both a generic implementation (e.g.
54 // `floatdidf.c`) and an arch optimized implementation
55 // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
56 // implementation and discard the generic implementation. If we don't
57 // and keep both implementations, the linker will yell at us about
60 let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
61 if src.contains("/") {
62 // Arch-optimized implementation (preferred)
63 self.map.insert(symbol, src);
65 // Generic implementation
66 if !self.map.contains_key(symbol) {
67 self.map.insert(symbol, src);
75 let target = env::var("TARGET").expect("TARGET was not set");
77 // Emscripten's runtime includes all the builtins
78 if target.contains("emscripten") {
82 let cfg = &mut gcc::Config::new();
84 if target.contains("msvc") {
85 // Don't pull in extra libraries on MSVC
88 // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
89 cfg.define("__func__", Some("__FUNCTION__"));
91 // Turn off various features of gcc and such, mostly copying
92 // compiler-rt's build system already
93 cfg.flag("-fno-builtin");
94 cfg.flag("-fvisibility=hidden");
95 cfg.flag("-fomit-frame-pointer");
96 cfg.flag("-ffreestanding");
97 cfg.define("VISIBILITY_HIDDEN", None);
100 let mut sources = Sources::new();
101 sources.extend(&["absvdi2.c",
107 "apple_versioning.c",
193 if !target.contains("ios") {
194 sources.extend(&["absvti2.c",
229 "trampoline_setup.c",
236 if target.contains("apple") {
237 sources.extend(&["atomic_flag_clear.c",
238 "atomic_flag_clear_explicit.c",
239 "atomic_flag_test_and_set.c",
240 "atomic_flag_test_and_set_explicit.c",
241 "atomic_signal_fence.c",
242 "atomic_thread_fence.c"]);
245 if !target.contains("redox") && !target.contains("windows") {
246 sources.extend(&["emutls.c"]);
249 if target.contains("msvc") {
250 if target.contains("x86_64") {
251 sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]);
254 if !target.contains("freebsd") {
255 sources.extend(&["gcc_personality_v0.c"]);
258 if target.contains("x86_64") {
259 sources.extend(&["x86_64/chkstk.S",
261 "x86_64/floatdidf.c",
262 "x86_64/floatdisf.c",
263 "x86_64/floatdixf.c",
264 "x86_64/floatundidf.S",
265 "x86_64/floatundisf.S",
266 "x86_64/floatundixf.S"]);
269 if target.contains("i386") || target.contains("i586") || target.contains("i686") {
270 sources.extend(&["i386/ashldi3.S",
278 "i386/floatundidf.S",
279 "i386/floatundisf.S",
280 "i386/floatundixf.S",
289 if target.contains("arm") && !target.contains("ios") {
290 sources.extend(&["arm/aeabi_cdcmp.S",
291 "arm/aeabi_cdcmpeq_check_nan.c",
293 "arm/aeabi_cfcmpeq_check_nan.c",
299 "arm/aeabi_idivmod.S",
300 "arm/aeabi_ldivmod.S",
301 "arm/aeabi_memcmp.S",
302 "arm/aeabi_memcpy.S",
303 "arm/aeabi_memmove.S",
304 "arm/aeabi_memset.S",
305 "arm/aeabi_uidivmod.S",
306 "arm/aeabi_uldivmod.S",
319 "arm/sync_synchronize.S",
325 if target.contains("armv7") {
326 sources.extend(&["arm/sync_fetch_and_add_4.S",
327 "arm/sync_fetch_and_add_8.S",
328 "arm/sync_fetch_and_and_4.S",
329 "arm/sync_fetch_and_and_8.S",
330 "arm/sync_fetch_and_max_4.S",
331 "arm/sync_fetch_and_max_8.S",
332 "arm/sync_fetch_and_min_4.S",
333 "arm/sync_fetch_and_min_8.S",
334 "arm/sync_fetch_and_nand_4.S",
335 "arm/sync_fetch_and_nand_8.S",
336 "arm/sync_fetch_and_or_4.S",
337 "arm/sync_fetch_and_or_8.S",
338 "arm/sync_fetch_and_sub_4.S",
339 "arm/sync_fetch_and_sub_8.S",
340 "arm/sync_fetch_and_umax_4.S",
341 "arm/sync_fetch_and_umax_8.S",
342 "arm/sync_fetch_and_umin_4.S",
343 "arm/sync_fetch_and_umin_8.S",
344 "arm/sync_fetch_and_xor_4.S",
345 "arm/sync_fetch_and_xor_8.S"]);
348 if target.contains("eabihf") {
349 sources.extend(&["arm/adddf3vfp.S",
355 "arm/extendsfdf2vfp.S",
358 "arm/fixunsdfsivfp.S",
359 "arm/fixunssfsivfp.S",
360 "arm/floatsidfvfp.S",
361 "arm/floatsisfvfp.S",
362 "arm/floatunssidfvfp.S",
363 "arm/floatunssisfvfp.S",
378 "arm/restore_vfp_d8_d15_regs.S",
379 "arm/save_vfp_d8_d15_regs.S",
382 "arm/truncdfsf2vfp.S",
384 "arm/unordsf2vfp.S"]);
387 if target.contains("aarch64") {
388 sources.extend(&["comparetf2.c",
406 for src in sources.map.values() {
407 cfg.file(Path::new("../compiler-rt/lib/builtins").join(src));
410 cfg.compile("libcompiler-rt.a");