]> git.lizzy.rs Git - rust.git/blob - src/libcompiler_builtins/build.rs
16ecf88256670233c9f1f543ebe05f46f11abd61
[rust.git] / src / libcompiler_builtins / build.rs
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.
4 //
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.
10
11 //! Compiles the `compiler-rt` library, or at least the builtins part of it.
12 //!
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.
19 //!
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!
24 //!
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.
28 //!
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.
35
36 extern crate gcc;
37
38 use std::collections::BTreeMap;
39 use std::env;
40 use std::path::Path;
41
42 struct Sources {
43     // SYMBOL -> PATH TO SOURCE
44     map: BTreeMap<&'static str, &'static str>,
45 }
46
47 impl Sources {
48     fn new() -> Sources {
49         Sources { map: BTreeMap::new() }
50     }
51
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
58         // duplicate symbols!
59         for &src in sources {
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);
64             } else {
65                 // Generic implementation
66                 if !self.map.contains_key(symbol) {
67                     self.map.insert(symbol, src);
68                 }
69             }
70         }
71     }
72 }
73
74 fn main() {
75     let target = env::var("TARGET").expect("TARGET was not set");
76
77     // Emscripten's runtime includes all the builtins
78     if target.contains("emscripten") {
79         return;
80     }
81
82     let cfg = &mut gcc::Config::new();
83
84     if target.contains("msvc") {
85         // Don't pull in extra libraries on MSVC
86         cfg.flag("/Zl");
87
88         // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
89         cfg.define("__func__", Some("__FUNCTION__"));
90     } else {
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         // Accepted practice on Solaris is to never omit frame pointer so that
96         // system observability tools work as expected.  In addition, at least
97         // on Solaris, -fomit-frame-pointer on sparcv9 appears to generate
98         // references to data outside of the current stack frame.  A search of
99         // the gcc bug database provides a variety of issues surrounding
100         // -fomit-frame-pointer on non-x86 platforms.
101         if !target.contains("solaris") && !target.contains("sparc") {
102             cfg.flag("-fomit-frame-pointer");
103         }
104         cfg.flag("-ffreestanding");
105         cfg.define("VISIBILITY_HIDDEN", None);
106     }
107
108     let mut sources = Sources::new();
109     sources.extend(&["absvdi2.c",
110                      "absvsi2.c",
111                      "adddf3.c",
112                      "addsf3.c",
113                      "addvdi3.c",
114                      "addvsi3.c",
115                      "apple_versioning.c",
116                      "ashldi3.c",
117                      "ashrdi3.c",
118                      "clzdi2.c",
119                      "clzsi2.c",
120                      "cmpdi2.c",
121                      "comparedf2.c",
122                      "comparesf2.c",
123                      "ctzdi2.c",
124                      "ctzsi2.c",
125                      "divdc3.c",
126                      "divdf3.c",
127                      "divdi3.c",
128                      "divmoddi4.c",
129                      "divmodsi4.c",
130                      "divsc3.c",
131                      "divsf3.c",
132                      "divsi3.c",
133                      "divxc3.c",
134                      "extendsfdf2.c",
135                      "extendhfsf2.c",
136                      "ffsdi2.c",
137                      "fixdfdi.c",
138                      "fixdfsi.c",
139                      "fixsfdi.c",
140                      "fixsfsi.c",
141                      "fixunsdfdi.c",
142                      "fixunsdfsi.c",
143                      "fixunssfdi.c",
144                      "fixunssfsi.c",
145                      "fixunsxfdi.c",
146                      "fixunsxfsi.c",
147                      "fixxfdi.c",
148                      "floatdidf.c",
149                      "floatdisf.c",
150                      "floatdixf.c",
151                      "floatsidf.c",
152                      "floatsisf.c",
153                      "floatundidf.c",
154                      "floatundisf.c",
155                      "floatundixf.c",
156                      "floatunsidf.c",
157                      "floatunsisf.c",
158                      "int_util.c",
159                      "lshrdi3.c",
160                      "moddi3.c",
161                      "modsi3.c",
162                      "muldc3.c",
163                      "muldf3.c",
164                      "muldi3.c",
165                      "mulodi4.c",
166                      "mulosi4.c",
167                      "muloti4.c",
168                      "mulsc3.c",
169                      "mulsf3.c",
170                      "mulvdi3.c",
171                      "mulvsi3.c",
172                      "mulxc3.c",
173                      "negdf2.c",
174                      "negdi2.c",
175                      "negsf2.c",
176                      "negvdi2.c",
177                      "negvsi2.c",
178                      "paritydi2.c",
179                      "paritysi2.c",
180                      "popcountdi2.c",
181                      "popcountsi2.c",
182                      "powidf2.c",
183                      "powisf2.c",
184                      "powixf2.c",
185                      "subdf3.c",
186                      "subsf3.c",
187                      "subvdi3.c",
188                      "subvsi3.c",
189                      "truncdfhf2.c",
190                      "truncdfsf2.c",
191                      "truncsfhf2.c",
192                      "ucmpdi2.c",
193                      "udivdi3.c",
194                      "udivmoddi4.c",
195                      "udivmodsi4.c",
196                      "udivsi3.c",
197                      "umoddi3.c",
198                      "umodsi3.c"]);
199
200     if !target.contains("ios") {
201         sources.extend(&["absvti2.c",
202                          "addvti3.c",
203                          "ashlti3.c",
204                          "ashrti3.c",
205                          "clzti2.c",
206                          "cmpti2.c",
207                          "ctzti2.c",
208                          "divti3.c",
209                          "ffsti2.c",
210                          "fixdfti.c",
211                          "fixsfti.c",
212                          "fixunsdfti.c",
213                          "fixunssfti.c",
214                          "fixunsxfti.c",
215                          "fixxfti.c",
216                          "floattidf.c",
217                          "floattisf.c",
218                          "floattixf.c",
219                          "floatuntidf.c",
220                          "floatuntisf.c",
221                          "floatuntixf.c",
222                          "lshrti3.c",
223                          "modti3.c",
224                          "multi3.c",
225                          "mulvti3.c",
226                          "negti2.c",
227                          "negvti2.c",
228                          "parityti2.c",
229                          "popcountti2.c",
230                          "subvti3.c",
231                          "ucmpti2.c",
232                          "udivmodti4.c",
233                          "udivti3.c",
234                          "umodti3.c"]);
235     }
236
237     if target.contains("apple") {
238         sources.extend(&["atomic_flag_clear.c",
239                          "atomic_flag_clear_explicit.c",
240                          "atomic_flag_test_and_set.c",
241                          "atomic_flag_test_and_set_explicit.c",
242                          "atomic_signal_fence.c",
243                          "atomic_thread_fence.c"]);
244     }
245
246     if target.contains("msvc") {
247         if target.contains("x86_64") {
248             sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]);
249         }
250     } else {
251         if !target.contains("freebsd") && !target.contains("netbsd") {
252             sources.extend(&["gcc_personality_v0.c"]);
253         }
254
255         if target.contains("x86_64") {
256             sources.extend(&["x86_64/chkstk.S",
257                              "x86_64/chkstk2.S",
258                              "x86_64/floatdidf.c",
259                              "x86_64/floatdisf.c",
260                              "x86_64/floatdixf.c",
261                              "x86_64/floatundidf.S",
262                              "x86_64/floatundisf.S",
263                              "x86_64/floatundixf.S"]);
264         }
265
266         if target.contains("i386") || target.contains("i586") || target.contains("i686") {
267             sources.extend(&["i386/ashldi3.S",
268                              "i386/ashrdi3.S",
269                              "i386/chkstk.S",
270                              "i386/chkstk2.S",
271                              "i386/divdi3.S",
272                              "i386/floatdidf.S",
273                              "i386/floatdisf.S",
274                              "i386/floatdixf.S",
275                              "i386/floatundidf.S",
276                              "i386/floatundisf.S",
277                              "i386/floatundixf.S",
278                              "i386/lshrdi3.S",
279                              "i386/moddi3.S",
280                              "i386/muldi3.S",
281                              "i386/udivdi3.S",
282                              "i386/umoddi3.S"]);
283         }
284     }
285
286     if target.contains("arm") && !target.contains("ios") {
287         sources.extend(&["arm/aeabi_cdcmp.S",
288                          "arm/aeabi_cdcmpeq_check_nan.c",
289                          "arm/aeabi_cfcmp.S",
290                          "arm/aeabi_cfcmpeq_check_nan.c",
291                          "arm/aeabi_dcmp.S",
292                          "arm/aeabi_div0.c",
293                          "arm/aeabi_drsub.c",
294                          "arm/aeabi_fcmp.S",
295                          "arm/aeabi_frsub.c",
296                          "arm/aeabi_idivmod.S",
297                          "arm/aeabi_ldivmod.S",
298                          "arm/aeabi_memcmp.S",
299                          "arm/aeabi_memcpy.S",
300                          "arm/aeabi_memmove.S",
301                          "arm/aeabi_memset.S",
302                          "arm/aeabi_uidivmod.S",
303                          "arm/aeabi_uldivmod.S",
304                          "arm/bswapdi2.S",
305                          "arm/bswapsi2.S",
306                          "arm/clzdi2.S",
307                          "arm/clzsi2.S",
308                          "arm/comparesf2.S",
309                          "arm/divmodsi4.S",
310                          "arm/divsi3.S",
311                          "arm/modsi3.S",
312                          "arm/switch16.S",
313                          "arm/switch32.S",
314                          "arm/switch8.S",
315                          "arm/switchu8.S",
316                          "arm/sync_synchronize.S",
317                          "arm/udivmodsi4.S",
318                          "arm/udivsi3.S",
319                          "arm/umodsi3.S"]);
320     }
321
322     if target.contains("armv7") {
323         sources.extend(&["arm/sync_fetch_and_add_4.S",
324                          "arm/sync_fetch_and_add_8.S",
325                          "arm/sync_fetch_and_and_4.S",
326                          "arm/sync_fetch_and_and_8.S",
327                          "arm/sync_fetch_and_max_4.S",
328                          "arm/sync_fetch_and_max_8.S",
329                          "arm/sync_fetch_and_min_4.S",
330                          "arm/sync_fetch_and_min_8.S",
331                          "arm/sync_fetch_and_nand_4.S",
332                          "arm/sync_fetch_and_nand_8.S",
333                          "arm/sync_fetch_and_or_4.S",
334                          "arm/sync_fetch_and_or_8.S",
335                          "arm/sync_fetch_and_sub_4.S",
336                          "arm/sync_fetch_and_sub_8.S",
337                          "arm/sync_fetch_and_umax_4.S",
338                          "arm/sync_fetch_and_umax_8.S",
339                          "arm/sync_fetch_and_umin_4.S",
340                          "arm/sync_fetch_and_umin_8.S",
341                          "arm/sync_fetch_and_xor_4.S",
342                          "arm/sync_fetch_and_xor_8.S"]);
343     }
344
345     if target.contains("eabihf") {
346         sources.extend(&["arm/adddf3vfp.S",
347                          "arm/addsf3vfp.S",
348                          "arm/divdf3vfp.S",
349                          "arm/divsf3vfp.S",
350                          "arm/eqdf2vfp.S",
351                          "arm/eqsf2vfp.S",
352                          "arm/extendsfdf2vfp.S",
353                          "arm/fixdfsivfp.S",
354                          "arm/fixsfsivfp.S",
355                          "arm/fixunsdfsivfp.S",
356                          "arm/fixunssfsivfp.S",
357                          "arm/floatsidfvfp.S",
358                          "arm/floatsisfvfp.S",
359                          "arm/floatunssidfvfp.S",
360                          "arm/floatunssisfvfp.S",
361                          "arm/gedf2vfp.S",
362                          "arm/gesf2vfp.S",
363                          "arm/gtdf2vfp.S",
364                          "arm/gtsf2vfp.S",
365                          "arm/ledf2vfp.S",
366                          "arm/lesf2vfp.S",
367                          "arm/ltdf2vfp.S",
368                          "arm/ltsf2vfp.S",
369                          "arm/muldf3vfp.S",
370                          "arm/mulsf3vfp.S",
371                          "arm/negdf2vfp.S",
372                          "arm/negsf2vfp.S",
373                          "arm/nedf2vfp.S",
374                          "arm/nesf2vfp.S",
375                          "arm/restore_vfp_d8_d15_regs.S",
376                          "arm/save_vfp_d8_d15_regs.S",
377                          "arm/subdf3vfp.S",
378                          "arm/subsf3vfp.S",
379                          "arm/truncdfsf2vfp.S",
380                          "arm/unorddf2vfp.S",
381                          "arm/unordsf2vfp.S"]);
382     }
383
384     if target.contains("aarch64") {
385         sources.extend(&["comparetf2.c",
386                          "extenddftf2.c",
387                          "extendsftf2.c",
388                          "fixtfdi.c",
389                          "fixtfsi.c",
390                          "fixtfti.c",
391                          "fixunstfdi.c",
392                          "fixunstfsi.c",
393                          "fixunstfti.c",
394                          "floatditf.c",
395                          "floatsitf.c",
396                          "floatunditf.c",
397                          "floatunsitf.c",
398                          "multc3.c",
399                          "trunctfdf2.c",
400                          "trunctfsf2.c"]);
401     }
402
403     for src in sources.map.values() {
404         cfg.file(Path::new("../compiler-rt/lib/builtins").join(src));
405     }
406
407     cfg.compile("libcompiler-rt.a");
408 }