mirror of
https://git.proxmox.com/git/rustc
synced 2026-01-17 01:45:06 +00:00
New upstream version 1.12.0+dfsg1
This commit is contained in:
parent
3157f602e5
commit
5bcae85e42
28
README.md
28
README.md
@ -66,7 +66,7 @@ build.
|
||||
|
||||
[MSYS2][msys2] can be used to easily build Rust on Windows:
|
||||
|
||||
msys2: https://msys2.github.io/
|
||||
[msys2]: https://msys2.github.io/
|
||||
|
||||
1. Grab the latest [MSYS2 installer][msys2] and go through the installer.
|
||||
|
||||
@ -105,7 +105,7 @@ msys2: https://msys2.github.io/
|
||||
|
||||
MSVC builds of Rust additionally require an installation of Visual Studio 2013
|
||||
(or later) so `rustc` can use its linker. Make sure to check the “C++ tools”
|
||||
option. In addition, `cmake` needs to be installed to build LLVM.
|
||||
option.
|
||||
|
||||
With these dependencies installed, the build takes two steps:
|
||||
|
||||
@ -116,13 +116,25 @@ $ make && make install
|
||||
|
||||
#### MSVC with rustbuild
|
||||
|
||||
For those who don't want the hassle of MSYS or MinGW, you can invoke rustbuild
|
||||
directly. All you need are Python 2, CMake, and Git in your PATH (make sure you
|
||||
do __not__ use the ones from MSYS!). You'll also need Visual Studio 2013 or
|
||||
newer with the C++ tools. Then all you need to do is invoke the appropriate
|
||||
vcvars bat file and kick off rustbuild.
|
||||
The old build system, based on makefiles, is currently being rewritten into a
|
||||
Rust-based build system called rustbuild. This can be used to bootstrap the
|
||||
compiler on MSVC without needing to install MSYS or MinGW. All you need are
|
||||
[Python 2](https://www.python.org/downloads/),
|
||||
[CMake](https://cmake.org/download/), and
|
||||
[Git](https://git-scm.com/downloads) in your PATH (make sure you do not use the
|
||||
ones from MSYS if you have it installed). You'll also need Visual Studio 2013 or
|
||||
newer with the C++ tools. Then all you need to do is to kick off rustbuild.
|
||||
|
||||
```bat
|
||||
```
|
||||
python .\src\bootstrap\bootstrap.py
|
||||
```
|
||||
|
||||
Currently rustbuild only works with some known versions of Visual Studio. If you
|
||||
have a more recent version installed that a part of rustbuild doesn't understand
|
||||
then you may need to force rustbuild to use an older version. This can be done
|
||||
by manually calling the appropriate vcvars file before running the bootstrap.
|
||||
|
||||
```
|
||||
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
|
||||
python .\src\bootstrap\bootstrap.py
|
||||
```
|
||||
|
||||
438
RELEASES.md
438
RELEASES.md
@ -1,3 +1,439 @@
|
||||
Version 1.12.0 (2016-09-29)
|
||||
===========================
|
||||
|
||||
Highlights
|
||||
----------
|
||||
|
||||
* [`rustc` translates code to LLVM IR via its own "middle" IR (MIR)]
|
||||
(https://github.com/rust-lang/rust/pull/34096).
|
||||
This translation pass is far simpler than the previous AST->LLVM pass, and
|
||||
creates opportunities to perform new optimizations directly on the MIR. It
|
||||
was previously described [on the Rust blog]
|
||||
(https://blog.rust-lang.org/2016/04/19/MIR.html).
|
||||
* [`rustc` presents a new, more readable error format, along with
|
||||
machine-readable JSON error output for use by IDEs]
|
||||
(https://github.com/rust-lang/rust/pull/35401).
|
||||
Most common editors supporting Rust have been updated to work with it. It was
|
||||
previously described [on the Rust blog]
|
||||
(https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html).
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
* [`rustc` translates code to LLVM IR via its own "middle" IR (MIR)]
|
||||
(https://github.com/rust-lang/rust/pull/34096).
|
||||
This translation pass is far simpler than the previous AST->LLVM pass, and
|
||||
creates opportunities to perform new optimizations directly on the MIR. It
|
||||
was previously described [on the Rust blog]
|
||||
(https://blog.rust-lang.org/2016/04/19/MIR.html).
|
||||
* [Print the Rust target name, not the LLVM target name, with
|
||||
`--print-target-list`]
|
||||
(https://github.com/rust-lang/rust/pull/35489)
|
||||
* [The computation of `TypeId` is correct in some cases where it was previously
|
||||
producing inconsistent results]
|
||||
(https://github.com/rust-lang/rust/pull/35267)
|
||||
* [The `mips-unknown-linux-gnu` target uses hardware floating point by default]
|
||||
(https://github.com/rust-lang/rust/pull/34910)
|
||||
* [The `rustc` arguments, `--print target-cpus`, `--print target-features`,
|
||||
`--print relocation-models`, and `--print code-models` print the available
|
||||
options to the `-C target-cpu`, `-C target-feature`, `-C relocation-model` and
|
||||
`-C code-model` code generation arguments]
|
||||
(https://github.com/rust-lang/rust/pull/34845)
|
||||
* [`rustc` supports three new MUSL targets on ARM: `arm-unknown-linux-musleabi`,
|
||||
`arm-unknown-linux-musleabihf`, and `armv7-unknown-linux-musleabihf`]
|
||||
(https://github.com/rust-lang/rust/pull/35060).
|
||||
These targets produce statically-linked binaries. There are no binary release
|
||||
builds yet though.
|
||||
|
||||
Diagnostics
|
||||
-----------
|
||||
|
||||
* [`rustc` presents a new, more readable error format, along with
|
||||
machine-readable JSON error output for use by IDEs]
|
||||
(https://github.com/rust-lang/rust/pull/35401).
|
||||
Most common editors supporting Rust have been updated to work with it. It was
|
||||
previously described [on the Rust blog]
|
||||
(https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html).
|
||||
* [In error descriptions, references are now described in plain english,
|
||||
instead of as "&-ptr"]
|
||||
(https://github.com/rust-lang/rust/pull/35611)
|
||||
* [In error type descriptions, unknown numeric types are named `{integer}` or
|
||||
`{float}` instead of `_`]
|
||||
(https://github.com/rust-lang/rust/pull/35080)
|
||||
* [`rustc` emits a clearer error when inner attributes follow a doc comment]
|
||||
(https://github.com/rust-lang/rust/pull/34676)
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
* [`macro_rules!` invocations can be made within `macro_rules!` invocations]
|
||||
(https://github.com/rust-lang/rust/pull/34925)
|
||||
* [`macro_rules!` meta-variables are hygienic]
|
||||
(https://github.com/rust-lang/rust/pull/35453)
|
||||
* [`macro_rules!` `tt` matchers can be reparsed correctly, making them much more
|
||||
useful]
|
||||
(https://github.com/rust-lang/rust/pull/34908)
|
||||
* [`macro_rules!` `stmt` matchers correctly consume the entire contents when
|
||||
insider non-braces invocations]
|
||||
(https://github.com/rust-lang/rust/pull/34886)
|
||||
* [Semicolons are properly required as statement delimeters inside
|
||||
`macro_rules!` invocations]
|
||||
(https://github.com/rust-lang/rust/pull/34660)
|
||||
* [`cfg_attr` works on `path` attributes]
|
||||
(https://github.com/rust-lang/rust/pull/34546)
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
* [`Cell::as_ptr`]
|
||||
(https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_ptr)
|
||||
* [`RefCell::as_ptr`]
|
||||
(https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.as_ptr)
|
||||
* [`IpAddr::is_unspecified`]
|
||||
(https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_unspecified)
|
||||
* [`IpAddr::is_loopback`]
|
||||
(https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_loopback)
|
||||
* [`IpAddr::is_multicast`]
|
||||
(https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_multicast)
|
||||
* [`Ipv4Addr::is_unspecified`]
|
||||
(https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_unspecified)
|
||||
* [`Ipv6Addr::octets`]
|
||||
(https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.octets)
|
||||
* [`LinkedList::contains`]
|
||||
(https://doc.rust-lang.org/std/collections/linked_list/struct.LinkedList.html#method.contains)
|
||||
* [`VecDeque::contains`]
|
||||
(https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.contains)
|
||||
* [`ExitStatusExt::from_raw`]
|
||||
(https://doc.rust-lang.org/std/os/unix/process/trait.ExitStatusExt.html#tymethod.from_raw).
|
||||
Both on Unix and Windows.
|
||||
* [`Receiver::recv_timeout`]
|
||||
(https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.recv_timeout)
|
||||
* [`RecvTimeoutError`]
|
||||
(https://doc.rust-lang.org/std/sync/mpsc/enum.RecvTimeoutError.html)
|
||||
* [`BinaryHeap::peek_mut`]
|
||||
(https://doc.rust-lang.org/std/collections/binary_heap/struct.BinaryHeap.html#method.peek_mut)
|
||||
* [`PeekMut`]
|
||||
(https://doc.rust-lang.org/std/collections/binary_heap/struct.PeekMut.html)
|
||||
* [`iter::Product`]
|
||||
(https://doc.rust-lang.org/std/iter/trait.Product.html)
|
||||
* [`iter::Sum`]
|
||||
(https://doc.rust-lang.org/std/iter/trait.Sum.html)
|
||||
* [`OccupiedEntry::remove_entry`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_map/struct.OccupiedEntry.html#method.remove_entry)
|
||||
* [`VacantEntry::into_key`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_map/struct.VacantEntry.html#method.into_key)
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
* [The `format!` macro and friends now allow a single argument to be formatted
|
||||
in multiple styles]
|
||||
(https://github.com/rust-lang/rust/pull/33642)
|
||||
* [The lifetime bounds on `[T]::binary_search_by` and
|
||||
`[T]::binary_search_by_key` have been adjusted to be more flexible]
|
||||
(https://github.com/rust-lang/rust/pull/34762)
|
||||
* [`Option` implements `From` for its contained type]
|
||||
(https://github.com/rust-lang/rust/pull/34828)
|
||||
* [`Cell`, `RefCell` and `UnsafeCell` implement `From` for their contained type]
|
||||
(https://github.com/rust-lang/rust/pull/35392)
|
||||
* [`RwLock` panics if the reader count overflows]
|
||||
(https://github.com/rust-lang/rust/pull/35378)
|
||||
* [`vec_deque::Drain`, `hash_map::Drain` and `hash_set::Drain` are covariant]
|
||||
(https://github.com/rust-lang/rust/pull/35354)
|
||||
* [`vec::Drain` and `binary_heap::Drain` are covariant]
|
||||
(https://github.com/rust-lang/rust/pull/34951)
|
||||
* [`Cow<str>` implements `FromIterator` for `char`, `&str` and `String`]
|
||||
(https://github.com/rust-lang/rust/pull/35064)
|
||||
* [Sockets on Linux are correctly closed in subprocesses via `SOCK_CLOEXEC`]
|
||||
(https://github.com/rust-lang/rust/pull/34946)
|
||||
* [`hash_map::Entry`, `hash_map::VacantEntry` and `hash_map::OccupiedEntry`
|
||||
implement `Debug`]
|
||||
(https://github.com/rust-lang/rust/pull/34946)
|
||||
* [`btree_map::Entry`, `btree_map::VacantEntry` and `btree_map::OccupiedEntry`
|
||||
implement `Debug`]
|
||||
(https://github.com/rust-lang/rust/pull/34885)
|
||||
* [`String` implements `AddAssign`]
|
||||
(https://github.com/rust-lang/rust/pull/34890)
|
||||
* [Variadic `extern fn` pointers implement the `Clone`, `PartialEq`, `Eq`,
|
||||
`PartialOrd`, `Ord`, `Hash`, `fmt::Pointer`, and `fmt::Debug` traits]
|
||||
(https://github.com/rust-lang/rust/pull/34879)
|
||||
* [`FileType` implements `Debug`]
|
||||
(https://github.com/rust-lang/rust/pull/34757)
|
||||
* [References to `Mutex` and `RwLock` are unwind-safe]
|
||||
(https://github.com/rust-lang/rust/pull/34756)
|
||||
* [`mpsc::sync_channel` `Receiver`s return any available message before
|
||||
reporting a disconnect]
|
||||
(https://github.com/rust-lang/rust/pull/34731)
|
||||
* [Unicode definitions have been updated to 9.0]
|
||||
(https://github.com/rust-lang/rust/pull/34599)
|
||||
* [`env` iterators implement `DoubleEndedIterator`]
|
||||
(https://github.com/rust-lang/rust/pull/33312)
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
* [Support local mirrors of registries]
|
||||
(https://github.com/rust-lang/cargo/pull/2857)
|
||||
* [Add support for command aliases]
|
||||
(https://github.com/rust-lang/cargo/pull/2679)
|
||||
* [Allow `opt-level="s"` / `opt-level="z"` in profile overrides]
|
||||
(https://github.com/rust-lang/cargo/pull/3007)
|
||||
* [Make `cargo doc --open --target` work as expected]
|
||||
(https://github.com/rust-lang/cargo/pull/2988)
|
||||
* [Speed up noop registry updates]
|
||||
(https://github.com/rust-lang/cargo/pull/2974)
|
||||
* [Update OpenSSL]
|
||||
(https://github.com/rust-lang/cargo/pull/2971)
|
||||
* [Fix `--panic=abort` with plugins]
|
||||
(https://github.com/rust-lang/cargo/pull/2954)
|
||||
* [Always pass `-C metadata` to the compiler]
|
||||
(https://github.com/rust-lang/cargo/pull/2946)
|
||||
* [Fix depending on git repos with workspaces]
|
||||
(https://github.com/rust-lang/cargo/pull/2938)
|
||||
* [Add a `--lib` flag to `cargo new`]
|
||||
(https://github.com/rust-lang/cargo/pull/2921)
|
||||
* [Add `http.cainfo` for custom certs]
|
||||
(https://github.com/rust-lang/cargo/pull/2917)
|
||||
* [Indicate the compilation profile after compiling]
|
||||
(https://github.com/rust-lang/cargo/pull/2909)
|
||||
* [Allow enabling features for dependencies with `--features`]
|
||||
(https://github.com/rust-lang/cargo/pull/2876)
|
||||
* [Add `--jobs` flag to `cargo package`]
|
||||
(https://github.com/rust-lang/cargo/pull/2867)
|
||||
* [Add `--dry-run` to `cargo publish`]
|
||||
(https://github.com/rust-lang/cargo/pull/2849)
|
||||
* [Add support for `RUSTDOCFLAGS`]
|
||||
(https://github.com/rust-lang/cargo/pull/2794)
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
* [`rustc` produces more compact code by more precisely identifying the live
|
||||
ranges of variables]
|
||||
(https://github.com/rust-lang/rust/pull/35409)
|
||||
* [`panic::catch_unwind` is more optimized]
|
||||
(https://github.com/rust-lang/rust/pull/35444)
|
||||
* [`panic::catch_unwind` no longer accesses thread-local storage on entry]
|
||||
(https://github.com/rust-lang/rust/pull/34866)
|
||||
|
||||
Tooling
|
||||
-------
|
||||
|
||||
* [Test binaries now support a `--test-threads` argument to specify the number
|
||||
of threads used to run tests, and which acts the same as the
|
||||
`RUST_TEST_THREADS` environment variable]
|
||||
(https://github.com/rust-lang/rust/pull/35414)
|
||||
* [The test runner now emits a warning when tests run over 60 seconds]
|
||||
(https://github.com/rust-lang/rust/pull/35405)
|
||||
* [rustdoc: Fix methods in search results]
|
||||
(https://github.com/rust-lang/rust/pull/34752)
|
||||
* [`rust-lldb` warns about unsupported versions of LLDB]
|
||||
(https://github.com/rust-lang/rust/pull/34646)
|
||||
* [Rust releases now come with source packages that can be installed by rustup
|
||||
via `rustup component add rust-src`]
|
||||
(https://github.com/rust-lang/rust/pull/34366).
|
||||
The resulting source code can be used by tools and IDES, located in the
|
||||
sysroot under `lib/rustlib/src`.
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
* [The compiler can now be built against LLVM 3.9]
|
||||
(https://github.com/rust-lang/rust/pull/35594)
|
||||
* Many minor improvements to the documentation.
|
||||
* [The Rust exception handling "personality" routine is now written in Rust]
|
||||
(https://github.com/rust-lang/rust/pull/34832)
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
* [When printing Windows `OsStr`s, unpaired surrogate codepoints are escaped
|
||||
with the lowercase format instead of the uppercase]
|
||||
(https://github.com/rust-lang/rust/pull/35084)
|
||||
* [When formatting strings, if "precision" is specified, the "fill",
|
||||
"align" and "width" specifiers are no longer ignored]
|
||||
(https://github.com/rust-lang/rust/pull/34544)
|
||||
* [The `Debug` impl for strings no longer escapes all non-ASCII characters]
|
||||
(https://github.com/rust-lang/rust/pull/34485)
|
||||
|
||||
|
||||
Version 1.11.0 (2016-08-18)
|
||||
===========================
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
* [`cfg_attr` works on `path` attributes]
|
||||
(https://github.com/rust-lang/rust/pull/34546)
|
||||
* [Support nested `cfg_attr` attributes]
|
||||
(https://github.com/rust-lang/rust/pull/34216)
|
||||
* [Allow statement-generating braced macro invocations at the end of blocks]
|
||||
(https://github.com/rust-lang/rust/pull/34436)
|
||||
* [Macros can be expanded inside of trait definitions]
|
||||
(https://github.com/rust-lang/rust/pull/34213)
|
||||
* [`#[macro_use]` works properly when it is itself expanded from a macro]
|
||||
(https://github.com/rust-lang/rust/pull/34032)
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
* [`BinaryHeap::append`]
|
||||
(https://doc.rust-lang.org/std/collections/binary_heap/struct.BinaryHeap.html#method.append)
|
||||
* [`BTreeMap::append`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.append)
|
||||
* [`BTreeMap::split_off`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.split_off)
|
||||
* [`BTreeSet::append`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_set/struct.BTreeSet.html#method.append)
|
||||
* [`BTreeSet::split_off`]
|
||||
(https://doc.rust-lang.org/std/collections/btree_set/struct.BTreeSet.html#method.split_off)
|
||||
* [`f32::to_degrees`]
|
||||
(https://doc.rust-lang.org/std/primitive.f32.html#method.to_degrees)
|
||||
(in libcore - previously stabilized in libstd)
|
||||
* [`f32::to_radians`]
|
||||
(https://doc.rust-lang.org/std/primitive.f32.html#method.to_radians)
|
||||
(in libcore - previously stabilized in libstd)
|
||||
* [`f64::to_degrees`]
|
||||
(https://doc.rust-lang.org/std/primitive.f64.html#method.to_degrees)
|
||||
(in libcore - previously stabilized in libstd)
|
||||
* [`f64::to_radians`]
|
||||
(https://doc.rust-lang.org/std/primitive.f64.html#method.to_radians)
|
||||
(in libcore - previously stabilized in libstd)
|
||||
* [`Iterator::sum`]
|
||||
(https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum)
|
||||
* [`Iterator::product`]
|
||||
(https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum)
|
||||
* [`Cell::get_mut`]
|
||||
(https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut)
|
||||
* [`RefCell::get_mut`]
|
||||
(https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.get_mut)
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
* [The `thread_local!` macro supports multiple definitions in a single
|
||||
invocation, and can apply attributes]
|
||||
(https://github.com/rust-lang/rust/pull/34077)
|
||||
* [`Cow` implements `Default`]
|
||||
(https://github.com/rust-lang/rust/pull/34305)
|
||||
* [`Wrapping` implements binary, octal, lower-hex and upper-hex
|
||||
`Display` formatting]
|
||||
(https://github.com/rust-lang/rust/pull/34190)
|
||||
* [The range types implement `Hash`]
|
||||
(https://github.com/rust-lang/rust/pull/34180)
|
||||
* [`lookup_host` ignores unknown address types]
|
||||
(https://github.com/rust-lang/rust/pull/34067)
|
||||
* [`assert_eq!` accepts a custom error message, like `assert!` does]
|
||||
(https://github.com/rust-lang/rust/pull/33976)
|
||||
* [The main thread is now called "main" instead of "<main>"]
|
||||
(https://github.com/rust-lang/rust/pull/33803)
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
* [Disallow specifying features of transitive deps]
|
||||
(https://github.com/rust-lang/cargo/pull/2821)
|
||||
* [Add color support for Windows consoles]
|
||||
(https://github.com/rust-lang/cargo/pull/2804)
|
||||
* [Fix `harness = false` on `[lib]` sections]
|
||||
(https://github.com/rust-lang/cargo/pull/2795)
|
||||
* [Don't panic when `links` contains a '.']
|
||||
(https://github.com/rust-lang/cargo/pull/2787)
|
||||
* [Build scripts can emit warnings]
|
||||
(https://github.com/rust-lang/cargo/pull/2630),
|
||||
and `-vv` prints warnings for all crates.
|
||||
* [Ignore file locks on OS X NFS mounts]
|
||||
(https://github.com/rust-lang/cargo/pull/2720)
|
||||
* [Don't warn about `package.metadata` keys]
|
||||
(https://github.com/rust-lang/cargo/pull/2668).
|
||||
This provides room for expansion by arbitrary tools.
|
||||
* [Add support for cdylib crate types]
|
||||
(https://github.com/rust-lang/cargo/pull/2741)
|
||||
* [Prevent publishing crates when files are dirty]
|
||||
(https://github.com/rust-lang/cargo/pull/2781)
|
||||
* [Don't fetch all crates on clean]
|
||||
(https://github.com/rust-lang/cargo/pull/2704)
|
||||
* [Propagate --color option to rustc]
|
||||
(https://github.com/rust-lang/cargo/pull/2779)
|
||||
* [Fix `cargo doc --open` on Windows]
|
||||
(https://github.com/rust-lang/cargo/pull/2780)
|
||||
* [Improve autocompletion]
|
||||
(https://github.com/rust-lang/cargo/pull/2772)
|
||||
* [Configure colors of stderr as well as stdout]
|
||||
(https://github.com/rust-lang/cargo/pull/2739)
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
* [Caching projections speeds up type check dramatically for some
|
||||
workloads]
|
||||
(https://github.com/rust-lang/rust/pull/33816)
|
||||
* [The default `HashMap` hasher is SipHash 1-3 instead of SipHash 2-4]
|
||||
(https://github.com/rust-lang/rust/pull/33940)
|
||||
This hasher is faster, but is believed to provide sufficient
|
||||
protection from collision attacks.
|
||||
* [Comparison of `Ipv4Addr` is 10x faster]
|
||||
(https://github.com/rust-lang/rust/pull/33891)
|
||||
|
||||
Rustdoc
|
||||
-------
|
||||
|
||||
* [Fix empty implementation section on some module pages]
|
||||
(https://github.com/rust-lang/rust/pull/34536)
|
||||
* [Fix inlined renamed reexports in import lists]
|
||||
(https://github.com/rust-lang/rust/pull/34479)
|
||||
* [Fix search result layout for enum variants and struct fields]
|
||||
(https://github.com/rust-lang/rust/pull/34477)
|
||||
* [Fix issues with source links to external crates]
|
||||
(https://github.com/rust-lang/rust/pull/34387)
|
||||
* [Fix redirect pages for renamed reexports]
|
||||
(https://github.com/rust-lang/rust/pull/34245)
|
||||
|
||||
Tooling
|
||||
-------
|
||||
|
||||
* [rustc is better at finding the MSVC toolchain]
|
||||
(https://github.com/rust-lang/rust/pull/34492)
|
||||
* [When emitting debug info, rustc emits frame pointers for closures,
|
||||
shims and glue, as it does for all other functions]
|
||||
(https://github.com/rust-lang/rust/pull/33909)
|
||||
* [rust-lldb warns about unsupported versions of LLDB]
|
||||
(https://github.com/rust-lang/rust/pull/34646)
|
||||
* Many more errors have been given error codes and extended
|
||||
explanations
|
||||
* API documentation continues to be improved, with many new examples
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
* [rustc no longer hangs when dependencies recursively re-export
|
||||
submodules]
|
||||
(https://github.com/rust-lang/rust/pull/34542)
|
||||
* [rustc requires LLVM 3.7+]
|
||||
(https://github.com/rust-lang/rust/pull/34104)
|
||||
* [The 'How Safe and Unsafe Interact' chapter of The Rustonomicon was
|
||||
rewritten]
|
||||
(https://github.com/rust-lang/rust/pull/33895)
|
||||
* [rustc support 16-bit pointer sizes]
|
||||
(https://github.com/rust-lang/rust/pull/33460).
|
||||
No targets use this yet, but it works toward AVR support.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
* [`const`s and `static`s may not have unsized types]
|
||||
(https://github.com/rust-lang/rust/pull/34443)
|
||||
* [The new follow-set rules that place restrictions on `macro_rules!`
|
||||
in order to ensure syntax forward-compatibility have been enabled]
|
||||
(https://github.com/rust-lang/rust/pull/33982)
|
||||
This was an [ammendment to RFC 550]
|
||||
(https://github.com/rust-lang/rfcs/pull/1384),
|
||||
and has been a warning since 1.10.
|
||||
* [`cfg` attribute process has been refactored to fix various bugs]
|
||||
(https://github.com/rust-lang/rust/pull/33706).
|
||||
This causes breakage in some corner cases.
|
||||
|
||||
|
||||
Version 1.10.0 (2016-07-07)
|
||||
===========================
|
||||
|
||||
@ -172,7 +608,7 @@ Libraries
|
||||
(https://github.com/rust-lang/rust/pull/33050).
|
||||
* [Implement `Display` and `Hash` for `std::num::Wrapping`]
|
||||
(https://github.com/rust-lang/rust/pull/33023).
|
||||
* [Add `Default` implementation for `&CStr`, `CString`, `Path`]
|
||||
* [Add `Default` implementation for `&CStr`, `CString`]
|
||||
(https://github.com/rust-lang/rust/pull/32990).
|
||||
* [Implement `From<Vec<T>>` and `Into<Vec<T>>` for `VecDeque<T>`]
|
||||
(https://github.com/rust-lang/rust/pull/32866).
|
||||
|
||||
45
configure
vendored
45
configure
vendored
@ -600,7 +600,7 @@ opt debug-assertions 0 "build with debugging assertions"
|
||||
opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
|
||||
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
|
||||
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
|
||||
opt local-rebuild 0 "use an installed rustc matching the current version, for rebuilds"
|
||||
opt local-rebuild 0 "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version"
|
||||
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
|
||||
opt rpath 1 "build rpaths into rustc itself"
|
||||
opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0"
|
||||
@ -609,9 +609,10 @@ opt dist-host-only 0 "only install bins for the host architecture"
|
||||
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
|
||||
opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
|
||||
opt rustbuild 0 "use the rust and cargo based build system"
|
||||
opt orbit 0 "get MIR where it belongs - everywhere; most importantly, in orbit"
|
||||
opt orbit 1 "get MIR where it belongs - everywhere; most importantly, in orbit"
|
||||
opt codegen-tests 1 "run the src/test/codegen tests"
|
||||
opt option-checking 1 "complain about unrecognized options in this configure script"
|
||||
opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
|
||||
|
||||
# Optimization and debugging options. These may be overridden by the release channel, etc.
|
||||
opt_nosave optimize 1 "build optimized rust code"
|
||||
@ -637,10 +638,20 @@ valopt arm-linux-androideabi-ndk "" "arm-linux-androideabi NDK standalone path"
|
||||
valopt armv7-linux-androideabi-ndk "" "armv7-linux-androideabi NDK standalone path"
|
||||
valopt aarch64-linux-android-ndk "" "aarch64-linux-android NDK standalone path"
|
||||
valopt nacl-cross-path "" "NaCl SDK path (Pepper Canary is recommended). Must be absolute!"
|
||||
valopt release-channel "dev" "the name of the release channel to build"
|
||||
valopt musl-root "/usr/local" "MUSL root installation directory"
|
||||
valopt extra-filename "" "Additional data that is hashed and passed to the -C extra-filename flag"
|
||||
|
||||
if [ -e ${CFG_SRC_DIR}.git ]
|
||||
then
|
||||
valopt release-channel "dev" "the name of the release channel to build"
|
||||
else
|
||||
# If we have no git directory then we are probably a tarball distribution
|
||||
# and should default to stable channel - Issue 28322
|
||||
probe CFG_GIT git
|
||||
msg "git: no git directory. Changing default release channel to stable"
|
||||
valopt release-channel "stable" "the name of the release channel to build"
|
||||
fi
|
||||
|
||||
# Used on systems where "cc" and "ar" are unavailable
|
||||
valopt default-linker "cc" "the default linker"
|
||||
valopt default-ar "ar" "the default ar"
|
||||
@ -722,7 +733,7 @@ if [ -n "$CFG_ENABLE_DEBUG_ASSERTIONS" ]; then putvar CFG_ENABLE_DEBUG_ASSERTION
|
||||
if [ -n "$CFG_ENABLE_DEBUGINFO" ]; then putvar CFG_ENABLE_DEBUGINFO; fi
|
||||
if [ -n "$CFG_ENABLE_DEBUG_JEMALLOC" ]; then putvar CFG_ENABLE_DEBUG_JEMALLOC; fi
|
||||
|
||||
if [ -n "$CFG_ENABLE_ORBIT" ]; then putvar CFG_ENABLE_ORBIT; fi
|
||||
if [ -n "$CFG_DISABLE_ORBIT" ]; then putvar CFG_DISABLE_ORBIT; fi
|
||||
|
||||
step_msg "looking for build programs"
|
||||
|
||||
@ -775,6 +786,17 @@ probe CFG_BISON bison
|
||||
probe CFG_GDB gdb
|
||||
probe CFG_LLDB lldb
|
||||
|
||||
if [ -n "$CFG_ENABLE_NINJA" ]
|
||||
then
|
||||
probe CFG_NINJA ninja
|
||||
if [ -z "$CFG_NINJA" ]
|
||||
then
|
||||
# On Debian and Fedora, the `ninja` binary is an IRC bot, so the build tool was
|
||||
# renamed. Handle this case.
|
||||
probe CFG_NINJA ninja-build
|
||||
fi
|
||||
fi
|
||||
|
||||
# For building LLVM
|
||||
probe_need CFG_CMAKE cmake
|
||||
|
||||
@ -991,13 +1013,19 @@ then
|
||||
LLVM_VERSION=$($LLVM_CONFIG --version)
|
||||
|
||||
case $LLVM_VERSION in
|
||||
(3.[7-8]*)
|
||||
(3.[7-9]*)
|
||||
msg "found ok version of LLVM: $LLVM_VERSION"
|
||||
;;
|
||||
(*)
|
||||
err "bad LLVM version: $LLVM_VERSION, need >=3.7"
|
||||
;;
|
||||
esac
|
||||
|
||||
if "$CFG_LLVM_ROOT/bin/llvm-mc" -help | grep -- "-relocation-model"; then
|
||||
msg "found older llvm-mc"
|
||||
CFG_LLVM_MC_HAS_RELOCATION_MODEL=1
|
||||
putvar CFG_LLVM_MC_HAS_RELOCATION_MODEL
|
||||
fi
|
||||
fi
|
||||
|
||||
# Even when the user overrides the choice of CC, still try to detect
|
||||
@ -1170,7 +1198,7 @@ do
|
||||
;;
|
||||
|
||||
|
||||
x86_64-*-musl)
|
||||
x86_64-*-musl | arm-*-musleabi)
|
||||
if [ ! -f $CFG_MUSL_ROOT/lib/libc.a ]
|
||||
then
|
||||
err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found"
|
||||
@ -1524,7 +1552,10 @@ do
|
||||
fi
|
||||
|
||||
# We need the generator later on for compiler-rt even if LLVM's not built
|
||||
if [ ${is_msvc} -ne 0 ]
|
||||
if [ -n "$CFG_NINJA" ]
|
||||
then
|
||||
generator="Ninja"
|
||||
elif [ ${is_msvc} -ne 0 ]
|
||||
then
|
||||
case "$CFG_MSVC_ROOT" in
|
||||
*14.0*)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH RUSTC "1" "August 2015" "rustc 1.2.0" "User Commands"
|
||||
.TH RUSTC "1" "August 2016" "rustc 1.12.0" "User Commands"
|
||||
.SH NAME
|
||||
rustc \- The Rust compiler
|
||||
.SH SYNOPSIS
|
||||
@ -44,7 +44,7 @@ The optional \fIKIND\fR can be one of \fIstatic\fR, \fIdylib\fR, or
|
||||
\fIframework\fR.
|
||||
If omitted, \fIdylib\fR is assumed.
|
||||
.TP
|
||||
\fB\-\-crate\-type\fR [bin|lib|rlib|dylib|staticlib]
|
||||
\fB\-\-crate\-type\fR [bin|lib|rlib|dylib|cdylib|staticlib]
|
||||
Comma separated list of types of crates for the compiler to emit.
|
||||
.TP
|
||||
\fB\-\-crate\-name\fR \fINAME\fR
|
||||
@ -264,7 +264,8 @@ which link to the standard library.
|
||||
.TP
|
||||
\fBRUST_TEST_THREADS\fR
|
||||
The test framework Rust provides executes tests in parallel. This variable sets
|
||||
the maximum number of threads used for this purpose.
|
||||
the maximum number of threads used for this purpose. This setting is overridden
|
||||
by the --test-threads option.
|
||||
|
||||
.TP
|
||||
\fBRUST_TEST_NOCAPTURE\fR
|
||||
@ -299,7 +300,7 @@ To build an executable with debug info:
|
||||
See https://github.com/rust\-lang/rust/issues for issues.
|
||||
|
||||
.SH "AUTHOR"
|
||||
See \fIAUTHORS.txt\fR in the Rust source distribution.
|
||||
See https://github.com/rust\-lang/rust/graphs/contributors or use `git log --all --format='%cN <%cE>' | sort -u` in the rust source distribution.
|
||||
|
||||
.SH "COPYRIGHT"
|
||||
This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH RUSTDOC "1" "August 2015" "rustdoc 1.2.0" "User Commands"
|
||||
.TH RUSTDOC "1" "August 2016" "rustdoc 1.12.0" "User Commands"
|
||||
.SH NAME
|
||||
rustdoc \- generate documentation from Rust source code
|
||||
.SH SYNOPSIS
|
||||
|
||||
@ -17,7 +17,7 @@ CFG_STATIC_LIB_NAME_aarch64-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_aarch64-apple-ios = lib$(1)-*.a.dSYM
|
||||
CFG_CFLAGS_aarch64-apple-ios := $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
|
||||
CFG_JEMALLOC_CFLAGS_aarch64-apple-ios := $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_aarch64-apple-ios := -Wall -Werror -fPIC $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_aarch64-apple-ios := -fPIC $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
|
||||
CFG_GCCISH_CXXFLAGS_aarch64-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios) -I$(CFG_IOS_SDK_aarch64-apple-ios)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_aarch64-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_aarch64-apple-ios) -Wl,-no_compact_unwind
|
||||
CFG_GCCISH_DEF_FLAG_aarch64-apple-ios := -Wl,-exported_symbols_list,
|
||||
|
||||
26
mk/cfg/arm-unknown-linux-musleabi.mk
Normal file
26
mk/cfg/arm-unknown-linux-musleabi.mk
Normal file
@ -0,0 +1,26 @@
|
||||
# arm-unknown-linux-musleabi configuration
|
||||
CROSS_PREFIX_arm-unknown-linux-musleabi=arm-linux-musleabi-
|
||||
CC_arm-unknown-linux-musleabi=gcc
|
||||
CXX_arm-unknown-linux-musleabi=g++
|
||||
CPP_arm-unknown-linux-musleabi=gcc -E
|
||||
AR_arm-unknown-linux-musleabi=ar
|
||||
CFG_LIB_NAME_arm-unknown-linux-musleabi=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_arm-unknown-linux-musleabi=lib$(1).a
|
||||
CFG_LIB_GLOB_arm-unknown-linux-musleabi=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_arm-unknown-linux-musleabi=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_arm-unknown-linux-musleabi := -D__arm__ -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
|
||||
CFG_GCCISH_CFLAGS_arm-unknown-linux-musleabi := -Wall -g -fPIC -D__arm__ -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
|
||||
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-musleabi := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-musleabi := -shared -fPIC -g
|
||||
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-musleabi := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_arm-unknown-linux-musleabi :=
|
||||
CFG_INSTALL_NAME_arm-unknown-linux-musleabi =
|
||||
CFG_EXE_SUFFIX_arm-unknown-linux-musleabi :=
|
||||
CFG_WINDOWSY_arm-unknown-linux-musleabi :=
|
||||
CFG_UNIXY_arm-unknown-linux-musleabi := 1
|
||||
CFG_LDPATH_arm-unknown-linux-musleabi :=
|
||||
CFG_RUN_arm-unknown-linux-musleabi=$(2)
|
||||
CFG_RUN_TARG_arm-unknown-linux-musleabi=$(call CFG_RUN_arm-unknown-linux-musleabi,,$(2))
|
||||
RUSTC_FLAGS_arm-unknown-linux-musleabi :=
|
||||
RUSTC_CROSS_FLAGS_arm-unknown-linux-musleabi :=
|
||||
CFG_GNU_TRIPLE_arm-unknown-linux-musleabi := arm-unknown-linux-musleabi
|
||||
3
mk/cfg/arm-unknown-linux-musleabihf.mk
Normal file
3
mk/cfg/arm-unknown-linux-musleabihf.mk
Normal file
@ -0,0 +1,3 @@
|
||||
# This file is intentially left empty to indicate that, while this target is
|
||||
# supported, it's not supported using plain GNU Make builds. Use a --rustbuild
|
||||
# instead.
|
||||
@ -15,7 +15,7 @@ CFG_INSTALL_ONLY_RLIB_armv7-apple-ios = 1
|
||||
CFG_STATIC_LIB_NAME_armv7-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_armv7-apple-ios = lib$(1)-*.a.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_armv7-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_SDK_FLAGS_armv7-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_armv7-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -mfpu=vfp3 -arch armv7
|
||||
CFG_GCCISH_CFLAGS_armv7-apple-ios := -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -mfpu=vfp3 -arch armv7
|
||||
CFG_GCCISH_CXXFLAGS_armv7-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -I$(CFG_IOS_SDK_armv7-apple-ios)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_armv7-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7-apple-ios) -Wl,-no_compact_unwind
|
||||
CFG_GCCISH_DEF_FLAG_armv7-apple-ios := -Wl,-exported_symbols_list,
|
||||
|
||||
3
mk/cfg/armv7-unknown-linux-musleabihf.mk
Normal file
3
mk/cfg/armv7-unknown-linux-musleabihf.mk
Normal file
@ -0,0 +1,3 @@
|
||||
# This file is intentially left empty to indicate that, while this target is
|
||||
# supported, it's not supported using plain GNU Make builds. Use a --rustbuild
|
||||
# instead.
|
||||
@ -15,7 +15,7 @@ CFG_INSTALL_ONLY_RLIB_armv7s-apple-ios = 1
|
||||
CFG_STATIC_LIB_NAME_armv7s-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_armv7s-apple-ios = lib$(1)-*.a.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_armv7s-apple-ios := -arch armv7s $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -arch armv7s
|
||||
CFG_GCCISH_CFLAGS_armv7s-apple-ios := -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -arch armv7s
|
||||
CFG_GCCISH_CXXFLAGS_armv7s-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -I$(CFG_IOS_SDK_armv7s-apple-ios)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_armv7s-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7s-apple-ios) -Wl,-no_compact_unwind
|
||||
CFG_GCCISH_DEF_FLAG_armv7s-apple-ios := -Wl,-exported_symbols_list,
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_asmjs-unknown-emscripten=lib$(1).a
|
||||
CFG_LIB_GLOB_asmjs-unknown-emscripten=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_asmjs-unknown-emscripten=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_asmjs-unknown-emscripten := -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_asmjs-unknown-emscripten := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_asmjs-unknown-emscripten := -g -fPIC -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_asmjs-unknown-emscripten := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_asmjs-unknown-emscripten := -shared -fPIC -ldl -pthread -lrt -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_asmjs-unknown-emscripten := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -14,7 +14,7 @@ CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
|
||||
CFG_INSTALL_ONLY_RLIB_i386-apple-ios = 1
|
||||
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
|
||||
CFG_GCCISH_CFLAGS_i386-apple-ios := -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS_i386-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_i386-apple-ios := -g -fPIC -m32 $(CFG_IOSSIM_FLAGS_i386-apple-ios)
|
||||
CFG_GCCISH_CXXFLAGS_i386-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_i386-apple-ios) -I$(CFG_IOSSIM_SDK_i386-apple-ios)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_i386-apple-ios := -lpthread -m32 -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK_i386-apple-ios)
|
||||
CFG_GCCISH_DEF_FLAG_i386-apple-ios := -Wl,-exported_symbols_list,
|
||||
|
||||
@ -7,8 +7,8 @@ CFG_LIB_NAME_i586-unknown-linux-gnu=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_i586-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_i586-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_i586-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_i586-unknown-linux-gnu := -m32 $(CFLAGS) -march=pentium
|
||||
CFG_GCCISH_CFLAGS_i586-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=pentium
|
||||
CFG_JEMALLOC_CFLAGS_i586-unknown-linux-gnu := -m32 $(CFLAGS) -march=pentium -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CFLAGS_i586-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS) -march=pentium -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CXXFLAGS_i586-unknown-linux-gnu := -fno-rtti $(CXXFLAGS) -march=pentium
|
||||
CFG_GCCISH_LINK_FLAGS_i586-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i586-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
|
||||
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
|
||||
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-apple-darwin := -g -fPIC -m32 -arch i386 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
|
||||
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_i686-pc-windows-gnu=$(1).lib
|
||||
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -g -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i686-pc-windows-gnu :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_i686-unknown-freebsd=lib$(1).a
|
||||
CFG_LIB_GLOB_i686-unknown-freebsd=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_i686-unknown-freebsd=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_i686-unknown-freebsd := -m32 -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-freebsd := -Wall -Werror -g -fPIC -m32 -arch i386 -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-freebsd := -g -fPIC -m32 -arch i386 -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-unknown-freebsd := -m32 -shared -fPIC -g -pthread -lrt
|
||||
CFG_GCCISH_DEF_FLAG_i686-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_i686-unknown-freebsd :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=i686
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS) -march=i686
|
||||
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -7,8 +7,8 @@ CFG_INSTALL_ONLY_RLIB_i686-unknown-linux-musl = 1
|
||||
CFG_LIB_NAME_i686-unknown-linux-musl=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_i686-unknown-linux-musl=lib$(1).a
|
||||
CFG_LIB_GLOB_i686-unknown-linux-musl=lib$(1)-*.so
|
||||
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-musl := -m32 -Wl,-melf_i386
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-linux-musl := -Wall -Werror -g -fPIC -m32 -Wl,-melf_i386
|
||||
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-musl := -m32 -Wl,-melf_i386 -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CFLAGS_i686-unknown-linux-musl := -g -fPIC -m32 -Wl,-melf_i386 -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-musl :=
|
||||
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-musl :=
|
||||
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-musl :=
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_powerpc-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_powerpc-unknown-linux-gnu := -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_powerpc-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_powerpc-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_powerpc-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -10,7 +10,7 @@ CFG_LIB_GLOB_powerpc64-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_powerpc64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_powerpc64-unknown-linux-gnu := -m64
|
||||
CFG_CFLAGS_powerpc64-unknown-linux-gnu := -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc64-unknown-linux-gnu := -g -fPIC -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_powerpc64-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_powerpc64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_powerpc64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_powerpc64le-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_powerpc64le-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_powerpc64le-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_powerpc64le-unknown-linux-gnu := -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc64le-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc64le-unknown-linux-gnu := -g -fPIC -m64 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_powerpc64le-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_powerpc64le-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_powerpc64le-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
|
||||
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -g -fPIC -m64 -arch x86_64 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
|
||||
|
||||
@ -16,7 +16,7 @@ CFG_STATIC_LIB_NAME_x86_64-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_x86_64-apple-ios = lib$(1)-*.a.dSYM
|
||||
CFG_CFLAGS_x86_64-apple-ios := $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-apple-ios := $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_x86_64-apple-ios := -Wall -Werror -fPIC $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
|
||||
CFG_GCCISH_CFLAGS_x86_64-apple-ios := -fPIC $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_x86_64-apple-ios) -I$(CFG_IOSSIM_SDK_x86_64-apple-ios)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-apple-ios := -lpthread -Wl,-no_compact_unwind -m64 -Wl,-syslibroot $(CFG_IOSSIM_SDK_x86_64-apple-ios)
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-apple-ios := -Wl,-exported_symbols_list,
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_x86_64-pc-windows-gnu=$(1).lib
|
||||
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -g -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-gnu :=
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_LIB_NAME_x86_64-rumprun-netbsd=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_x86_64-rumprun-netbsd=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-rumprun-netbsd=lib$(1)-*.so
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-rumprun-netbsd := -m64
|
||||
CFG_GCCISH_CFLAGS_x86_64-rumprun-netbsd := -Wall -Werror -g -fPIC -m64
|
||||
CFG_GCCISH_CFLAGS_x86_64-rumprun-netbsd := -g -fPIC -m64
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-rumprun-netbsd :=
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-rumprun-netbsd :=
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-rumprun-netbsd :=
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_x86_64-sun-solaris=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-sun-solaris=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-sun-solaris=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-sun-solaris := -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-sun-solaris := -Wall -Werror -g -D_POSIX_PTHREAD_SEMANTICS -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-sun-solaris := -g -D_POSIX_PTHREAD_SEMANTICS -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-sun-solaris := -shared -fPIC -g -pthread -lrt
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-sun-solaris := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-sun-solaris :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-bitrig=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-bitrig=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-bitrig=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-bitrig := -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -Wall -Werror -fPIE -fPIC -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -fPIE -fPIC -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 $(LDFLAGS)
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-bitrig := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-unknown-bitrig :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-dragonfly := -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -g -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-gnu := -m64
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -g -fPIC -m64
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
|
||||
@ -7,8 +7,8 @@ CFG_INSTALL_ONLY_RLIB_x86_64-unknown-linux-musl = 1
|
||||
CFG_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-linux-musl=lib$(1)-*.so
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -Wall -Werror -g -fPIC -m64
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64 -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -g -fPIC -m64 -Wa,-mrelax-relocations=no
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-musl :=
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-musl :=
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-musl :=
|
||||
|
||||
@ -9,7 +9,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-netbsd=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-netbsd=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-netbsd=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-netbsd := -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-netbsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-netbsd := -g -fPIC -I/usr/local/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-netbsd := -shared -fPIC -g -pthread -lrt
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-netbsd := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-unknown-netbsd :=
|
||||
|
||||
@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_x86_64-unknown-openbsd=lib$(1).a
|
||||
CFG_LIB_GLOB_x86_64-unknown-openbsd=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-openbsd=$(1)-*.dylib.dSYM
|
||||
CFG_JEMALLOC_CFLAGS_x86_64-unknown-openbsd := -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-openbsd := -Wall -Werror -g -fPIC -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-unknown-openbsd := -g -fPIC -m64 -I/usr/include $(CFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-openbsd := -shared -fPIC -g -pthread -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-openbsd := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_LLC_FLAGS_x86_64-unknown-openbsd :=
|
||||
|
||||
33
mk/dist.mk
33
mk/dist.mk
@ -24,6 +24,7 @@ PKG_NAME := $(CFG_PACKAGE_NAME)
|
||||
STD_PKG_NAME := rust-std-$(CFG_PACKAGE_VERS)
|
||||
DOC_PKG_NAME := rust-docs-$(CFG_PACKAGE_VERS)
|
||||
MINGW_PKG_NAME := rust-mingw-$(CFG_PACKAGE_VERS)
|
||||
SRC_PKG_NAME := rust-src-$(CFG_PACKAGE_VERS)
|
||||
|
||||
# License suitable for displaying in a popup
|
||||
LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT
|
||||
@ -71,10 +72,10 @@ PKG_FILES := \
|
||||
|
||||
UNROOTED_PKG_FILES := $(patsubst $(S)%,./%,$(PKG_FILES))
|
||||
|
||||
$(PKG_TAR): $(PKG_FILES)
|
||||
@$(call E, making dist dir)
|
||||
$(Q)rm -Rf tmp/dist/$(PKG_NAME)
|
||||
$(Q)mkdir -p tmp/dist/$(PKG_NAME)
|
||||
tmp/dist/$$(SRC_PKG_NAME)-image: $(PKG_FILES)
|
||||
@$(call E, making src image)
|
||||
$(Q)rm -Rf tmp/dist/$(SRC_PKG_NAME)-image
|
||||
$(Q)mkdir -p tmp/dist/$(SRC_PKG_NAME)-image/lib/rustlib/src/rust
|
||||
$(Q)tar \
|
||||
-C $(S) \
|
||||
-f - \
|
||||
@ -87,10 +88,11 @@ $(PKG_TAR): $(PKG_FILES)
|
||||
--exclude=*/llvm/test/*/*/*.ll \
|
||||
--exclude=*/llvm/test/*/*/*.td \
|
||||
--exclude=*/llvm/test/*/*/*.s \
|
||||
-c $(UNROOTED_PKG_FILES) | tar -x -f - -C tmp/dist/$(PKG_NAME)
|
||||
-c $(UNROOTED_PKG_FILES) | tar -x -f - -C tmp/dist/$(SRC_PKG_NAME)-image/lib/rustlib/src/rust
|
||||
|
||||
$(PKG_TAR): tmp/dist/$$(SRC_PKG_NAME)-image
|
||||
@$(call E, making $@)
|
||||
$(Q)tar -czf $(PKG_TAR) -C tmp/dist $(PKG_NAME)
|
||||
$(Q)rm -Rf tmp/dist/$(PKG_NAME)
|
||||
$(Q)tar -czf $(PKG_TAR) -C tmp/dist/$(SRC_PKG_NAME)-image/lib/rustlib/src rust --transform 's,^rust,$(PKG_NAME),S'
|
||||
|
||||
dist-tar-src: $(PKG_TAR)
|
||||
|
||||
@ -259,6 +261,19 @@ endef
|
||||
$(foreach host,$(CFG_HOST),\
|
||||
$(eval $(call DEF_INSTALLER,$(host))))
|
||||
|
||||
dist/$(SRC_PKG_NAME).tar.gz: tmp/dist/$(SRC_PKG_NAME)-image
|
||||
@$(call E, build: $@)
|
||||
$(Q)$(S)src/rust-installer/gen-installer.sh \
|
||||
--product-name=Rust \
|
||||
--rel-manifest-dir=rustlib \
|
||||
--success-message=Awesome-Source. \
|
||||
--image-dir=tmp/dist/$(SRC_PKG_NAME)-image \
|
||||
--work-dir=tmp/dist \
|
||||
--output-dir=dist \
|
||||
--package-name=$(SRC_PKG_NAME) \
|
||||
--component-name=rust-src \
|
||||
--legacy-manifest-dirs=rustlib,cargo
|
||||
|
||||
# When generating packages for the standard library, we've actually got a lot of
|
||||
# artifacts to choose from. Each of the CFG_HOST compilers will have a copy of
|
||||
# the standard library for each CFG_TARGET, but we only want to generate one
|
||||
@ -329,8 +344,8 @@ distcheck-docs: dist-docs
|
||||
# Primary targets (dist, distcheck)
|
||||
######################################################################
|
||||
|
||||
MAYBE_DIST_TAR_SRC=dist-tar-src
|
||||
MAYBE_DISTCHECK_TAR_SRC=distcheck-tar-src
|
||||
MAYBE_DIST_TAR_SRC=dist-tar-src dist/$(SRC_PKG_NAME).tar.gz
|
||||
MAYBE_DISTCHECK_TAR_SRC=distcheck-tar-src dist/$(SRC_PKG_NAME).tar.gz
|
||||
|
||||
# FIXME #13224: On OS X don't produce tarballs simply because --exclude-vcs don't work.
|
||||
# This is a huge hack because I just don't have time to figure out another solution.
|
||||
|
||||
14
mk/llvm.mk
14
mk/llvm.mk
@ -43,7 +43,9 @@ $$(LLVM_CONFIG_$(1)): $$(LLVM_DONE_$(1))
|
||||
|
||||
$$(LLVM_DONE_$(1)): $$(LLVM_DEPS_TARGET_$(1)) $$(LLVM_STAMP_$(1))
|
||||
@$$(call E, cmake: llvm)
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
ifneq ($$(CFG_NINJA),)
|
||||
$$(Q)$$(CFG_NINJA) -C $$(CFG_LLVM_BUILD_DIR_$(1))
|
||||
else ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE)
|
||||
else
|
||||
@ -51,8 +53,16 @@ else
|
||||
endif
|
||||
$$(Q)touch $$@
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
ifneq ($$(CFG_NINJA),)
|
||||
clean-llvm$(1):
|
||||
@$$(call E, clean: llvm)
|
||||
$$(Q)$$(CFG_NINJA) -C $$(CFG_LLVM_BUILD_DIR_$(1)) -t clean
|
||||
else ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
clean-llvm$(1):
|
||||
@$$(call E, clean: llvm)
|
||||
$$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE) \
|
||||
--target clean
|
||||
else
|
||||
clean-llvm$(1):
|
||||
@$$(call E, clean: llvm)
|
||||
|
||||
66
mk/main.mk
66
mk/main.mk
@ -13,35 +13,12 @@
|
||||
######################################################################
|
||||
|
||||
# The version number
|
||||
CFG_RELEASE_NUM=1.11.0
|
||||
CFG_RELEASE_NUM=1.12.0
|
||||
|
||||
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
|
||||
# NB Make sure it starts with a dot to conform to semver pre-release
|
||||
# versions (section 9)
|
||||
CFG_PRERELEASE_VERSION=.3
|
||||
|
||||
# Append a version-dependent hash to each library, so we can install different
|
||||
# versions in the same place
|
||||
CFG_FILENAME_EXTRA=$(shell printf '%s' $(CFG_RELEASE)$(CFG_EXTRA_FILENAME) | $(CFG_HASH_COMMAND))
|
||||
|
||||
# A magic value that allows the compiler to use unstable features during the
|
||||
# bootstrap even when doing so would normally be an error because of feature
|
||||
# staging or because the build turns on warnings-as-errors and unstable features
|
||||
# default to warnings. The build has to match this key in an env var.
|
||||
#
|
||||
# This value is keyed off the release to ensure that all compilers for one
|
||||
# particular release have the same bootstrap key. Note that this is
|
||||
# intentionally not "secure" by any definition, this is largely just a deterrent
|
||||
# from users enabling unstable features on the stable compiler.
|
||||
CFG_BOOTSTRAP_KEY=$(CFG_FILENAME_EXTRA)
|
||||
|
||||
# The stage0 compiler needs to use the previous key recorded in src/stage0.txt,
|
||||
# except for local-rebuild when it just uses the same current key.
|
||||
ifdef CFG_ENABLE_LOCAL_REBUILD
|
||||
CFG_BOOTSTRAP_KEY_STAGE0=$(CFG_BOOTSTRAP_KEY)
|
||||
else
|
||||
CFG_BOOTSTRAP_KEY_STAGE0=$(shell grep 'rustc_key' $(S)src/stage0.txt | sed 's/rustc_key: '//)
|
||||
endif
|
||||
CFG_PRERELEASE_VERSION=.6
|
||||
|
||||
ifeq ($(CFG_RELEASE_CHANNEL),stable)
|
||||
# This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly"
|
||||
@ -72,6 +49,38 @@ CFG_RELEASE=$(CFG_RELEASE_NUM)-dev
|
||||
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-dev
|
||||
endif
|
||||
|
||||
# Append a version-dependent hash to each library, so we can install different
|
||||
# versions in the same place
|
||||
CFG_FILENAME_EXTRA=$(shell printf '%s' $(CFG_RELEASE)$(CFG_EXTRA_FILENAME) | $(CFG_HASH_COMMAND))
|
||||
|
||||
# A magic value that allows the compiler to use unstable features during the
|
||||
# bootstrap even when doing so would normally be an error because of feature
|
||||
# staging or because the build turns on warnings-as-errors and unstable features
|
||||
# default to warnings. The build has to match this key in an env var.
|
||||
#
|
||||
# This value is keyed off the release to ensure that all compilers for one
|
||||
# particular release have the same bootstrap key. Note that this is
|
||||
# intentionally not "secure" by any definition, this is largely just a deterrent
|
||||
# from users enabling unstable features on the stable compiler.
|
||||
CFG_BOOTSTRAP_KEY=$(CFG_FILENAME_EXTRA)
|
||||
|
||||
# If local-rust is the same as the current version, then force a local-rebuild
|
||||
ifdef CFG_ENABLE_LOCAL_RUST
|
||||
ifeq ($(CFG_RELEASE),\
|
||||
$(shell $(S)src/etc/local_stage0.sh --print-rustc-release $(CFG_LOCAL_RUST_ROOT)))
|
||||
CFG_INFO := $(info cfg: auto-detected local-rebuild $(CFG_RELEASE))
|
||||
CFG_ENABLE_LOCAL_REBUILD = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
# The stage0 compiler needs to use the previous key recorded in src/stage0.txt,
|
||||
# except for local-rebuild when it just uses the same current key.
|
||||
ifdef CFG_ENABLE_LOCAL_REBUILD
|
||||
CFG_BOOTSTRAP_KEY_STAGE0=$(CFG_BOOTSTRAP_KEY)
|
||||
else
|
||||
CFG_BOOTSTRAP_KEY_STAGE0=$(shell sed -ne 's/^rustc_key: //p' $(S)src/stage0.txt)
|
||||
endif
|
||||
|
||||
# The name of the package to use for creating tarballs, installers etc.
|
||||
CFG_PACKAGE_NAME=rustc-$(CFG_PACKAGE_VERS)
|
||||
|
||||
@ -153,9 +162,10 @@ ifdef CFG_ENABLE_DEBUGINFO
|
||||
CFG_RUSTC_FLAGS += -g
|
||||
endif
|
||||
|
||||
ifdef CFG_ENABLE_ORBIT
|
||||
$(info cfg: launching MIR (CFG_ENABLE_ORBIT))
|
||||
CFG_RUSTC_FLAGS += -Z orbit
|
||||
ifdef CFG_DISABLE_ORBIT
|
||||
$(info cfg: HOLD HOLD HOLD (CFG_DISABLE_ORBIT))
|
||||
RUSTFLAGS_STAGE1 += -Z orbit=off
|
||||
RUSTFLAGS_STAGE2 += -Z orbit=off
|
||||
endif
|
||||
|
||||
ifdef SAVE_TEMPS
|
||||
|
||||
@ -221,12 +221,19 @@ define CFG_MAKE_TOOLCHAIN
|
||||
LLVM_MC_RELOCATION_MODEL="default"
|
||||
endif
|
||||
|
||||
# LLVM changed this flag in 3.9
|
||||
ifdef CFG_LLVM_MC_HAS_RELOCATION_MODEL
|
||||
LLVM_MC_RELOC_FLAG := -relocation-model=$$(LLVM_MC_RELOCATION_MODEL)
|
||||
else
|
||||
LLVM_MC_RELOC_FLAG := -position-independent
|
||||
endif
|
||||
|
||||
# We're using llvm-mc as our assembler because it supports
|
||||
# .cfi pseudo-ops on mac
|
||||
CFG_ASSEMBLE_$(1)=$$(CPP_$(1)) -E $$(2) | \
|
||||
$$(LLVM_MC_$$(CFG_BUILD)) \
|
||||
-assemble \
|
||||
-relocation-model=$$(LLVM_MC_RELOCATION_MODEL) \
|
||||
$$(LLVM_MC_RELOC_FLAG) \
|
||||
-filetype=obj \
|
||||
-triple=$(1) \
|
||||
-o=$$(1)
|
||||
|
||||
475
mk/rt.mk
475
mk/rt.mk
@ -223,141 +223,378 @@ endif
|
||||
# compiler-rt
|
||||
################################################################################
|
||||
|
||||
ifdef CFG_ENABLE_FAST_MAKE
|
||||
COMPRT_DEPS := $(S)/.gitmodules
|
||||
else
|
||||
COMPRT_DEPS := $(wildcard \
|
||||
$(S)src/compiler-rt/* \
|
||||
$(S)src/compiler-rt/*/* \
|
||||
$(S)src/compiler-rt/*/*/* \
|
||||
$(S)src/compiler-rt/*/*/*/*)
|
||||
endif
|
||||
|
||||
# compiler-rt's build system is a godawful mess. Here we figure out
|
||||
# the ridiculous platform-specific values and paths necessary to get
|
||||
# useful artifacts out of it.
|
||||
# Everything below is a manual compilation of compiler-rt, disregarding its
|
||||
# build system. See comments in `src/bootstrap/native.rs` for more information.
|
||||
|
||||
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
|
||||
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
|
||||
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
|
||||
|
||||
COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1)))
|
||||
|
||||
# All this is to figure out the path to the compiler-rt bin
|
||||
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
|
||||
COMPRT_DIR_$(1) := windows/Release
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1)))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
|
||||
COMPRT_DIR_$(1) := windows
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring darwin,$(1)),darwin)
|
||||
COMPRT_DIR_$(1) := builtins
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring ios,$(1)),ios)
|
||||
COMPRT_DIR_$(1) := builtins
|
||||
COMPRT_ARCH_$(1) := $$(patsubst armv7s,armv7em,$$(COMPRT_ARCH_$(1)))
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.hard_pic_$$(COMPRT_ARCH_$(1))_macho_embedded
|
||||
ifeq ($$(COMPRT_ARCH_$(1)),aarch64)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_arm64_ios
|
||||
endif
|
||||
COMPRT_DEFINES_$(1) := -DCOMPILER_RT_ENABLE_IOS=ON
|
||||
endif
|
||||
|
||||
ifndef COMPRT_DIR_$(1)
|
||||
# NB: FreeBSD and NetBSD output to "linux"...
|
||||
COMPRT_DIR_$(1) := linux
|
||||
COMPRT_ARCH_$(1) := $$(patsubst i586,i386,$$(COMPRT_ARCH_$(1)))
|
||||
|
||||
ifeq ($$(findstring android,$(1)),android)
|
||||
ifeq ($$(findstring arm,$$(COMPRT_ARCH_$(1))),arm)
|
||||
COMPRT_ARCH_$(1) := armhf
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring eabihf,$(1)),eabihf)
|
||||
ifeq ($$(findstring armv7,$(1)),)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-armhf
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef COMPRT_LIB_NAME_$(1)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
|
||||
COMPRT_LIB_FILE_$(1) := lib$$(COMPRT_LIB_NAME_$(1)).a
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring android,$(1)),android)
|
||||
ifeq ($$(findstring arm,$(1)),arm)
|
||||
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))-android)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef COMPRT_LIB_FILE_$(1)
|
||||
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1)))
|
||||
endif
|
||||
|
||||
COMPRT_OUTPUT_$(1) := $$(COMPRT_BUILD_DIR_$(1))/lib/$$(COMPRT_DIR_$(1))/$$(COMPRT_LIB_FILE_$(1))
|
||||
|
||||
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
|
||||
COMPRT_BUILD_ARGS_$(1) := //v:m //nologo
|
||||
COMPRT_BUILD_TARGET_$(1) := lib/builtins/builtins
|
||||
COMPRT_BUILD_CC_$(1) :=
|
||||
else
|
||||
COMPRT_BUILD_ARGS_$(1) :=
|
||||
ifndef COMPRT_BUILD_TARGET_$(1)
|
||||
COMPRT_BUILD_TARGET_$(1) := $$(COMPRT_LIB_NAME_$(1))
|
||||
endif
|
||||
COMPRT_BUILD_CC_$(1) := -DCMAKE_C_COMPILER=$$(call FIND_COMPILER,$$(CC_$(1))) \
|
||||
-DCMAKE_CXX_COMPILER=$$(call FIND_COMPILER,$$(CXX_$(1)))
|
||||
# GENERIC_SOURCES in CMakeLists.txt
|
||||
COMPRT_OBJS_$(1) := \
|
||||
absvdi2.o \
|
||||
absvsi2.o \
|
||||
adddf3.o \
|
||||
addsf3.o \
|
||||
addvdi3.o \
|
||||
addvsi3.o \
|
||||
apple_versioning.o \
|
||||
ashldi3.o \
|
||||
ashrdi3.o \
|
||||
clear_cache.o \
|
||||
clzdi2.o \
|
||||
clzsi2.o \
|
||||
cmpdi2.o \
|
||||
comparedf2.o \
|
||||
comparesf2.o \
|
||||
ctzdi2.o \
|
||||
ctzsi2.o \
|
||||
divdc3.o \
|
||||
divdf3.o \
|
||||
divdi3.o \
|
||||
divmoddi4.o \
|
||||
divmodsi4.o \
|
||||
divsc3.o \
|
||||
divsf3.o \
|
||||
divsi3.o \
|
||||
divxc3.o \
|
||||
extendsfdf2.o \
|
||||
extendhfsf2.o \
|
||||
ffsdi2.o \
|
||||
fixdfdi.o \
|
||||
fixdfsi.o \
|
||||
fixsfdi.o \
|
||||
fixsfsi.o \
|
||||
fixunsdfdi.o \
|
||||
fixunsdfsi.o \
|
||||
fixunssfdi.o \
|
||||
fixunssfsi.o \
|
||||
fixunsxfdi.o \
|
||||
fixunsxfsi.o \
|
||||
fixxfdi.o \
|
||||
floatdidf.o \
|
||||
floatdisf.o \
|
||||
floatdixf.o \
|
||||
floatsidf.o \
|
||||
floatsisf.o \
|
||||
floatundidf.o \
|
||||
floatundisf.o \
|
||||
floatundixf.o \
|
||||
floatunsidf.o \
|
||||
floatunsisf.o \
|
||||
int_util.o \
|
||||
lshrdi3.o \
|
||||
moddi3.o \
|
||||
modsi3.o \
|
||||
muldc3.o \
|
||||
muldf3.o \
|
||||
muldi3.o \
|
||||
mulodi4.o \
|
||||
mulosi4.o \
|
||||
muloti4.o \
|
||||
mulsc3.o \
|
||||
mulsf3.o \
|
||||
mulvdi3.o \
|
||||
mulvsi3.o \
|
||||
mulxc3.o \
|
||||
negdf2.o \
|
||||
negdi2.o \
|
||||
negsf2.o \
|
||||
negvdi2.o \
|
||||
negvsi2.o \
|
||||
paritydi2.o \
|
||||
paritysi2.o \
|
||||
popcountdi2.o \
|
||||
popcountsi2.o \
|
||||
powidf2.o \
|
||||
powisf2.o \
|
||||
powixf2.o \
|
||||
subdf3.o \
|
||||
subsf3.o \
|
||||
subvdi3.o \
|
||||
subvsi3.o \
|
||||
truncdfhf2.o \
|
||||
truncdfsf2.o \
|
||||
truncsfhf2.o \
|
||||
ucmpdi2.o \
|
||||
udivdi3.o \
|
||||
udivmoddi4.o \
|
||||
udivmodsi4.o \
|
||||
udivsi3.o \
|
||||
umoddi3.o \
|
||||
umodsi3.o
|
||||
|
||||
ifeq ($$(findstring ios,$(1)),)
|
||||
COMPRT_BUILD_CC_$(1) := $$(COMPRT_BUILD_CC_$(1)) \
|
||||
-DCMAKE_C_FLAGS="$$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error"
|
||||
COMPRT_OBJS_$(1) += \
|
||||
absvti2.o \
|
||||
addtf3.o \
|
||||
addvti3.o \
|
||||
ashlti3.o \
|
||||
ashrti3.o \
|
||||
clzti2.o \
|
||||
cmpti2.o \
|
||||
ctzti2.o \
|
||||
divtf3.o \
|
||||
divti3.o \
|
||||
ffsti2.o \
|
||||
fixdfti.o \
|
||||
fixsfti.o \
|
||||
fixunsdfti.o \
|
||||
fixunssfti.o \
|
||||
fixunsxfti.o \
|
||||
fixxfti.o \
|
||||
floattidf.o \
|
||||
floattisf.o \
|
||||
floattixf.o \
|
||||
floatuntidf.o \
|
||||
floatuntisf.o \
|
||||
floatuntixf.o \
|
||||
lshrti3.o \
|
||||
modti3.o \
|
||||
multf3.o \
|
||||
multi3.o \
|
||||
mulvti3.o \
|
||||
negti2.o \
|
||||
negvti2.o \
|
||||
parityti2.o \
|
||||
popcountti2.o \
|
||||
powitf2.o \
|
||||
subtf3.o \
|
||||
subvti3.o \
|
||||
trampoline_setup.o \
|
||||
ucmpti2.o \
|
||||
udivmodti4.o \
|
||||
udivti3.o \
|
||||
umodti3.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring apple,$(1)),apple)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
atomic_flag_clear.o \
|
||||
atomic_flag_clear_explicit.o \
|
||||
atomic_flag_test_and_set.o \
|
||||
atomic_flag_test_and_set_explicit.o \
|
||||
atomic_signal_fence.o \
|
||||
atomic_thread_fence.o
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($$(findstring windows,$(1)),)
|
||||
COMPRT_OBJS_$(1) += emutls.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),)
|
||||
|
||||
ifeq ($$(findstring freebsd,$(1)),)
|
||||
COMPRT_OBJS_$(1) += gcc_personality_v0.o
|
||||
endif
|
||||
|
||||
COMPRT_OBJS_$(1) += emutls.o
|
||||
|
||||
ifeq ($$(findstring x86_64,$(1)),x86_64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
x86_64/chkstk.o \
|
||||
x86_64/chkstk2.o \
|
||||
x86_64/floatdidf.o \
|
||||
x86_64/floatdisf.o \
|
||||
x86_64/floatdixf.o \
|
||||
x86_64/floatundidf.o \
|
||||
x86_64/floatundisf.o \
|
||||
x86_64/floatundixf.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring i686,$$(patsubts i%86,i686,$(1))),i686)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
i386/ashldi3.o \
|
||||
i386/ashrdi3.o \
|
||||
i386/chkstk.o \
|
||||
i386/chkstk2.o \
|
||||
i386/divdi3.o \
|
||||
i386/floatdidf.o \
|
||||
i386/floatdisf.o \
|
||||
i386/floatdixf.o \
|
||||
i386/floatundidf.o \
|
||||
i386/floatundisf.o \
|
||||
i386/floatundixf.o \
|
||||
i386/lshrdi3.o \
|
||||
i386/moddi3.o \
|
||||
i386/muldi3.o \
|
||||
i386/udivdi3.o \
|
||||
i386/umoddi3.o
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
ifeq ($$(findstring x86_64,$(1)),x86_64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
x86_64/floatdidf.o \
|
||||
x86_64/floatdisf.o \
|
||||
x86_64/floatdixf.o
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# Generic ARM sources, nothing compiles on iOS though
|
||||
ifeq ($$(findstring arm,$(1)),arm)
|
||||
ifeq ($$(findstring ios,$(1)),)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/aeabi_cdcmp.o \
|
||||
arm/aeabi_cdcmpeq_check_nan.o \
|
||||
arm/aeabi_cfcmp.o \
|
||||
arm/aeabi_cfcmpeq_check_nan.o \
|
||||
arm/aeabi_dcmp.o \
|
||||
arm/aeabi_div0.o \
|
||||
arm/aeabi_drsub.o \
|
||||
arm/aeabi_fcmp.o \
|
||||
arm/aeabi_frsub.o \
|
||||
arm/aeabi_idivmod.o \
|
||||
arm/aeabi_ldivmod.o \
|
||||
arm/aeabi_memcmp.o \
|
||||
arm/aeabi_memcpy.o \
|
||||
arm/aeabi_memmove.o \
|
||||
arm/aeabi_memset.o \
|
||||
arm/aeabi_uidivmod.o \
|
||||
arm/aeabi_uldivmod.o \
|
||||
arm/bswapdi2.o \
|
||||
arm/bswapsi2.o \
|
||||
arm/clzdi2.o \
|
||||
arm/clzsi2.o \
|
||||
arm/comparesf2.o \
|
||||
arm/divmodsi4.o \
|
||||
arm/divsi3.o \
|
||||
arm/modsi3.o \
|
||||
arm/switch16.o \
|
||||
arm/switch32.o \
|
||||
arm/switch8.o \
|
||||
arm/switchu8.o \
|
||||
arm/sync_synchronize.o \
|
||||
arm/udivmodsi4.o \
|
||||
arm/udivsi3.o \
|
||||
arm/umodsi3.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# Thumb sources
|
||||
ifeq ($$(findstring armv7,$(1)),armv7)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/sync_fetch_and_add_4.o \
|
||||
arm/sync_fetch_and_add_8.o \
|
||||
arm/sync_fetch_and_and_4.o \
|
||||
arm/sync_fetch_and_and_8.o \
|
||||
arm/sync_fetch_and_max_4.o \
|
||||
arm/sync_fetch_and_max_8.o \
|
||||
arm/sync_fetch_and_min_4.o \
|
||||
arm/sync_fetch_and_min_8.o \
|
||||
arm/sync_fetch_and_nand_4.o \
|
||||
arm/sync_fetch_and_nand_8.o \
|
||||
arm/sync_fetch_and_or_4.o \
|
||||
arm/sync_fetch_and_or_8.o \
|
||||
arm/sync_fetch_and_sub_4.o \
|
||||
arm/sync_fetch_and_sub_8.o \
|
||||
arm/sync_fetch_and_umax_4.o \
|
||||
arm/sync_fetch_and_umax_8.o \
|
||||
arm/sync_fetch_and_umin_4.o \
|
||||
arm/sync_fetch_and_umin_8.o \
|
||||
arm/sync_fetch_and_xor_4.o \
|
||||
arm/sync_fetch_and_xor_8.o
|
||||
endif
|
||||
|
||||
# VFP sources
|
||||
ifeq ($$(findstring eabihf,$(1)),eabihf)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/adddf3vfp.o \
|
||||
arm/addsf3vfp.o \
|
||||
arm/divdf3vfp.o \
|
||||
arm/divsf3vfp.o \
|
||||
arm/eqdf2vfp.o \
|
||||
arm/eqsf2vfp.o \
|
||||
arm/extendsfdf2vfp.o \
|
||||
arm/fixdfsivfp.o \
|
||||
arm/fixsfsivfp.o \
|
||||
arm/fixunsdfsivfp.o \
|
||||
arm/fixunssfsivfp.o \
|
||||
arm/floatsidfvfp.o \
|
||||
arm/floatsisfvfp.o \
|
||||
arm/floatunssidfvfp.o \
|
||||
arm/floatunssisfvfp.o \
|
||||
arm/gedf2vfp.o \
|
||||
arm/gesf2vfp.o \
|
||||
arm/gtdf2vfp.o \
|
||||
arm/gtsf2vfp.o \
|
||||
arm/ledf2vfp.o \
|
||||
arm/lesf2vfp.o \
|
||||
arm/ltdf2vfp.o \
|
||||
arm/ltsf2vfp.o \
|
||||
arm/muldf3vfp.o \
|
||||
arm/mulsf3vfp.o \
|
||||
arm/negdf2vfp.o \
|
||||
arm/negsf2vfp.o \
|
||||
arm/nedf2vfp.o \
|
||||
arm/nesf2vfp.o \
|
||||
arm/restore_vfp_d8_d15_regs.o \
|
||||
arm/save_vfp_d8_d15_regs.o \
|
||||
arm/subdf3vfp.o \
|
||||
arm/subsf3vfp.o \
|
||||
arm/truncdfsf2vfp.o \
|
||||
arm/unorddf2vfp.o \
|
||||
arm/unordsf2vfp.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring aarch64,$(1)),aarch64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
comparetf2.o \
|
||||
extenddftf2.o \
|
||||
extendsftf2.o \
|
||||
fixtfdi.o \
|
||||
fixtfsi.o \
|
||||
fixtfti.o \
|
||||
fixunstfdi.o \
|
||||
fixunstfsi.o \
|
||||
fixunstfti.o \
|
||||
floatditf.o \
|
||||
floatsitf.o \
|
||||
floatunditf.o \
|
||||
floatunsitf.o \
|
||||
multc3.o \
|
||||
trunctfdf2.o \
|
||||
trunctfsf2.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -Zl -D__func__=__FUNCTION__
|
||||
else
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -fno-builtin -fvisibility=hidden \
|
||||
-fomit-frame-pointer -ffreestanding
|
||||
endif
|
||||
|
||||
COMPRT_OBJS_$(1) := $$(COMPRT_OBJS_$(1):%=$$(COMPRT_BUILD_DIR_$(1))/%)
|
||||
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.c
|
||||
@mkdir -p $$(@D)
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_COMPILE_C_$(1),$$@,$$<)
|
||||
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.S \
|
||||
$$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@mkdir -p $$(@D)
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: \
|
||||
export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1)))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring emscripten,$(1)),emscripten)
|
||||
|
||||
# FIXME: emscripten doesn't use compiler-rt and can't build it without
|
||||
# further hacks
|
||||
$$(COMPRT_LIB_$(1)):
|
||||
touch $$@
|
||||
|
||||
else
|
||||
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@$$(call E, cmake: compiler-rt)
|
||||
$$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \
|
||||
$$(CFG_CMAKE) "$(S)src/compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
|
||||
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \
|
||||
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
|
||||
-DCOMPILER_RT_BUILD_EMUTLS=OFF \
|
||||
$$(COMPRT_DEFINES_$(1)) \
|
||||
$$(COMPRT_BUILD_CC_$(1)) \
|
||||
-G"$$(CFG_CMAKE_GENERATOR)"
|
||||
$$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
|
||||
--target $$(COMPRT_BUILD_TARGET_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-- $$(COMPRT_BUILD_ARGS_$(1)) $$(MFLAGS)
|
||||
$$(Q)cp "$$(COMPRT_OUTPUT_$(1))" $$@
|
||||
|
||||
COMPRT_OBJS_$(1) :=
|
||||
endif
|
||||
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_OBJS_$(1))
|
||||
@$$(call E, link: $$@)
|
||||
$$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^
|
||||
|
||||
################################################################################
|
||||
# libbacktrace
|
||||
#
|
||||
|
||||
@ -24,7 +24,7 @@ LLVM_EXTRA_INCDIRS_$(1)= $$(call CFG_CC_INCLUDE_$(1),$(S)src/llvm/include) \
|
||||
endif
|
||||
|
||||
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
|
||||
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp \
|
||||
RustWrapper.cpp PassWrapper.cpp \
|
||||
ArchiveWrapper.cpp)
|
||||
|
||||
RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
|
||||
@ -32,6 +32,11 @@ RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
|
||||
$$(call CFG_CC_INCLUDE_$(1),$$(S)src/rustllvm/include)
|
||||
RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
|
||||
|
||||
# Flag that we are building with Rust's llvm fork
|
||||
ifeq ($(CFG_LLVM_ROOT),)
|
||||
RUSTLLVM_CXXFLAGS_$(1) := -DLLVM_RUSTLLVM
|
||||
endif
|
||||
|
||||
# Note that we appease `cl.exe` and its need for some sort of exception
|
||||
# handling flag with the `EHsc` argument here as well.
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
@ -55,6 +60,7 @@ $(1)/rustllvm/%.o: $(S)src/rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
|
||||
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
|
||||
$$(subst /,//,$$(LLVM_CXXFLAGS_$(1))) \
|
||||
$$(RUSTLLVM_COMPONENTS_$(1)) \
|
||||
$$(RUSTLLVM_CXXFLAGS_$(1)) \
|
||||
$$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
|
||||
$$(RUSTLLVM_INCS_$(1)) \
|
||||
$$<
|
||||
|
||||
@ -11,6 +11,7 @@ endif
|
||||
|
||||
$(SNAPSHOT_RUSTC_POST_CLEANUP): \
|
||||
$(S)src/stage0.txt \
|
||||
$(S)src/etc/local_stage0.sh \
|
||||
$(S)src/etc/get-stage0.py $(MKFILE_DEPS) \
|
||||
| $(HBIN0_H_$(CFG_BUILD))/
|
||||
@$(call E, fetch: $@)
|
||||
|
||||
14
mk/tests.mk
14
mk/tests.mk
@ -277,7 +277,8 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-ui-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
|
||||
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec \
|
||||
check-stage$(1)-T-$(2)-H-$(3)-mir-opt-exec
|
||||
|
||||
ifndef CFG_DISABLE_CODEGEN_TESTS
|
||||
check-stage$(1)-T-$(2)-H-$(3)-exec: \
|
||||
@ -458,6 +459,7 @@ UI_RS := $(call rwildcard,$(S)src/test/ui/,*.rs) \
|
||||
$(call rwildcard,$(S)src/test/ui/,*.stdout) \
|
||||
$(call rwildcard,$(S)src/test/ui/,*.stderr)
|
||||
RUSTDOCCK_RS := $(call rwildcard,$(S)src/test/rustdoc/,*.rs)
|
||||
MIR_OPT_RS := $(call rwildcard,$(S)src/test/mir-opt/,*.rs)
|
||||
|
||||
RPASS_TESTS := $(RPASS_RS)
|
||||
RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS)
|
||||
@ -475,6 +477,7 @@ CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS)
|
||||
INCREMENTAL_TESTS := $(INCREMENTAL_RS)
|
||||
RMAKE_TESTS := $(RMAKE_RS)
|
||||
UI_TESTS := $(UI_RS)
|
||||
MIR_OPT_TESTS := $(MIR_OPT_RS)
|
||||
RUSTDOCCK_TESTS := $(RUSTDOCCK_RS)
|
||||
|
||||
CTEST_SRC_BASE_rpass = run-pass
|
||||
@ -552,6 +555,11 @@ CTEST_BUILD_BASE_ui = ui
|
||||
CTEST_MODE_ui = ui
|
||||
CTEST_RUNTOOL_ui = $(CTEST_RUNTOOL)
|
||||
|
||||
CTEST_SRC_BASE_mir-opt = mir-opt
|
||||
CTEST_BUILD_BASE_mir-opt = mir-opt
|
||||
CTEST_MODE_mir-opt = mir-opt
|
||||
CTEST_RUNTOOL_mir-opt = $(CTEST_RUNTOOL)
|
||||
|
||||
CTEST_SRC_BASE_rustdocck = rustdoc
|
||||
CTEST_BUILD_BASE_rustdocck = rustdoc
|
||||
CTEST_MODE_rustdocck = rustdoc
|
||||
@ -684,6 +692,7 @@ CTEST_DEPS_incremental_$(1)-T-$(2)-H-$(3) = $$(INCREMENTAL_TESTS)
|
||||
CTEST_DEPS_rmake_$(1)-T-$(2)-H-$(3) = $$(RMAKE_TESTS) \
|
||||
$$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
|
||||
CTEST_DEPS_ui_$(1)-T-$(2)-H-$(3) = $$(UI_TESTS)
|
||||
CTEST_DEPS_mir-opt_$(1)-T-$(2)-H-$(3) = $$(MIR_OPT_TESTS)
|
||||
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
|
||||
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
|
||||
$(S)src/etc/htmldocck.py
|
||||
@ -755,7 +764,7 @@ endef
|
||||
|
||||
CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
|
||||
debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck incremental \
|
||||
rmake ui
|
||||
rmake ui mir-opt
|
||||
|
||||
$(foreach host,$(CFG_HOST), \
|
||||
$(eval $(foreach target,$(CFG_TARGET), \
|
||||
@ -964,6 +973,7 @@ TEST_GROUPS = \
|
||||
pretty-rfail-full \
|
||||
pretty-rfail \
|
||||
pretty-pretty \
|
||||
mir-opt \
|
||||
$(NULL)
|
||||
|
||||
define DEF_CHECK_FOR_STAGE_AND_TARGET_AND_HOST
|
||||
|
||||
79
src/bootstrap/Cargo.lock
generated
79
src/bootstrap/Cargo.lock
generated
@ -5,17 +5,26 @@ dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build_helper"
|
||||
version = "0.1.0"
|
||||
@ -25,7 +34,7 @@ name = "cmake"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -33,12 +42,17 @@ name = "filetime"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.26"
|
||||
version = "0.3.31"
|
||||
source = "git+https://github.com/alexcrichton/gcc-rs#b8e2400883f1a2749b323354dad372cdd1c838c7"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -48,7 +62,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -57,7 +71,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -65,19 +79,61 @@ name = "md5"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.1.28"
|
||||
@ -86,6 +142,11 @@ dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.6"
|
||||
|
||||
@ -9,15 +9,15 @@ path = "lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "bootstrap"
|
||||
path = "main.rs"
|
||||
path = "bin/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "rustc"
|
||||
path = "rustc.rs"
|
||||
path = "bin/rustc.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "rustdoc"
|
||||
path = "rustdoc.rs"
|
||||
path = "bin/rustdoc.rs"
|
||||
|
||||
[dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
@ -29,6 +29,7 @@ getopts = "0.2"
|
||||
rustc-serialize = "0.3"
|
||||
winapi = "0.2"
|
||||
kernel32-sys = "0.2"
|
||||
gcc = "0.3.17"
|
||||
gcc = { git = "https://github.com/alexcrichton/gcc-rs" }
|
||||
libc = "0.2"
|
||||
md5 = "0.1"
|
||||
regex = "0.1.73"
|
||||
|
||||
@ -18,22 +18,10 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
extern crate bootstrap;
|
||||
extern crate build_helper;
|
||||
extern crate cmake;
|
||||
extern crate filetime;
|
||||
extern crate gcc;
|
||||
extern crate getopts;
|
||||
extern crate libc;
|
||||
extern crate num_cpus;
|
||||
extern crate rustc_serialize;
|
||||
extern crate toml;
|
||||
extern crate md5;
|
||||
|
||||
use std::env;
|
||||
|
||||
use build::{Flags, Config, Build};
|
||||
|
||||
mod build;
|
||||
use bootstrap::{Flags, Config, Build};
|
||||
|
||||
fn main() {
|
||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||
@ -53,13 +53,14 @@ fn main() {
|
||||
|
||||
let rustc = env::var_os(rustc).unwrap();
|
||||
let libdir = env::var_os(libdir).unwrap();
|
||||
let mut dylib_path = bootstrap::dylib_path();
|
||||
let mut dylib_path = bootstrap::util::dylib_path();
|
||||
dylib_path.insert(0, PathBuf::from(libdir));
|
||||
|
||||
let mut cmd = Command::new(rustc);
|
||||
cmd.args(&args)
|
||||
.arg("--cfg").arg(format!("stage{}", stage))
|
||||
.env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
if let Some(target) = target {
|
||||
// The stage0 compiler has a special sysroot distinct from what we
|
||||
@ -23,14 +23,15 @@ fn main() {
|
||||
let rustdoc = env::var_os("RUSTDOC_REAL").unwrap();
|
||||
let libdir = env::var_os("RUSTC_LIBDIR").unwrap();
|
||||
|
||||
let mut dylib_path = bootstrap::dylib_path();
|
||||
let mut dylib_path = bootstrap::util::dylib_path();
|
||||
dylib_path.insert(0, PathBuf::from(libdir));
|
||||
|
||||
let mut cmd = Command::new(rustdoc);
|
||||
cmd.args(&args)
|
||||
.arg("--cfg").arg(format!("stage{}", env::var("RUSTC_STAGE").unwrap()))
|
||||
.arg("--cfg").arg("dox")
|
||||
.env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
std::process::exit(match cmd.status() {
|
||||
Ok(s) => s.code().unwrap_or(1),
|
||||
Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
|
||||
@ -31,8 +31,16 @@ def get(url, path, verbose=False):
|
||||
|
||||
try:
|
||||
download(sha_path, sha_url, verbose)
|
||||
if os.path.exists(path):
|
||||
if verify(path, sha_path, False):
|
||||
print("using already-download file " + path)
|
||||
return
|
||||
else:
|
||||
print("ignoring already-download file " + path + " due to failed verification")
|
||||
os.unlink(path)
|
||||
download(temp_path, url, verbose)
|
||||
verify(temp_path, sha_path, verbose)
|
||||
if not verify(temp_path, sha_path, True):
|
||||
raise RuntimeError("failed verification")
|
||||
print("moving {} to {}".format(temp_path, path))
|
||||
shutil.move(temp_path, path)
|
||||
finally:
|
||||
@ -64,13 +72,12 @@ def verify(path, sha_path, verbose):
|
||||
found = hashlib.sha256(f.read()).hexdigest()
|
||||
with open(sha_path, "r") as f:
|
||||
expected, _ = f.readline().split()
|
||||
if found != expected:
|
||||
err = ("invalid checksum:\n"
|
||||
verified = found == expected
|
||||
if not verified and verbose:
|
||||
print("invalid checksum:\n"
|
||||
" found: {}\n"
|
||||
" expected: {}".format(found, expected))
|
||||
if verbose:
|
||||
raise RuntimeError(err)
|
||||
sys.exit(err)
|
||||
return verified
|
||||
|
||||
|
||||
def unpack(tarball, dst, verbose=False, match=None):
|
||||
@ -352,7 +359,7 @@ def main():
|
||||
parser.add_argument('--clean', action='store_true')
|
||||
parser.add_argument('-v', '--verbose', action='store_true')
|
||||
|
||||
args = [a for a in sys.argv if a != '-h']
|
||||
args = [a for a in sys.argv if a != '-h' and a != '--help']
|
||||
args, _ = parser.parse_known_args(args)
|
||||
|
||||
# Configure initial bootstrap
|
||||
|
||||
@ -1,871 +0,0 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation of rustbuild, the Rust build system.
|
||||
//!
|
||||
//! This module, and its descendants, are the implementation of the Rust build
|
||||
//! system. Most of this build system is backed by Cargo but the outer layer
|
||||
//! here serves as the ability to orchestrate calling Cargo, sequencing Cargo
|
||||
//! builds, building artifacts like LLVM, etc.
|
||||
//!
|
||||
//! More documentation can be found in each respective module below.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
|
||||
use build_helper::{run_silent, output};
|
||||
use gcc;
|
||||
use num_cpus;
|
||||
|
||||
use build::util::{exe, mtime, libdir, add_lib_path};
|
||||
|
||||
/// A helper macro to `unwrap` a result except also print out details like:
|
||||
///
|
||||
/// * The file/line of the panic
|
||||
/// * The expression that failed
|
||||
/// * The error itself
|
||||
///
|
||||
/// This is currently used judiciously throughout the build system rather than
|
||||
/// using a `Result` with `try!`, but this may change on day...
|
||||
macro_rules! t {
|
||||
($e:expr) => (match $e {
|
||||
Ok(e) => e,
|
||||
Err(e) => panic!("{} failed with {}", stringify!($e), e),
|
||||
})
|
||||
}
|
||||
|
||||
mod cc;
|
||||
mod channel;
|
||||
mod check;
|
||||
mod clean;
|
||||
mod compile;
|
||||
mod config;
|
||||
mod dist;
|
||||
mod doc;
|
||||
mod flags;
|
||||
mod native;
|
||||
mod sanity;
|
||||
mod step;
|
||||
mod util;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod job;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
mod job {
|
||||
pub unsafe fn setup() {}
|
||||
}
|
||||
|
||||
pub use build::config::Config;
|
||||
pub use build::flags::Flags;
|
||||
|
||||
/// A structure representing a Rust compiler.
|
||||
///
|
||||
/// Each compiler has a `stage` that it is associated with and a `host` that
|
||||
/// corresponds to the platform the compiler runs on. This structure is used as
|
||||
/// a parameter to many methods below.
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
|
||||
pub struct Compiler<'a> {
|
||||
stage: u32,
|
||||
host: &'a str,
|
||||
}
|
||||
|
||||
/// Global configuration for the build system.
|
||||
///
|
||||
/// This structure transitively contains all configuration for the build system.
|
||||
/// All filesystem-encoded configuration is in `config`, all flags are in
|
||||
/// `flags`, and then parsed or probed information is listed in the keys below.
|
||||
///
|
||||
/// This structure is a parameter of almost all methods in the build system,
|
||||
/// although most functions are implemented as free functions rather than
|
||||
/// methods specifically on this structure itself (to make it easier to
|
||||
/// organize).
|
||||
pub struct Build {
|
||||
// User-specified configuration via config.toml
|
||||
config: Config,
|
||||
|
||||
// User-specified configuration via CLI flags
|
||||
flags: Flags,
|
||||
|
||||
// Derived properties from the above two configurations
|
||||
cargo: PathBuf,
|
||||
rustc: PathBuf,
|
||||
src: PathBuf,
|
||||
out: PathBuf,
|
||||
release: String,
|
||||
unstable_features: bool,
|
||||
ver_hash: Option<String>,
|
||||
short_ver_hash: Option<String>,
|
||||
ver_date: Option<String>,
|
||||
version: String,
|
||||
package_vers: String,
|
||||
bootstrap_key: String,
|
||||
bootstrap_key_stage0: String,
|
||||
|
||||
// Probed tools at runtime
|
||||
gdb_version: Option<String>,
|
||||
lldb_version: Option<String>,
|
||||
lldb_python_dir: Option<String>,
|
||||
|
||||
// Runtime state filled in later on
|
||||
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
||||
cxx: HashMap<String, gcc::Tool>,
|
||||
compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
|
||||
}
|
||||
|
||||
/// The various "modes" of invoking Cargo.
|
||||
///
|
||||
/// These entries currently correspond to the various output directories of the
|
||||
/// build system, with each mod generating output in a different directory.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Mode {
|
||||
/// This cargo is going to build the standard library, placing output in the
|
||||
/// "stageN-std" directory.
|
||||
Libstd,
|
||||
|
||||
/// This cargo is going to build libtest, placing output in the
|
||||
/// "stageN-test" directory.
|
||||
Libtest,
|
||||
|
||||
/// This cargo is going to build librustc and compiler libraries, placing
|
||||
/// output in the "stageN-rustc" directory.
|
||||
Librustc,
|
||||
|
||||
/// This cargo is going to some build tool, placing output in the
|
||||
/// "stageN-tools" directory.
|
||||
Tool,
|
||||
}
|
||||
|
||||
impl Build {
|
||||
/// Creates a new set of build configuration from the `flags` on the command
|
||||
/// line and the filesystem `config`.
|
||||
///
|
||||
/// By default all build output will be placed in the current directory.
|
||||
pub fn new(flags: Flags, config: Config) -> Build {
|
||||
let cwd = t!(env::current_dir());
|
||||
let src = flags.src.clone().unwrap_or(cwd.clone());
|
||||
let out = cwd.join("build");
|
||||
|
||||
let stage0_root = out.join(&config.build).join("stage0/bin");
|
||||
let rustc = match config.rustc {
|
||||
Some(ref s) => PathBuf::from(s),
|
||||
None => stage0_root.join(exe("rustc", &config.build)),
|
||||
};
|
||||
let cargo = match config.cargo {
|
||||
Some(ref s) => PathBuf::from(s),
|
||||
None => stage0_root.join(exe("cargo", &config.build)),
|
||||
};
|
||||
|
||||
Build {
|
||||
flags: flags,
|
||||
config: config,
|
||||
cargo: cargo,
|
||||
rustc: rustc,
|
||||
src: src,
|
||||
out: out,
|
||||
|
||||
release: String::new(),
|
||||
unstable_features: false,
|
||||
ver_hash: None,
|
||||
short_ver_hash: None,
|
||||
ver_date: None,
|
||||
version: String::new(),
|
||||
bootstrap_key: String::new(),
|
||||
bootstrap_key_stage0: String::new(),
|
||||
package_vers: String::new(),
|
||||
cc: HashMap::new(),
|
||||
cxx: HashMap::new(),
|
||||
compiler_rt_built: RefCell::new(HashMap::new()),
|
||||
gdb_version: None,
|
||||
lldb_version: None,
|
||||
lldb_python_dir: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes the entire build, as configured by the flags and configuration.
|
||||
pub fn build(&mut self) {
|
||||
use build::step::Source::*;
|
||||
|
||||
unsafe {
|
||||
job::setup();
|
||||
}
|
||||
|
||||
if self.flags.clean {
|
||||
return clean::clean(self);
|
||||
}
|
||||
|
||||
self.verbose("finding compilers");
|
||||
cc::find(self);
|
||||
self.verbose("running sanity check");
|
||||
sanity::check(self);
|
||||
self.verbose("collecting channel variables");
|
||||
channel::collect(self);
|
||||
self.verbose("updating submodules");
|
||||
self.update_submodules();
|
||||
|
||||
// The main loop of the build system.
|
||||
//
|
||||
// The `step::all` function returns a topographically sorted list of all
|
||||
// steps that need to be executed as part of this build. Each step has a
|
||||
// corresponding entry in `step.rs` and indicates some unit of work that
|
||||
// needs to be done as part of the build.
|
||||
//
|
||||
// Almost all of these are simple one-liners that shell out to the
|
||||
// corresponding functionality in the extra modules, where more
|
||||
// documentation can be found.
|
||||
for target in step::all(self) {
|
||||
let doc_out = self.out.join(&target.target).join("doc");
|
||||
match target.src {
|
||||
Llvm { _dummy } => {
|
||||
native::llvm(self, target.target);
|
||||
}
|
||||
CompilerRt { _dummy } => {
|
||||
native::compiler_rt(self, target.target);
|
||||
}
|
||||
TestHelpers { _dummy } => {
|
||||
native::test_helpers(self, target.target);
|
||||
}
|
||||
Libstd { compiler } => {
|
||||
compile::std(self, target.target, &compiler);
|
||||
}
|
||||
Libtest { compiler } => {
|
||||
compile::test(self, target.target, &compiler);
|
||||
}
|
||||
Librustc { compiler } => {
|
||||
compile::rustc(self, target.target, &compiler);
|
||||
}
|
||||
LibstdLink { compiler, host } => {
|
||||
compile::std_link(self, target.target, &compiler, host);
|
||||
}
|
||||
LibtestLink { compiler, host } => {
|
||||
compile::test_link(self, target.target, &compiler, host);
|
||||
}
|
||||
LibrustcLink { compiler, host } => {
|
||||
compile::rustc_link(self, target.target, &compiler, host);
|
||||
}
|
||||
Rustc { stage: 0 } => {
|
||||
// nothing to do...
|
||||
}
|
||||
Rustc { stage } => {
|
||||
compile::assemble_rustc(self, stage, target.target);
|
||||
}
|
||||
ToolLinkchecker { stage } => {
|
||||
compile::tool(self, stage, target.target, "linkchecker");
|
||||
}
|
||||
ToolRustbook { stage } => {
|
||||
compile::tool(self, stage, target.target, "rustbook");
|
||||
}
|
||||
ToolErrorIndex { stage } => {
|
||||
compile::tool(self, stage, target.target,
|
||||
"error_index_generator");
|
||||
}
|
||||
ToolCargoTest { stage } => {
|
||||
compile::tool(self, stage, target.target, "cargotest");
|
||||
}
|
||||
ToolTidy { stage } => {
|
||||
compile::tool(self, stage, target.target, "tidy");
|
||||
}
|
||||
ToolCompiletest { stage } => {
|
||||
compile::tool(self, stage, target.target, "compiletest");
|
||||
}
|
||||
DocBook { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "book", &doc_out);
|
||||
}
|
||||
DocNomicon { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "nomicon",
|
||||
&doc_out);
|
||||
}
|
||||
DocStyle { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "style",
|
||||
&doc_out);
|
||||
}
|
||||
DocStandalone { stage } => {
|
||||
doc::standalone(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocStd { stage } => {
|
||||
doc::std(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocTest { stage } => {
|
||||
doc::test(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocRustc { stage } => {
|
||||
doc::rustc(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocErrorIndex { stage } => {
|
||||
doc::error_index(self, stage, target.target, &doc_out);
|
||||
}
|
||||
|
||||
CheckLinkcheck { stage } => {
|
||||
check::linkcheck(self, stage, target.target);
|
||||
}
|
||||
CheckCargoTest { stage } => {
|
||||
check::cargotest(self, stage, target.target);
|
||||
}
|
||||
CheckTidy { stage } => {
|
||||
check::tidy(self, stage, target.target);
|
||||
}
|
||||
CheckRPass { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass", "run-pass");
|
||||
}
|
||||
CheckRPassFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass", "run-pass-fulldeps");
|
||||
}
|
||||
CheckCFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"compile-fail", "compile-fail");
|
||||
}
|
||||
CheckCFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"compile-fail", "compile-fail-fulldeps")
|
||||
}
|
||||
CheckPFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"parse-fail", "parse-fail");
|
||||
}
|
||||
CheckRFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-fail", "run-fail");
|
||||
}
|
||||
CheckRFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-fail", "run-fail-fulldeps");
|
||||
}
|
||||
CheckPretty { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "pretty");
|
||||
}
|
||||
CheckPrettyRPass { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass");
|
||||
}
|
||||
CheckPrettyRPassFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass-fulldeps");
|
||||
}
|
||||
CheckPrettyRFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-fail");
|
||||
}
|
||||
CheckPrettyRFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-fail-fulldeps");
|
||||
}
|
||||
CheckPrettyRPassValgrind { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass-valgrind");
|
||||
}
|
||||
CheckCodegen { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"codegen", "codegen");
|
||||
}
|
||||
CheckCodegenUnits { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"codegen-units", "codegen-units");
|
||||
}
|
||||
CheckIncremental { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"incremental", "incremental");
|
||||
}
|
||||
CheckUi { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"ui", "ui");
|
||||
}
|
||||
CheckDebuginfo { compiler } => {
|
||||
if target.target.contains("msvc") {
|
||||
// nothing to do
|
||||
} else if target.target.contains("apple") {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"debuginfo-lldb", "debuginfo");
|
||||
} else {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"debuginfo-gdb", "debuginfo");
|
||||
}
|
||||
}
|
||||
CheckRustdoc { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"rustdoc", "rustdoc");
|
||||
}
|
||||
CheckRPassValgrind { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass-valgrind", "run-pass-valgrind");
|
||||
}
|
||||
CheckDocs { compiler } => {
|
||||
check::docs(self, &compiler);
|
||||
}
|
||||
CheckErrorIndex { compiler } => {
|
||||
check::error_index(self, &compiler);
|
||||
}
|
||||
CheckRMake { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-make", "run-make")
|
||||
}
|
||||
CheckCrateStd { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Libstd)
|
||||
}
|
||||
CheckCrateTest { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Libtest)
|
||||
}
|
||||
CheckCrateRustc { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Librustc)
|
||||
}
|
||||
|
||||
DistDocs { stage } => dist::docs(self, stage, target.target),
|
||||
DistMingw { _dummy } => dist::mingw(self, target.target),
|
||||
DistRustc { stage } => dist::rustc(self, stage, target.target),
|
||||
DistStd { compiler } => dist::std(self, &compiler, target.target),
|
||||
|
||||
DebuggerScripts { stage } => {
|
||||
let compiler = Compiler::new(stage, target.target);
|
||||
dist::debugger_scripts(self,
|
||||
&self.sysroot(&compiler),
|
||||
target.target);
|
||||
}
|
||||
|
||||
AndroidCopyLibs { compiler } => {
|
||||
check::android_copy_libs(self, &compiler, target.target);
|
||||
}
|
||||
|
||||
// pseudo-steps
|
||||
Dist { .. } |
|
||||
Doc { .. } |
|
||||
CheckTarget { .. } |
|
||||
Check { .. } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates all git submodules that we have.
|
||||
///
|
||||
/// This will detect if any submodules are out of date an run the necessary
|
||||
/// commands to sync them all with upstream.
|
||||
fn update_submodules(&self) {
|
||||
if !self.config.submodules {
|
||||
return
|
||||
}
|
||||
if fs::metadata(self.src.join(".git")).is_err() {
|
||||
return
|
||||
}
|
||||
let git_submodule = || {
|
||||
let mut cmd = Command::new("git");
|
||||
cmd.current_dir(&self.src).arg("submodule");
|
||||
return cmd
|
||||
};
|
||||
|
||||
// FIXME: this takes a seriously long time to execute on Windows and a
|
||||
// nontrivial amount of time on Unix, we should have a better way
|
||||
// of detecting whether we need to run all the submodule commands
|
||||
// below.
|
||||
let out = output(git_submodule().arg("status"));
|
||||
if !out.lines().any(|l| l.starts_with("+") || l.starts_with("-")) {
|
||||
return
|
||||
}
|
||||
|
||||
self.run(git_submodule().arg("sync"));
|
||||
self.run(git_submodule().arg("init"));
|
||||
self.run(git_submodule().arg("update"));
|
||||
self.run(git_submodule().arg("update").arg("--recursive"));
|
||||
self.run(git_submodule().arg("status").arg("--recursive"));
|
||||
self.run(git_submodule().arg("foreach").arg("--recursive")
|
||||
.arg("git").arg("clean").arg("-fdx"));
|
||||
self.run(git_submodule().arg("foreach").arg("--recursive")
|
||||
.arg("git").arg("checkout").arg("."));
|
||||
}
|
||||
|
||||
/// Clear out `dir` if `input` is newer.
|
||||
///
|
||||
/// After this executes, it will also ensure that `dir` exists.
|
||||
fn clear_if_dirty(&self, dir: &Path, input: &Path) {
|
||||
let stamp = dir.join(".stamp");
|
||||
if mtime(&stamp) < mtime(input) {
|
||||
self.verbose(&format!("Dirty - {}", dir.display()));
|
||||
let _ = fs::remove_dir_all(dir);
|
||||
}
|
||||
t!(fs::create_dir_all(dir));
|
||||
t!(File::create(stamp));
|
||||
}
|
||||
|
||||
/// Prepares an invocation of `cargo` to be run.
|
||||
///
|
||||
/// This will create a `Command` that represents a pending execution of
|
||||
/// Cargo. This cargo will be configured to use `compiler` as the actual
|
||||
/// rustc compiler, its output will be scoped by `mode`'s output directory,
|
||||
/// it will pass the `--target` flag for the specified `target`, and will be
|
||||
/// executing the Cargo command `cmd`.
|
||||
fn cargo(&self,
|
||||
compiler: &Compiler,
|
||||
mode: Mode,
|
||||
target: &str,
|
||||
cmd: &str) -> Command {
|
||||
let mut cargo = Command::new(&self.cargo);
|
||||
let out_dir = self.stage_out(compiler, mode);
|
||||
cargo.env("CARGO_TARGET_DIR", out_dir)
|
||||
.arg(cmd)
|
||||
.arg("-j").arg(self.jobs().to_string())
|
||||
.arg("--target").arg(target);
|
||||
|
||||
let stage;
|
||||
if compiler.stage == 0 && self.config.local_rebuild {
|
||||
// Assume the local-rebuild rustc already has stage1 features.
|
||||
stage = 1;
|
||||
} else {
|
||||
stage = compiler.stage;
|
||||
}
|
||||
|
||||
// Customize the compiler we're running. Specify the compiler to cargo
|
||||
// as our shim and then pass it some various options used to configure
|
||||
// how the actual compiler itself is called.
|
||||
//
|
||||
// These variables are primarily all read by
|
||||
// src/bootstrap/{rustc,rustdoc.rs}
|
||||
cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
|
||||
.env("RUSTC_REAL", self.compiler_path(compiler))
|
||||
.env("RUSTC_STAGE", stage.to_string())
|
||||
.env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string())
|
||||
.env("RUSTC_CODEGEN_UNITS",
|
||||
self.config.rust_codegen_units.to_string())
|
||||
.env("RUSTC_DEBUG_ASSERTIONS",
|
||||
self.config.rust_debug_assertions.to_string())
|
||||
.env("RUSTC_SNAPSHOT", &self.rustc)
|
||||
.env("RUSTC_SYSROOT", self.sysroot(compiler))
|
||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
||||
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir())
|
||||
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
||||
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
||||
.env("RUSTDOC_REAL", self.rustdoc(compiler))
|
||||
.env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
|
||||
|
||||
self.add_bootstrap_key(compiler, &mut cargo);
|
||||
|
||||
// Specify some various options for build scripts used throughout
|
||||
// the build.
|
||||
//
|
||||
// FIXME: the guard against msvc shouldn't need to be here
|
||||
if !target.contains("msvc") {
|
||||
cargo.env(format!("CC_{}", target), self.cc(target))
|
||||
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
|
||||
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
|
||||
}
|
||||
|
||||
// If we're building for OSX, inform the compiler and the linker that
|
||||
// we want to build a compiler runnable on 10.7
|
||||
if target.contains("apple-darwin") {
|
||||
cargo.env("MACOSX_DEPLOYMENT_TARGET", "10.7");
|
||||
}
|
||||
|
||||
// Environment variables *required* needed throughout the build
|
||||
//
|
||||
// FIXME: should update code to not require this env var
|
||||
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
|
||||
|
||||
if self.config.verbose || self.flags.verbose {
|
||||
cargo.arg("-v");
|
||||
}
|
||||
if self.config.rust_optimize {
|
||||
cargo.arg("--release");
|
||||
}
|
||||
return cargo
|
||||
}
|
||||
|
||||
/// Get a path to the compiler specified.
|
||||
fn compiler_path(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.rustc.clone()
|
||||
} else {
|
||||
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the specified tool built by the specified compiler
|
||||
fn tool(&self, compiler: &Compiler, tool: &str) -> PathBuf {
|
||||
self.cargo_out(compiler, Mode::Tool, compiler.host)
|
||||
.join(exe(tool, compiler.host))
|
||||
}
|
||||
|
||||
/// Get the `rustdoc` executable next to the specified compiler
|
||||
fn rustdoc(&self, compiler: &Compiler) -> PathBuf {
|
||||
let mut rustdoc = self.compiler_path(compiler);
|
||||
rustdoc.pop();
|
||||
rustdoc.push(exe("rustdoc", compiler.host));
|
||||
return rustdoc
|
||||
}
|
||||
|
||||
/// Get a `Command` which is ready to run `tool` in `stage` built for
|
||||
/// `host`.
|
||||
fn tool_cmd(&self, compiler: &Compiler, tool: &str) -> Command {
|
||||
let mut cmd = Command::new(self.tool(&compiler, tool));
|
||||
let host = compiler.host;
|
||||
let paths = vec![
|
||||
self.cargo_out(compiler, Mode::Libstd, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Libtest, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Librustc, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Tool, host).join("deps"),
|
||||
];
|
||||
add_lib_path(paths, &mut cmd);
|
||||
return cmd
|
||||
}
|
||||
|
||||
/// Get the space-separated set of activated features for the standard
|
||||
/// library.
|
||||
fn std_features(&self) -> String {
|
||||
let mut features = String::new();
|
||||
if self.config.debug_jemalloc {
|
||||
features.push_str(" debug-jemalloc");
|
||||
}
|
||||
if self.config.use_jemalloc {
|
||||
features.push_str(" jemalloc");
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
||||
/// Get the space-separated set of activated features for the compiler.
|
||||
fn rustc_features(&self) -> String {
|
||||
let mut features = String::new();
|
||||
if self.config.use_jemalloc {
|
||||
features.push_str(" jemalloc");
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
||||
/// Component directory that Cargo will produce output into (e.g.
|
||||
/// release/debug)
|
||||
fn cargo_dir(&self) -> &'static str {
|
||||
if self.config.rust_optimize {"release"} else {"debug"}
|
||||
}
|
||||
|
||||
/// Returns the sysroot for the `compiler` specified that *this build system
|
||||
/// generates*.
|
||||
///
|
||||
/// That is, the sysroot for the stage0 compiler is not what the compiler
|
||||
/// thinks it is by default, but it's the same as the default for stages
|
||||
/// 1-3.
|
||||
fn sysroot(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.stage == 0 {
|
||||
self.out.join(compiler.host).join("stage0-sysroot")
|
||||
} else {
|
||||
self.out.join(compiler.host).join(format!("stage{}", compiler.stage))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the libdir where the standard library and other artifacts are
|
||||
/// found for a compiler's sysroot.
|
||||
fn sysroot_libdir(&self, compiler: &Compiler, target: &str) -> PathBuf {
|
||||
self.sysroot(compiler).join("lib").join("rustlib")
|
||||
.join(target).join("lib")
|
||||
}
|
||||
|
||||
/// Returns the root directory for all output generated in a particular
|
||||
/// stage when running with a particular host compiler.
|
||||
///
|
||||
/// The mode indicates what the root directory is for.
|
||||
fn stage_out(&self, compiler: &Compiler, mode: Mode) -> PathBuf {
|
||||
let suffix = match mode {
|
||||
Mode::Libstd => "-std",
|
||||
Mode::Libtest => "-test",
|
||||
Mode::Tool => "-tools",
|
||||
Mode::Librustc => "-rustc",
|
||||
};
|
||||
self.out.join(compiler.host)
|
||||
.join(format!("stage{}{}", compiler.stage, suffix))
|
||||
}
|
||||
|
||||
/// Returns the root output directory for all Cargo output in a given stage,
|
||||
/// running a particular comipler, wehther or not we're building the
|
||||
/// standard library, and targeting the specified architecture.
|
||||
fn cargo_out(&self,
|
||||
compiler: &Compiler,
|
||||
mode: Mode,
|
||||
target: &str) -> PathBuf {
|
||||
self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
|
||||
}
|
||||
|
||||
/// Root output directory for LLVM compiled for `target`
|
||||
///
|
||||
/// Note that if LLVM is configured externally then the directory returned
|
||||
/// will likely be empty.
|
||||
fn llvm_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("llvm")
|
||||
}
|
||||
|
||||
/// Returns the path to `llvm-config` for the specified target.
|
||||
///
|
||||
/// If a custom `llvm-config` was specified for target then that's returned
|
||||
/// instead.
|
||||
fn llvm_config(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
s.clone()
|
||||
} else {
|
||||
self.llvm_out(&self.config.build).join("bin")
|
||||
.join(exe("llvm-config", target))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the path to `FileCheck` binary for the specified target
|
||||
fn llvm_filecheck(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
s.parent().unwrap().join(exe("FileCheck", target))
|
||||
} else {
|
||||
let base = self.llvm_out(&self.config.build).join("build");
|
||||
let exe = exe("FileCheck", target);
|
||||
if self.config.build.contains("msvc") {
|
||||
base.join("Release/bin").join(exe)
|
||||
} else {
|
||||
base.join("bin").join(exe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Root output directory for compiler-rt compiled for `target`
|
||||
fn compiler_rt_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("compiler-rt")
|
||||
}
|
||||
|
||||
/// Root output directory for rust_test_helpers library compiled for
|
||||
/// `target`
|
||||
fn test_helpers_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("rust-test-helpers")
|
||||
}
|
||||
|
||||
/// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic
|
||||
/// library lookup path.
|
||||
fn add_rustc_lib_path(&self, compiler: &Compiler, cmd: &mut Command) {
|
||||
// Windows doesn't need dylib path munging because the dlls for the
|
||||
// compiler live next to the compiler and the system will find them
|
||||
// automatically.
|
||||
if cfg!(windows) {
|
||||
return
|
||||
}
|
||||
|
||||
add_lib_path(vec![self.rustc_libdir(compiler)], cmd);
|
||||
}
|
||||
|
||||
/// Adds the compiler's bootstrap key to the environment of `cmd`.
|
||||
fn add_bootstrap_key(&self, compiler: &Compiler, cmd: &mut Command) {
|
||||
// In stage0 we're using a previously released stable compiler, so we
|
||||
// use the stage0 bootstrap key. Otherwise we use our own build's
|
||||
// bootstrap key.
|
||||
let bootstrap_key = if compiler.is_snapshot(self) && !self.config.local_rebuild {
|
||||
&self.bootstrap_key_stage0
|
||||
} else {
|
||||
&self.bootstrap_key
|
||||
};
|
||||
cmd.env("RUSTC_BOOTSTRAP_KEY", bootstrap_key);
|
||||
}
|
||||
|
||||
/// Returns the compiler's libdir where it stores the dynamic libraries that
|
||||
/// it itself links against.
|
||||
///
|
||||
/// For example this returns `<sysroot>/lib` on Unix and `<sysroot>/bin` on
|
||||
/// Windows.
|
||||
fn rustc_libdir(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.rustc_snapshot_libdir()
|
||||
} else {
|
||||
self.sysroot(compiler).join(libdir(compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the libdir of the snapshot compiler.
|
||||
fn rustc_snapshot_libdir(&self) -> PathBuf {
|
||||
self.rustc.parent().unwrap().parent().unwrap()
|
||||
.join(libdir(&self.config.build))
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
fn run(&self, cmd: &mut Command) {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_silent(cmd)
|
||||
}
|
||||
|
||||
/// Prints a message if this build is configured in verbose mode.
|
||||
fn verbose(&self, msg: &str) {
|
||||
if self.flags.verbose || self.config.verbose {
|
||||
println!("{}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of parallel jobs that have been configured for this
|
||||
/// build.
|
||||
fn jobs(&self) -> u32 {
|
||||
self.flags.jobs.unwrap_or(num_cpus::get() as u32)
|
||||
}
|
||||
|
||||
/// Returns the path to the C compiler for the target specified.
|
||||
fn cc(&self, target: &str) -> &Path {
|
||||
self.cc[target].0.path()
|
||||
}
|
||||
|
||||
/// Returns a list of flags to pass to the C compiler for the target
|
||||
/// specified.
|
||||
fn cflags(&self, target: &str) -> Vec<String> {
|
||||
// Filter out -O and /O (the optimization flags) that we picked up from
|
||||
// gcc-rs because the build scripts will determine that for themselves.
|
||||
let mut base = self.cc[target].0.args().iter()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// If we're compiling on OSX then we add a few unconditional flags
|
||||
// indicating that we want libc++ (more filled out than libstdc++) and
|
||||
// we want to compile for 10.7. This way we can ensure that
|
||||
// LLVM/jemalloc/etc are all properly compiled.
|
||||
if target.contains("apple-darwin") {
|
||||
base.push("-stdlib=libc++".into());
|
||||
base.push("-mmacosx-version-min=10.7".into());
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
/// Returns the path to the `ar` archive utility for the target specified.
|
||||
fn ar(&self, target: &str) -> Option<&Path> {
|
||||
self.cc[target].1.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// Returns the path to the C++ compiler for the target specified, may panic
|
||||
/// if no C++ compiler was configured for the target.
|
||||
fn cxx(&self, target: &str) -> &Path {
|
||||
self.cxx[target].path()
|
||||
}
|
||||
|
||||
/// Returns flags to pass to the compiler to generate code for `target`.
|
||||
fn rustc_flags(&self, target: &str) -> Vec<String> {
|
||||
// New flags should be added here with great caution!
|
||||
//
|
||||
// It's quite unfortunate to **require** flags to generate code for a
|
||||
// target, so it should only be passed here if absolutely necessary!
|
||||
// Most default configuration should be done through target specs rather
|
||||
// than an entry here.
|
||||
|
||||
let mut base = Vec::new();
|
||||
if target != self.config.build && !target.contains("msvc") {
|
||||
base.push(format!("-Clinker={}", self.cc(target).display()));
|
||||
}
|
||||
return base
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
/// Creates a new complier for the specified stage/host
|
||||
fn new(stage: u32, host: &'a str) -> Compiler<'a> {
|
||||
Compiler { stage: stage, host: host }
|
||||
}
|
||||
|
||||
/// Returns whether this is a snapshot compiler for `build`'s configuration
|
||||
fn is_snapshot(&self, build: &Build) -> bool {
|
||||
self.stage == 0 && self.host == build.config.build
|
||||
}
|
||||
}
|
||||
@ -1,238 +0,0 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Compilation of native dependencies like LLVM.
|
||||
//!
|
||||
//! Native projects like LLVM unfortunately aren't suited just yet for
|
||||
//! compilation in build scripts that Cargo has. This is because thie
|
||||
//! compilation takes a *very* long time but also because we don't want to
|
||||
//! compile LLVM 3 times as part of a normal bootstrap (we want it cached).
|
||||
//!
|
||||
//! LLVM and compiler-rt are essentially just wired up to everything else to
|
||||
//! ensure that they're always in place if needed.
|
||||
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::fs::{self, File};
|
||||
|
||||
use build_helper::output;
|
||||
use cmake;
|
||||
use gcc;
|
||||
|
||||
use build::Build;
|
||||
use build::util::{staticlib, up_to_date};
|
||||
|
||||
/// Compile LLVM for `target`.
|
||||
pub fn llvm(build: &Build, target: &str) {
|
||||
// If we're using a custom LLVM bail out here, but we can only use a
|
||||
// custom LLVM for the build triple.
|
||||
if let Some(config) = build.config.target_config.get(target) {
|
||||
if let Some(ref s) = config.llvm_config {
|
||||
return check_llvm_version(build, s);
|
||||
}
|
||||
}
|
||||
|
||||
// If the cleaning trigger is newer than our built artifacts (or if the
|
||||
// artifacts are missing) then we keep going, otherwise we bail out.
|
||||
let dst = build.llvm_out(target);
|
||||
let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
|
||||
let done_stamp = dst.join("llvm-finished-building");
|
||||
build.clear_if_dirty(&dst, &stamp);
|
||||
if fs::metadata(&done_stamp).is_ok() {
|
||||
return
|
||||
}
|
||||
|
||||
println!("Building LLVM for {}", target);
|
||||
|
||||
let _ = fs::remove_dir_all(&dst.join("build"));
|
||||
t!(fs::create_dir_all(&dst.join("build")));
|
||||
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
|
||||
|
||||
// http://llvm.org/docs/CMake.html
|
||||
let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
|
||||
if build.config.ninja {
|
||||
cfg.generator("Ninja");
|
||||
}
|
||||
cfg.target(target)
|
||||
.host(&build.config.build)
|
||||
.out_dir(&dst)
|
||||
.profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
|
||||
.define("LLVM_ENABLE_ASSERTIONS", assertions)
|
||||
.define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC")
|
||||
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
||||
.define("LLVM_INCLUDE_TESTS", "OFF")
|
||||
.define("LLVM_INCLUDE_DOCS", "OFF")
|
||||
.define("LLVM_ENABLE_ZLIB", "OFF")
|
||||
.define("WITH_POLLY", "OFF")
|
||||
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
||||
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
||||
.define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string());
|
||||
|
||||
if target.starts_with("i686") {
|
||||
cfg.define("LLVM_BUILD_32_BITS", "ON");
|
||||
}
|
||||
|
||||
// http://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
if target != build.config.build {
|
||||
// FIXME: if the llvm root for the build triple is overridden then we
|
||||
// should use llvm-tblgen from there, also should verify that it
|
||||
// actually exists most of the time in normal installs of LLVM.
|
||||
let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
|
||||
cfg.define("CMAKE_CROSSCOMPILING", "True")
|
||||
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
|
||||
.define("LLVM_TABLEGEN", &host)
|
||||
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
|
||||
}
|
||||
|
||||
// MSVC handles compiler business itself
|
||||
if !target.contains("msvc") {
|
||||
if build.config.ccache {
|
||||
cfg.define("CMAKE_C_COMPILER", "ccache")
|
||||
.define("CMAKE_C_COMPILER_ARG1", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", "ccache")
|
||||
.define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
|
||||
} else {
|
||||
cfg.define("CMAKE_C_COMPILER", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", build.cxx(target));
|
||||
}
|
||||
cfg.build_arg("-j").build_arg(build.jobs().to_string());
|
||||
|
||||
cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
|
||||
cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
|
||||
}
|
||||
|
||||
// FIXME: we don't actually need to build all LLVM tools and all LLVM
|
||||
// libraries here, e.g. we just want a few components and a few
|
||||
// tools. Figure out how to filter them down and only build the right
|
||||
// tools and libs on all platforms.
|
||||
cfg.build();
|
||||
|
||||
t!(File::create(&done_stamp));
|
||||
}
|
||||
|
||||
fn check_llvm_version(build: &Build, llvm_config: &Path) {
|
||||
if !build.config.llvm_version_check {
|
||||
return
|
||||
}
|
||||
|
||||
let mut cmd = Command::new(llvm_config);
|
||||
let version = output(cmd.arg("--version"));
|
||||
if version.starts_with("3.5") || version.starts_with("3.6") ||
|
||||
version.starts_with("3.7") {
|
||||
return
|
||||
}
|
||||
panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
|
||||
}
|
||||
|
||||
/// Compiles the `compiler-rt` library, or at least the builtins part of it.
|
||||
///
|
||||
/// This uses the CMake build system and an existing LLVM build directory to
|
||||
/// compile the project.
|
||||
pub fn compiler_rt(build: &Build, target: &str) {
|
||||
let dst = build.compiler_rt_out(target);
|
||||
let arch = target.split('-').next().unwrap();
|
||||
let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
|
||||
|
||||
let build_llvm_config = build.llvm_config(&build.config.build);
|
||||
let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
|
||||
cfg.target(target)
|
||||
.host(&build.config.build)
|
||||
.out_dir(&dst)
|
||||
.profile(mode)
|
||||
.define("LLVM_CONFIG_PATH", build_llvm_config)
|
||||
.define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
|
||||
.define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
|
||||
.define("COMPILER_RT_BUILD_EMUTLS", "OFF")
|
||||
// inform about c/c++ compilers, the c++ compiler isn't actually used but
|
||||
// it's needed to get the initial configure to work on all platforms.
|
||||
.define("CMAKE_C_COMPILER", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", build.cc(target));
|
||||
|
||||
let (dir, build_target, libname) = if target.contains("linux") ||
|
||||
target.contains("freebsd") ||
|
||||
target.contains("netbsd") {
|
||||
let os_extra = if target.contains("android") && target.contains("arm") {
|
||||
"-android"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let builtins_arch = match arch {
|
||||
"i586" => "i386",
|
||||
"arm" | "armv7" if target.contains("android") => "armhf",
|
||||
"arm" if target.contains("eabihf") => "armhf",
|
||||
_ => arch,
|
||||
};
|
||||
let target = format!("clang_rt.builtins-{}", builtins_arch);
|
||||
("linux".to_string(),
|
||||
target.clone(),
|
||||
format!("{}{}", target, os_extra))
|
||||
} else if target.contains("apple-darwin") {
|
||||
let builtins_arch = match arch {
|
||||
"i686" => "i386",
|
||||
_ => arch,
|
||||
};
|
||||
let target = format!("clang_rt.builtins_{}_osx", builtins_arch);
|
||||
("builtins".to_string(), target.clone(), target)
|
||||
} else if target.contains("apple-ios") {
|
||||
cfg.define("COMPILER_RT_ENABLE_IOS", "ON");
|
||||
let target = match arch {
|
||||
"armv7s" => "hard_pic_armv7em_macho_embedded".to_string(),
|
||||
"aarch64" => "builtins_arm64_ios".to_string(),
|
||||
_ => format!("hard_pic_{}_macho_embedded", arch),
|
||||
};
|
||||
("builtins".to_string(), target.clone(), target)
|
||||
} else if target.contains("windows-gnu") {
|
||||
let target = format!("clang_rt.builtins-{}", arch);
|
||||
("windows".to_string(), target.clone(), target)
|
||||
} else if target.contains("windows-msvc") {
|
||||
let builtins_arch = match arch {
|
||||
"i586" | "i686" => "i386",
|
||||
_ => arch,
|
||||
};
|
||||
(format!("windows/{}", mode),
|
||||
"lib/builtins/builtins".to_string(),
|
||||
format!("clang_rt.builtins-{}", builtins_arch))
|
||||
} else {
|
||||
panic!("can't get os from target: {}", target)
|
||||
};
|
||||
let output = dst.join("build/lib").join(dir)
|
||||
.join(staticlib(&libname, target));
|
||||
build.compiler_rt_built.borrow_mut().insert(target.to_string(),
|
||||
output.clone());
|
||||
if fs::metadata(&output).is_ok() {
|
||||
return
|
||||
}
|
||||
let _ = fs::remove_dir_all(&dst);
|
||||
t!(fs::create_dir_all(&dst));
|
||||
cfg.build_target(&build_target);
|
||||
cfg.build();
|
||||
}
|
||||
|
||||
/// Compiles the `rust_test_helpers.c` library which we used in various
|
||||
/// `run-pass` test suites for ABI testing.
|
||||
pub fn test_helpers(build: &Build, target: &str) {
|
||||
let dst = build.test_helpers_out(target);
|
||||
let src = build.src.join("src/rt/rust_test_helpers.c");
|
||||
if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
|
||||
return
|
||||
}
|
||||
|
||||
println!("Building test helpers");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
let mut cfg = gcc::Config::new();
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&dst)
|
||||
.target(target)
|
||||
.host(&build.config.build)
|
||||
.opt_level(0)
|
||||
.debug(false)
|
||||
.file(build.src.join("src/rt/rust_test_helpers.c"))
|
||||
.compile("librust_test_helpers.a");
|
||||
}
|
||||
@ -36,8 +36,8 @@ use std::process::Command;
|
||||
use build_helper::{cc2ar, output};
|
||||
use gcc;
|
||||
|
||||
use build::Build;
|
||||
use build::config::Target;
|
||||
use Build;
|
||||
use config::Target;
|
||||
|
||||
pub fn find(build: &mut Build) {
|
||||
// For all targets we're going to need a C compiler for building some shims
|
||||
@ -22,7 +22,7 @@ use std::process::Command;
|
||||
use build_helper::output;
|
||||
use md5;
|
||||
|
||||
use build::Build;
|
||||
use Build;
|
||||
|
||||
pub fn collect(build: &mut Build) {
|
||||
// Currently the canonical source for the release number (e.g. 1.10.0) and
|
||||
@ -20,10 +20,9 @@ use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
|
||||
use build_helper::output;
|
||||
use bootstrap::{dylib_path, dylib_path_var};
|
||||
|
||||
use build::{Build, Compiler, Mode};
|
||||
use build::util;
|
||||
use {Build, Compiler, Mode};
|
||||
use util::{self, dylib_path, dylib_path_var};
|
||||
|
||||
const ADB_TEST_DIR: &'static str = "/data/tmp";
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use build::Build;
|
||||
use Build;
|
||||
|
||||
pub fn clean(build: &Build) {
|
||||
rm_rf(build, "tmp".as_ref());
|
||||
@ -23,8 +23,8 @@ use std::process::Command;
|
||||
|
||||
use build_helper::output;
|
||||
|
||||
use build::util::{exe, staticlib, libdir, mtime, is_dylib, copy};
|
||||
use build::{Build, Compiler, Mode};
|
||||
use util::{exe, staticlib, libdir, mtime, is_dylib, copy};
|
||||
use {Build, Compiler, Mode};
|
||||
|
||||
/// Build the standard library.
|
||||
///
|
||||
@ -92,8 +92,7 @@ pub fn std_link(build: &Build,
|
||||
}
|
||||
add_to_sysroot(&out_dir, &libdir);
|
||||
|
||||
if target.contains("musl") &&
|
||||
(target.contains("x86_64") || target.contains("i686")) {
|
||||
if target.contains("musl") && !target.contains("mips") {
|
||||
copy_third_party_objects(build, target, &libdir);
|
||||
}
|
||||
}
|
||||
@ -199,6 +198,10 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
|
||||
if !build.unstable_features {
|
||||
cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
|
||||
}
|
||||
// Flag that rust llvm is in use
|
||||
if build.is_rust_llvm(target) {
|
||||
cargo.env("LLVM_RUSTLLVM", "1");
|
||||
}
|
||||
cargo.env("LLVM_CONFIG", build.llvm_config(target));
|
||||
if build.config.llvm_static_stdcpp {
|
||||
cargo.env("LLVM_STATIC_STDCPP",
|
||||
@ -72,6 +72,7 @@ pub struct Config {
|
||||
// libstd features
|
||||
pub debug_jemalloc: bool,
|
||||
pub use_jemalloc: bool,
|
||||
pub backtrace: bool, // support for RUST_BACKTRACE
|
||||
|
||||
// misc
|
||||
pub channel: String,
|
||||
@ -134,6 +135,7 @@ struct Rust {
|
||||
debuginfo: Option<bool>,
|
||||
debug_jemalloc: Option<bool>,
|
||||
use_jemalloc: Option<bool>,
|
||||
backtrace: Option<bool>,
|
||||
default_linker: Option<String>,
|
||||
default_ar: Option<String>,
|
||||
channel: Option<String>,
|
||||
@ -158,6 +160,7 @@ impl Config {
|
||||
let mut config = Config::default();
|
||||
config.llvm_optimize = true;
|
||||
config.use_jemalloc = true;
|
||||
config.backtrace = true;
|
||||
config.rust_optimize = true;
|
||||
config.rust_optimize_tests = true;
|
||||
config.submodules = true;
|
||||
@ -230,6 +233,7 @@ impl Config {
|
||||
set(&mut config.rust_rpath, rust.rpath);
|
||||
set(&mut config.debug_jemalloc, rust.debug_jemalloc);
|
||||
set(&mut config.use_jemalloc, rust.use_jemalloc);
|
||||
set(&mut config.backtrace, rust.backtrace);
|
||||
set(&mut config.channel, rust.channel.clone());
|
||||
config.rustc_default_linker = rust.default_linker.clone();
|
||||
config.rustc_default_ar = rust.default_ar.clone();
|
||||
@ -317,6 +321,7 @@ impl Config {
|
||||
("OPTIMIZE_TESTS", self.rust_optimize_tests),
|
||||
("DEBUGINFO_TESTS", self.rust_debuginfo_tests),
|
||||
("LOCAL_REBUILD", self.local_rebuild),
|
||||
("NINJA", self.ninja),
|
||||
}
|
||||
|
||||
match key {
|
||||
@ -99,6 +99,9 @@
|
||||
# Whether or not jemalloc is built with its debug option set
|
||||
#debug-jemalloc = false
|
||||
|
||||
# Whether or not `panic!`s generate backtraces (RUST_BACKTRACE)
|
||||
#backtrace = true
|
||||
|
||||
# The default linker that will be used by the generated compiler. Note that this
|
||||
# is not the linker used to link said compiler.
|
||||
#default-linker = "cc"
|
||||
|
||||
@ -23,8 +23,9 @@ use std::io::Write;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
|
||||
use build::{Build, Compiler};
|
||||
use build::util::{cp_r, libdir, is_dylib};
|
||||
use {Build, Compiler};
|
||||
use util::{cp_r, libdir, is_dylib, cp_filtered, copy};
|
||||
use regex::{RegexSet, quote};
|
||||
|
||||
fn package_vers(build: &Build) -> &str {
|
||||
match &build.config.channel[..] {
|
||||
@ -284,6 +285,119 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
|
||||
t!(fs::remove_dir_all(&image));
|
||||
}
|
||||
|
||||
/// Creates the `rust-src` installer component and the plain source tarball
|
||||
pub fn rust_src(build: &Build) {
|
||||
println!("Dist src");
|
||||
let plain_name = format!("rustc-{}-src", package_vers(build));
|
||||
let name = format!("rust-src-{}", package_vers(build));
|
||||
let image = tmpdir(build).join(format!("{}-image", name));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
|
||||
let dst = image.join("lib/rustlib/src");
|
||||
let dst_src = dst.join("rust");
|
||||
let plain_dst_src = dst.join(&plain_name);
|
||||
t!(fs::create_dir_all(&dst_src));
|
||||
|
||||
// This is the set of root paths which will become part of the source package
|
||||
let src_files = [
|
||||
"COPYRIGHT",
|
||||
"LICENSE-APACHE",
|
||||
"LICENSE-MIT",
|
||||
"CONTRIBUTING.md",
|
||||
"README.md",
|
||||
"RELEASES.md",
|
||||
"configure",
|
||||
"Makefile.in"
|
||||
];
|
||||
let src_dirs = [
|
||||
"man",
|
||||
"src",
|
||||
"mk"
|
||||
];
|
||||
|
||||
// Exclude paths matching these wildcard expressions
|
||||
let excludes = [
|
||||
// exclude-vcs
|
||||
"CVS", "RCS", "SCCS", ".git", ".gitignore", ".gitmodules", ".gitattributes", ".cvsignore",
|
||||
".svn", ".arch-ids", "{arch}", "=RELEASE-ID", "=meta-update", "=update", ".bzr",
|
||||
".bzrignore", ".bzrtags", ".hg", ".hgignore", ".hgrags", "_darcs",
|
||||
// extensions
|
||||
"*~", "*.pyc",
|
||||
// misc
|
||||
"llvm/test/*/*.ll",
|
||||
"llvm/test/*/*.td",
|
||||
"llvm/test/*/*.s",
|
||||
"llvm/test/*/*/*.ll",
|
||||
"llvm/test/*/*/*.td",
|
||||
"llvm/test/*/*/*.s"
|
||||
];
|
||||
|
||||
// Construct a set of regexes for efficiently testing whether paths match one of the above
|
||||
// expressions.
|
||||
let regex_set = t!(RegexSet::new(
|
||||
// This converts a wildcard expression to a regex
|
||||
excludes.iter().map(|&s| {
|
||||
// Prefix ensures that matching starts on a path separator boundary
|
||||
r"^(.*[\\/])?".to_owned() + (
|
||||
// Escape the expression to produce a regex matching exactly that string
|
||||
"e(s)
|
||||
// Replace slashes with a pattern matching either forward or backslash
|
||||
.replace(r"/", r"[\\/]")
|
||||
// Replace wildcards with a pattern matching a single path segment, ie. containing
|
||||
// no slashes.
|
||||
.replace(r"\*", r"[^\\/]*")
|
||||
// Suffix anchors to the end of the path
|
||||
) + "$"
|
||||
})
|
||||
));
|
||||
|
||||
// Create a filter which skips files which match the regex set or contain invalid unicode
|
||||
let filter_fn = move |path: &Path| {
|
||||
if let Some(path) = path.to_str() {
|
||||
!regex_set.is_match(path)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
// Copy the directories using our filter
|
||||
for item in &src_dirs {
|
||||
let dst = &dst_src.join(item);
|
||||
t!(fs::create_dir(dst));
|
||||
cp_filtered(&build.src.join(item), dst, &filter_fn);
|
||||
}
|
||||
// Copy the files normally
|
||||
for item in &src_files {
|
||||
copy(&build.src.join(item), &dst_src.join(item));
|
||||
}
|
||||
|
||||
// Create source tarball in rust-installer format
|
||||
let mut cmd = Command::new("sh");
|
||||
cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh")))
|
||||
.arg("--product-name=Rust")
|
||||
.arg("--rel-manifest-dir=rustlib")
|
||||
.arg("--success-message=Awesome-Source.")
|
||||
.arg(format!("--image-dir={}", sanitize_sh(&image)))
|
||||
.arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build))))
|
||||
.arg(format!("--output-dir={}", sanitize_sh(&distdir(build))))
|
||||
.arg(format!("--package-name={}", name))
|
||||
.arg("--component-name=rust-src")
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
build.run(&mut cmd);
|
||||
|
||||
// Rename directory, so that root folder of tarball has the correct name
|
||||
t!(fs::rename(&dst_src, &plain_dst_src));
|
||||
|
||||
// Create plain source tarball
|
||||
let mut cmd = Command::new("tar");
|
||||
cmd.arg("-czf").arg(sanitize_sh(&distdir(build).join(&format!("{}.tar.gz", plain_name))))
|
||||
.arg(&plain_name)
|
||||
.current_dir(&dst);
|
||||
build.run(&mut cmd);
|
||||
|
||||
t!(fs::remove_dir_all(&image));
|
||||
}
|
||||
|
||||
fn install(src: &Path, dstdir: &Path, perms: u32) {
|
||||
let dst = dstdir.join(src.file_name().unwrap());
|
||||
t!(fs::create_dir_all(dstdir));
|
||||
@ -22,8 +22,8 @@ use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use build::{Build, Compiler, Mode};
|
||||
use build::util::{up_to_date, cp_r};
|
||||
use {Build, Compiler, Mode};
|
||||
use util::{up_to_date, cp_r};
|
||||
|
||||
/// Invoke `rustbook` as compiled in `stage` for `target` for the doc book
|
||||
/// `name` into the `out` path.
|
||||
@ -155,6 +155,7 @@ pub fn std(build: &Build, stage: u32, target: &str, out: &Path) {
|
||||
/// is largely just a wrapper around `cargo doc`.
|
||||
pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
|
||||
println!("Documenting stage{} test ({})", stage, target);
|
||||
t!(fs::create_dir_all(out));
|
||||
let compiler = Compiler::new(stage, &build.config.build);
|
||||
let out_dir = build.stage_out(&compiler, Mode::Libtest)
|
||||
.join(target).join("doc");
|
||||
@ -175,11 +176,12 @@ pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
|
||||
/// dependencies. This is largely just a wrapper around `cargo doc`.
|
||||
pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) {
|
||||
println!("Documenting stage{} compiler ({})", stage, target);
|
||||
t!(fs::create_dir_all(out));
|
||||
let compiler = Compiler::new(stage, &build.config.build);
|
||||
let out_dir = build.stage_out(&compiler, Mode::Librustc)
|
||||
.join(target).join("doc");
|
||||
let rustdoc = build.rustdoc(&compiler);
|
||||
if !up_to_date(&rustdoc, &out_dir.join("rustc/index.html")) {
|
||||
if !up_to_date(&rustdoc, &out_dir.join("rustc/index.html")) && out_dir.exists() {
|
||||
t!(fs::remove_dir_all(&out_dir));
|
||||
}
|
||||
let mut cargo = build.cargo(&compiler, Mode::Librustc, target, "doc");
|
||||
@ -8,30 +8,915 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! A small helper library shared between the build system's executables
|
||||
//! Implementation of rustbuild, the Rust build system.
|
||||
//!
|
||||
//! Currently this just has some simple utilities for modifying the dynamic
|
||||
//! library lookup path.
|
||||
//! This module, and its descendants, are the implementation of the Rust build
|
||||
//! system. Most of this build system is backed by Cargo but the outer layer
|
||||
//! here serves as the ability to orchestrate calling Cargo, sequencing Cargo
|
||||
//! builds, building artifacts like LLVM, etc.
|
||||
//!
|
||||
//! More documentation can be found in each respective module below.
|
||||
|
||||
extern crate build_helper;
|
||||
extern crate cmake;
|
||||
extern crate filetime;
|
||||
extern crate gcc;
|
||||
extern crate getopts;
|
||||
extern crate md5;
|
||||
extern crate num_cpus;
|
||||
extern crate rustc_serialize;
|
||||
extern crate toml;
|
||||
extern crate regex;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::fs::{self, File};
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
|
||||
/// Returns the environment variable which the dynamic library lookup path
|
||||
/// resides in for this platform.
|
||||
pub fn dylib_path_var() -> &'static str {
|
||||
if cfg!(target_os = "windows") {
|
||||
"PATH"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"DYLD_LIBRARY_PATH"
|
||||
} else {
|
||||
"LD_LIBRARY_PATH"
|
||||
use build_helper::{run_silent, output};
|
||||
|
||||
use util::{exe, mtime, libdir, add_lib_path};
|
||||
|
||||
/// A helper macro to `unwrap` a result except also print out details like:
|
||||
///
|
||||
/// * The file/line of the panic
|
||||
/// * The expression that failed
|
||||
/// * The error itself
|
||||
///
|
||||
/// This is currently used judiciously throughout the build system rather than
|
||||
/// using a `Result` with `try!`, but this may change on day...
|
||||
macro_rules! t {
|
||||
($e:expr) => (match $e {
|
||||
Ok(e) => e,
|
||||
Err(e) => panic!("{} failed with {}", stringify!($e), e),
|
||||
})
|
||||
}
|
||||
|
||||
mod cc;
|
||||
mod channel;
|
||||
mod check;
|
||||
mod clean;
|
||||
mod compile;
|
||||
mod config;
|
||||
mod dist;
|
||||
mod doc;
|
||||
mod flags;
|
||||
mod native;
|
||||
mod sanity;
|
||||
mod step;
|
||||
pub mod util;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod job;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
mod job {
|
||||
pub unsafe fn setup() {}
|
||||
}
|
||||
|
||||
pub use config::Config;
|
||||
pub use flags::Flags;
|
||||
|
||||
/// A structure representing a Rust compiler.
|
||||
///
|
||||
/// Each compiler has a `stage` that it is associated with and a `host` that
|
||||
/// corresponds to the platform the compiler runs on. This structure is used as
|
||||
/// a parameter to many methods below.
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
|
||||
pub struct Compiler<'a> {
|
||||
stage: u32,
|
||||
host: &'a str,
|
||||
}
|
||||
|
||||
/// Global configuration for the build system.
|
||||
///
|
||||
/// This structure transitively contains all configuration for the build system.
|
||||
/// All filesystem-encoded configuration is in `config`, all flags are in
|
||||
/// `flags`, and then parsed or probed information is listed in the keys below.
|
||||
///
|
||||
/// This structure is a parameter of almost all methods in the build system,
|
||||
/// although most functions are implemented as free functions rather than
|
||||
/// methods specifically on this structure itself (to make it easier to
|
||||
/// organize).
|
||||
pub struct Build {
|
||||
// User-specified configuration via config.toml
|
||||
config: Config,
|
||||
|
||||
// User-specified configuration via CLI flags
|
||||
flags: Flags,
|
||||
|
||||
// Derived properties from the above two configurations
|
||||
cargo: PathBuf,
|
||||
rustc: PathBuf,
|
||||
src: PathBuf,
|
||||
out: PathBuf,
|
||||
release: String,
|
||||
unstable_features: bool,
|
||||
ver_hash: Option<String>,
|
||||
short_ver_hash: Option<String>,
|
||||
ver_date: Option<String>,
|
||||
version: String,
|
||||
package_vers: String,
|
||||
local_rebuild: bool,
|
||||
bootstrap_key: String,
|
||||
bootstrap_key_stage0: String,
|
||||
|
||||
// Probed tools at runtime
|
||||
gdb_version: Option<String>,
|
||||
lldb_version: Option<String>,
|
||||
lldb_python_dir: Option<String>,
|
||||
|
||||
// Runtime state filled in later on
|
||||
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
||||
cxx: HashMap<String, gcc::Tool>,
|
||||
compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
|
||||
}
|
||||
|
||||
/// The various "modes" of invoking Cargo.
|
||||
///
|
||||
/// These entries currently correspond to the various output directories of the
|
||||
/// build system, with each mod generating output in a different directory.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Mode {
|
||||
/// This cargo is going to build the standard library, placing output in the
|
||||
/// "stageN-std" directory.
|
||||
Libstd,
|
||||
|
||||
/// This cargo is going to build libtest, placing output in the
|
||||
/// "stageN-test" directory.
|
||||
Libtest,
|
||||
|
||||
/// This cargo is going to build librustc and compiler libraries, placing
|
||||
/// output in the "stageN-rustc" directory.
|
||||
Librustc,
|
||||
|
||||
/// This cargo is going to some build tool, placing output in the
|
||||
/// "stageN-tools" directory.
|
||||
Tool,
|
||||
}
|
||||
|
||||
impl Build {
|
||||
/// Creates a new set of build configuration from the `flags` on the command
|
||||
/// line and the filesystem `config`.
|
||||
///
|
||||
/// By default all build output will be placed in the current directory.
|
||||
pub fn new(flags: Flags, config: Config) -> Build {
|
||||
let cwd = t!(env::current_dir());
|
||||
let src = flags.src.clone().unwrap_or(cwd.clone());
|
||||
let out = cwd.join("build");
|
||||
|
||||
let stage0_root = out.join(&config.build).join("stage0/bin");
|
||||
let rustc = match config.rustc {
|
||||
Some(ref s) => PathBuf::from(s),
|
||||
None => stage0_root.join(exe("rustc", &config.build)),
|
||||
};
|
||||
let cargo = match config.cargo {
|
||||
Some(ref s) => PathBuf::from(s),
|
||||
None => stage0_root.join(exe("cargo", &config.build)),
|
||||
};
|
||||
let local_rebuild = config.local_rebuild;
|
||||
|
||||
Build {
|
||||
flags: flags,
|
||||
config: config,
|
||||
cargo: cargo,
|
||||
rustc: rustc,
|
||||
src: src,
|
||||
out: out,
|
||||
|
||||
release: String::new(),
|
||||
unstable_features: false,
|
||||
ver_hash: None,
|
||||
short_ver_hash: None,
|
||||
ver_date: None,
|
||||
version: String::new(),
|
||||
local_rebuild: local_rebuild,
|
||||
bootstrap_key: String::new(),
|
||||
bootstrap_key_stage0: String::new(),
|
||||
package_vers: String::new(),
|
||||
cc: HashMap::new(),
|
||||
cxx: HashMap::new(),
|
||||
compiler_rt_built: RefCell::new(HashMap::new()),
|
||||
gdb_version: None,
|
||||
lldb_version: None,
|
||||
lldb_python_dir: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes the entire build, as configured by the flags and configuration.
|
||||
pub fn build(&mut self) {
|
||||
use step::Source::*;
|
||||
|
||||
unsafe {
|
||||
job::setup();
|
||||
}
|
||||
|
||||
if self.flags.clean {
|
||||
return clean::clean(self);
|
||||
}
|
||||
|
||||
self.verbose("finding compilers");
|
||||
cc::find(self);
|
||||
self.verbose("running sanity check");
|
||||
sanity::check(self);
|
||||
self.verbose("collecting channel variables");
|
||||
channel::collect(self);
|
||||
// If local-rust is the same as the current version, then force a local-rebuild
|
||||
let local_version_verbose = output(
|
||||
Command::new(&self.rustc).arg("--version").arg("--verbose"));
|
||||
let local_release = local_version_verbose
|
||||
.lines().filter(|x| x.starts_with("release:"))
|
||||
.next().unwrap().trim_left_matches("release:").trim();
|
||||
if local_release == self.release {
|
||||
self.verbose(&format!("auto-detected local-rebuild {}", self.release));
|
||||
self.local_rebuild = true;
|
||||
}
|
||||
self.verbose("updating submodules");
|
||||
self.update_submodules();
|
||||
|
||||
// The main loop of the build system.
|
||||
//
|
||||
// The `step::all` function returns a topographically sorted list of all
|
||||
// steps that need to be executed as part of this build. Each step has a
|
||||
// corresponding entry in `step.rs` and indicates some unit of work that
|
||||
// needs to be done as part of the build.
|
||||
//
|
||||
// Almost all of these are simple one-liners that shell out to the
|
||||
// corresponding functionality in the extra modules, where more
|
||||
// documentation can be found.
|
||||
for target in step::all(self) {
|
||||
let doc_out = self.out.join(&target.target).join("doc");
|
||||
match target.src {
|
||||
Llvm { _dummy } => {
|
||||
native::llvm(self, target.target);
|
||||
}
|
||||
CompilerRt { _dummy } => {
|
||||
native::compiler_rt(self, target.target);
|
||||
}
|
||||
TestHelpers { _dummy } => {
|
||||
native::test_helpers(self, target.target);
|
||||
}
|
||||
Libstd { compiler } => {
|
||||
compile::std(self, target.target, &compiler);
|
||||
}
|
||||
Libtest { compiler } => {
|
||||
compile::test(self, target.target, &compiler);
|
||||
}
|
||||
Librustc { compiler } => {
|
||||
compile::rustc(self, target.target, &compiler);
|
||||
}
|
||||
LibstdLink { compiler, host } => {
|
||||
compile::std_link(self, target.target, &compiler, host);
|
||||
}
|
||||
LibtestLink { compiler, host } => {
|
||||
compile::test_link(self, target.target, &compiler, host);
|
||||
}
|
||||
LibrustcLink { compiler, host } => {
|
||||
compile::rustc_link(self, target.target, &compiler, host);
|
||||
}
|
||||
Rustc { stage: 0 } => {
|
||||
// nothing to do...
|
||||
}
|
||||
Rustc { stage } => {
|
||||
compile::assemble_rustc(self, stage, target.target);
|
||||
}
|
||||
ToolLinkchecker { stage } => {
|
||||
compile::tool(self, stage, target.target, "linkchecker");
|
||||
}
|
||||
ToolRustbook { stage } => {
|
||||
compile::tool(self, stage, target.target, "rustbook");
|
||||
}
|
||||
ToolErrorIndex { stage } => {
|
||||
compile::tool(self, stage, target.target,
|
||||
"error_index_generator");
|
||||
}
|
||||
ToolCargoTest { stage } => {
|
||||
compile::tool(self, stage, target.target, "cargotest");
|
||||
}
|
||||
ToolTidy { stage } => {
|
||||
compile::tool(self, stage, target.target, "tidy");
|
||||
}
|
||||
ToolCompiletest { stage } => {
|
||||
compile::tool(self, stage, target.target, "compiletest");
|
||||
}
|
||||
DocBook { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "book", &doc_out);
|
||||
}
|
||||
DocNomicon { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "nomicon",
|
||||
&doc_out);
|
||||
}
|
||||
DocStyle { stage } => {
|
||||
doc::rustbook(self, stage, target.target, "style",
|
||||
&doc_out);
|
||||
}
|
||||
DocStandalone { stage } => {
|
||||
doc::standalone(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocStd { stage } => {
|
||||
doc::std(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocTest { stage } => {
|
||||
doc::test(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocRustc { stage } => {
|
||||
doc::rustc(self, stage, target.target, &doc_out);
|
||||
}
|
||||
DocErrorIndex { stage } => {
|
||||
doc::error_index(self, stage, target.target, &doc_out);
|
||||
}
|
||||
|
||||
CheckLinkcheck { stage } => {
|
||||
check::linkcheck(self, stage, target.target);
|
||||
}
|
||||
CheckCargoTest { stage } => {
|
||||
check::cargotest(self, stage, target.target);
|
||||
}
|
||||
CheckTidy { stage } => {
|
||||
check::tidy(self, stage, target.target);
|
||||
}
|
||||
CheckRPass { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass", "run-pass");
|
||||
}
|
||||
CheckRPassFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass", "run-pass-fulldeps");
|
||||
}
|
||||
CheckCFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"compile-fail", "compile-fail");
|
||||
}
|
||||
CheckCFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"compile-fail", "compile-fail-fulldeps")
|
||||
}
|
||||
CheckPFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"parse-fail", "parse-fail");
|
||||
}
|
||||
CheckRFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-fail", "run-fail");
|
||||
}
|
||||
CheckRFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-fail", "run-fail-fulldeps");
|
||||
}
|
||||
CheckPretty { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "pretty");
|
||||
}
|
||||
CheckPrettyRPass { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass");
|
||||
}
|
||||
CheckPrettyRPassFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass-fulldeps");
|
||||
}
|
||||
CheckPrettyRFail { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-fail");
|
||||
}
|
||||
CheckPrettyRFailFull { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-fail-fulldeps");
|
||||
}
|
||||
CheckPrettyRPassValgrind { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"pretty", "run-pass-valgrind");
|
||||
}
|
||||
CheckMirOpt { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"mir-opt", "mir-opt");
|
||||
}
|
||||
CheckCodegen { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"codegen", "codegen");
|
||||
}
|
||||
CheckCodegenUnits { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"codegen-units", "codegen-units");
|
||||
}
|
||||
CheckIncremental { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"incremental", "incremental");
|
||||
}
|
||||
CheckUi { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"ui", "ui");
|
||||
}
|
||||
CheckDebuginfo { compiler } => {
|
||||
if target.target.contains("msvc") {
|
||||
// nothing to do
|
||||
} else if target.target.contains("apple") {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"debuginfo-lldb", "debuginfo");
|
||||
} else {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"debuginfo-gdb", "debuginfo");
|
||||
}
|
||||
}
|
||||
CheckRustdoc { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"rustdoc", "rustdoc");
|
||||
}
|
||||
CheckRPassValgrind { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-pass-valgrind", "run-pass-valgrind");
|
||||
}
|
||||
CheckDocs { compiler } => {
|
||||
check::docs(self, &compiler);
|
||||
}
|
||||
CheckErrorIndex { compiler } => {
|
||||
check::error_index(self, &compiler);
|
||||
}
|
||||
CheckRMake { compiler } => {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
"run-make", "run-make")
|
||||
}
|
||||
CheckCrateStd { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Libstd)
|
||||
}
|
||||
CheckCrateTest { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Libtest)
|
||||
}
|
||||
CheckCrateRustc { compiler } => {
|
||||
check::krate(self, &compiler, target.target, Mode::Librustc)
|
||||
}
|
||||
|
||||
DistDocs { stage } => dist::docs(self, stage, target.target),
|
||||
DistMingw { _dummy } => dist::mingw(self, target.target),
|
||||
DistRustc { stage } => dist::rustc(self, stage, target.target),
|
||||
DistStd { compiler } => dist::std(self, &compiler, target.target),
|
||||
DistSrc { _dummy } => dist::rust_src(self),
|
||||
|
||||
DebuggerScripts { stage } => {
|
||||
let compiler = Compiler::new(stage, target.target);
|
||||
dist::debugger_scripts(self,
|
||||
&self.sysroot(&compiler),
|
||||
target.target);
|
||||
}
|
||||
|
||||
AndroidCopyLibs { compiler } => {
|
||||
check::android_copy_libs(self, &compiler, target.target);
|
||||
}
|
||||
|
||||
// pseudo-steps
|
||||
Dist { .. } |
|
||||
Doc { .. } |
|
||||
CheckTarget { .. } |
|
||||
Check { .. } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates all git submodules that we have.
|
||||
///
|
||||
/// This will detect if any submodules are out of date an run the necessary
|
||||
/// commands to sync them all with upstream.
|
||||
fn update_submodules(&self) {
|
||||
if !self.config.submodules {
|
||||
return
|
||||
}
|
||||
if fs::metadata(self.src.join(".git")).is_err() {
|
||||
return
|
||||
}
|
||||
let git_submodule = || {
|
||||
let mut cmd = Command::new("git");
|
||||
cmd.current_dir(&self.src).arg("submodule");
|
||||
return cmd
|
||||
};
|
||||
|
||||
// FIXME: this takes a seriously long time to execute on Windows and a
|
||||
// nontrivial amount of time on Unix, we should have a better way
|
||||
// of detecting whether we need to run all the submodule commands
|
||||
// below.
|
||||
let out = output(git_submodule().arg("status"));
|
||||
if !out.lines().any(|l| l.starts_with("+") || l.starts_with("-")) {
|
||||
return
|
||||
}
|
||||
|
||||
self.run(git_submodule().arg("sync"));
|
||||
self.run(git_submodule().arg("init"));
|
||||
self.run(git_submodule().arg("update"));
|
||||
self.run(git_submodule().arg("update").arg("--recursive"));
|
||||
self.run(git_submodule().arg("status").arg("--recursive"));
|
||||
self.run(git_submodule().arg("foreach").arg("--recursive")
|
||||
.arg("git").arg("clean").arg("-fdx"));
|
||||
self.run(git_submodule().arg("foreach").arg("--recursive")
|
||||
.arg("git").arg("checkout").arg("."));
|
||||
}
|
||||
|
||||
/// Clear out `dir` if `input` is newer.
|
||||
///
|
||||
/// After this executes, it will also ensure that `dir` exists.
|
||||
fn clear_if_dirty(&self, dir: &Path, input: &Path) {
|
||||
let stamp = dir.join(".stamp");
|
||||
if mtime(&stamp) < mtime(input) {
|
||||
self.verbose(&format!("Dirty - {}", dir.display()));
|
||||
let _ = fs::remove_dir_all(dir);
|
||||
}
|
||||
t!(fs::create_dir_all(dir));
|
||||
t!(File::create(stamp));
|
||||
}
|
||||
|
||||
/// Prepares an invocation of `cargo` to be run.
|
||||
///
|
||||
/// This will create a `Command` that represents a pending execution of
|
||||
/// Cargo. This cargo will be configured to use `compiler` as the actual
|
||||
/// rustc compiler, its output will be scoped by `mode`'s output directory,
|
||||
/// it will pass the `--target` flag for the specified `target`, and will be
|
||||
/// executing the Cargo command `cmd`.
|
||||
fn cargo(&self,
|
||||
compiler: &Compiler,
|
||||
mode: Mode,
|
||||
target: &str,
|
||||
cmd: &str) -> Command {
|
||||
let mut cargo = Command::new(&self.cargo);
|
||||
let out_dir = self.stage_out(compiler, mode);
|
||||
cargo.env("CARGO_TARGET_DIR", out_dir)
|
||||
.arg(cmd)
|
||||
.arg("-j").arg(self.jobs().to_string())
|
||||
.arg("--target").arg(target);
|
||||
|
||||
let stage;
|
||||
if compiler.stage == 0 && self.local_rebuild {
|
||||
// Assume the local-rebuild rustc already has stage1 features.
|
||||
stage = 1;
|
||||
} else {
|
||||
stage = compiler.stage;
|
||||
}
|
||||
|
||||
// Customize the compiler we're running. Specify the compiler to cargo
|
||||
// as our shim and then pass it some various options used to configure
|
||||
// how the actual compiler itself is called.
|
||||
//
|
||||
// These variables are primarily all read by
|
||||
// src/bootstrap/{rustc,rustdoc.rs}
|
||||
cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
|
||||
.env("RUSTC_REAL", self.compiler_path(compiler))
|
||||
.env("RUSTC_STAGE", stage.to_string())
|
||||
.env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string())
|
||||
.env("RUSTC_CODEGEN_UNITS",
|
||||
self.config.rust_codegen_units.to_string())
|
||||
.env("RUSTC_DEBUG_ASSERTIONS",
|
||||
self.config.rust_debug_assertions.to_string())
|
||||
.env("RUSTC_SNAPSHOT", &self.rustc)
|
||||
.env("RUSTC_SYSROOT", self.sysroot(compiler))
|
||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
||||
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir())
|
||||
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
||||
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
||||
.env("RUSTDOC_REAL", self.rustdoc(compiler))
|
||||
.env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
|
||||
|
||||
self.add_bootstrap_key(compiler, &mut cargo);
|
||||
|
||||
// Specify some various options for build scripts used throughout
|
||||
// the build.
|
||||
//
|
||||
// FIXME: the guard against msvc shouldn't need to be here
|
||||
if !target.contains("msvc") {
|
||||
cargo.env(format!("CC_{}", target), self.cc(target))
|
||||
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
|
||||
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
|
||||
}
|
||||
|
||||
// If we're building for OSX, inform the compiler and the linker that
|
||||
// we want to build a compiler runnable on 10.7
|
||||
if target.contains("apple-darwin") {
|
||||
cargo.env("MACOSX_DEPLOYMENT_TARGET", "10.7");
|
||||
}
|
||||
|
||||
// Environment variables *required* needed throughout the build
|
||||
//
|
||||
// FIXME: should update code to not require this env var
|
||||
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
|
||||
|
||||
if self.config.verbose || self.flags.verbose {
|
||||
cargo.arg("-v");
|
||||
}
|
||||
if self.config.rust_optimize {
|
||||
cargo.arg("--release");
|
||||
}
|
||||
return cargo
|
||||
}
|
||||
|
||||
/// Get a path to the compiler specified.
|
||||
fn compiler_path(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.rustc.clone()
|
||||
} else {
|
||||
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the specified tool built by the specified compiler
|
||||
fn tool(&self, compiler: &Compiler, tool: &str) -> PathBuf {
|
||||
self.cargo_out(compiler, Mode::Tool, compiler.host)
|
||||
.join(exe(tool, compiler.host))
|
||||
}
|
||||
|
||||
/// Get the `rustdoc` executable next to the specified compiler
|
||||
fn rustdoc(&self, compiler: &Compiler) -> PathBuf {
|
||||
let mut rustdoc = self.compiler_path(compiler);
|
||||
rustdoc.pop();
|
||||
rustdoc.push(exe("rustdoc", compiler.host));
|
||||
return rustdoc
|
||||
}
|
||||
|
||||
/// Get a `Command` which is ready to run `tool` in `stage` built for
|
||||
/// `host`.
|
||||
fn tool_cmd(&self, compiler: &Compiler, tool: &str) -> Command {
|
||||
let mut cmd = Command::new(self.tool(&compiler, tool));
|
||||
let host = compiler.host;
|
||||
let paths = vec![
|
||||
self.cargo_out(compiler, Mode::Libstd, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Libtest, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Librustc, host).join("deps"),
|
||||
self.cargo_out(compiler, Mode::Tool, host).join("deps"),
|
||||
];
|
||||
add_lib_path(paths, &mut cmd);
|
||||
return cmd
|
||||
}
|
||||
|
||||
/// Get the space-separated set of activated features for the standard
|
||||
/// library.
|
||||
fn std_features(&self) -> String {
|
||||
let mut features = String::new();
|
||||
if self.config.debug_jemalloc {
|
||||
features.push_str(" debug-jemalloc");
|
||||
}
|
||||
if self.config.use_jemalloc {
|
||||
features.push_str(" jemalloc");
|
||||
}
|
||||
if self.config.backtrace {
|
||||
features.push_str(" backtrace");
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
||||
/// Get the space-separated set of activated features for the compiler.
|
||||
fn rustc_features(&self) -> String {
|
||||
let mut features = String::new();
|
||||
if self.config.use_jemalloc {
|
||||
features.push_str(" jemalloc");
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
||||
/// Component directory that Cargo will produce output into (e.g.
|
||||
/// release/debug)
|
||||
fn cargo_dir(&self) -> &'static str {
|
||||
if self.config.rust_optimize {"release"} else {"debug"}
|
||||
}
|
||||
|
||||
/// Returns the sysroot for the `compiler` specified that *this build system
|
||||
/// generates*.
|
||||
///
|
||||
/// That is, the sysroot for the stage0 compiler is not what the compiler
|
||||
/// thinks it is by default, but it's the same as the default for stages
|
||||
/// 1-3.
|
||||
fn sysroot(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.stage == 0 {
|
||||
self.out.join(compiler.host).join("stage0-sysroot")
|
||||
} else {
|
||||
self.out.join(compiler.host).join(format!("stage{}", compiler.stage))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the libdir where the standard library and other artifacts are
|
||||
/// found for a compiler's sysroot.
|
||||
fn sysroot_libdir(&self, compiler: &Compiler, target: &str) -> PathBuf {
|
||||
self.sysroot(compiler).join("lib").join("rustlib")
|
||||
.join(target).join("lib")
|
||||
}
|
||||
|
||||
/// Returns the root directory for all output generated in a particular
|
||||
/// stage when running with a particular host compiler.
|
||||
///
|
||||
/// The mode indicates what the root directory is for.
|
||||
fn stage_out(&self, compiler: &Compiler, mode: Mode) -> PathBuf {
|
||||
let suffix = match mode {
|
||||
Mode::Libstd => "-std",
|
||||
Mode::Libtest => "-test",
|
||||
Mode::Tool => "-tools",
|
||||
Mode::Librustc => "-rustc",
|
||||
};
|
||||
self.out.join(compiler.host)
|
||||
.join(format!("stage{}{}", compiler.stage, suffix))
|
||||
}
|
||||
|
||||
/// Returns the root output directory for all Cargo output in a given stage,
|
||||
/// running a particular comipler, wehther or not we're building the
|
||||
/// standard library, and targeting the specified architecture.
|
||||
fn cargo_out(&self,
|
||||
compiler: &Compiler,
|
||||
mode: Mode,
|
||||
target: &str) -> PathBuf {
|
||||
self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
|
||||
}
|
||||
|
||||
/// Root output directory for LLVM compiled for `target`
|
||||
///
|
||||
/// Note that if LLVM is configured externally then the directory returned
|
||||
/// will likely be empty.
|
||||
fn llvm_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("llvm")
|
||||
}
|
||||
|
||||
/// Returns true if no custom `llvm-config` is set for the specified target.
|
||||
///
|
||||
/// If no custom `llvm-config` was specified then Rust's llvm will be used.
|
||||
fn is_rust_llvm(&self, target: &str) -> bool {
|
||||
match self.config.target_config.get(target) {
|
||||
Some(ref c) => c.llvm_config.is_none(),
|
||||
None => true
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the path to `llvm-config` for the specified target.
|
||||
///
|
||||
/// If a custom `llvm-config` was specified for target then that's returned
|
||||
/// instead.
|
||||
fn llvm_config(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
s.clone()
|
||||
} else {
|
||||
self.llvm_out(&self.config.build).join("bin")
|
||||
.join(exe("llvm-config", target))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the path to `FileCheck` binary for the specified target
|
||||
fn llvm_filecheck(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
s.parent().unwrap().join(exe("FileCheck", target))
|
||||
} else {
|
||||
let base = self.llvm_out(&self.config.build).join("build");
|
||||
let exe = exe("FileCheck", target);
|
||||
if self.config.build.contains("msvc") {
|
||||
base.join("Release/bin").join(exe)
|
||||
} else {
|
||||
base.join("bin").join(exe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Root output directory for compiler-rt compiled for `target`
|
||||
fn compiler_rt_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("compiler-rt")
|
||||
}
|
||||
|
||||
/// Root output directory for rust_test_helpers library compiled for
|
||||
/// `target`
|
||||
fn test_helpers_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("rust-test-helpers")
|
||||
}
|
||||
|
||||
/// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic
|
||||
/// library lookup path.
|
||||
fn add_rustc_lib_path(&self, compiler: &Compiler, cmd: &mut Command) {
|
||||
// Windows doesn't need dylib path munging because the dlls for the
|
||||
// compiler live next to the compiler and the system will find them
|
||||
// automatically.
|
||||
if cfg!(windows) {
|
||||
return
|
||||
}
|
||||
|
||||
add_lib_path(vec![self.rustc_libdir(compiler)], cmd);
|
||||
}
|
||||
|
||||
/// Adds the compiler's bootstrap key to the environment of `cmd`.
|
||||
fn add_bootstrap_key(&self, compiler: &Compiler, cmd: &mut Command) {
|
||||
// In stage0 we're using a previously released stable compiler, so we
|
||||
// use the stage0 bootstrap key. Otherwise we use our own build's
|
||||
// bootstrap key.
|
||||
let bootstrap_key = if compiler.is_snapshot(self) && !self.local_rebuild {
|
||||
&self.bootstrap_key_stage0
|
||||
} else {
|
||||
&self.bootstrap_key
|
||||
};
|
||||
cmd.env("RUSTC_BOOTSTRAP_KEY", bootstrap_key);
|
||||
}
|
||||
|
||||
/// Returns the compiler's libdir where it stores the dynamic libraries that
|
||||
/// it itself links against.
|
||||
///
|
||||
/// For example this returns `<sysroot>/lib` on Unix and `<sysroot>/bin` on
|
||||
/// Windows.
|
||||
fn rustc_libdir(&self, compiler: &Compiler) -> PathBuf {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.rustc_snapshot_libdir()
|
||||
} else {
|
||||
self.sysroot(compiler).join(libdir(compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the libdir of the snapshot compiler.
|
||||
fn rustc_snapshot_libdir(&self) -> PathBuf {
|
||||
self.rustc.parent().unwrap().parent().unwrap()
|
||||
.join(libdir(&self.config.build))
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
fn run(&self, cmd: &mut Command) {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_silent(cmd)
|
||||
}
|
||||
|
||||
/// Prints a message if this build is configured in verbose mode.
|
||||
fn verbose(&self, msg: &str) {
|
||||
if self.flags.verbose || self.config.verbose {
|
||||
println!("{}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of parallel jobs that have been configured for this
|
||||
/// build.
|
||||
fn jobs(&self) -> u32 {
|
||||
self.flags.jobs.unwrap_or(num_cpus::get() as u32)
|
||||
}
|
||||
|
||||
/// Returns the path to the C compiler for the target specified.
|
||||
fn cc(&self, target: &str) -> &Path {
|
||||
self.cc[target].0.path()
|
||||
}
|
||||
|
||||
/// Returns a list of flags to pass to the C compiler for the target
|
||||
/// specified.
|
||||
fn cflags(&self, target: &str) -> Vec<String> {
|
||||
// Filter out -O and /O (the optimization flags) that we picked up from
|
||||
// gcc-rs because the build scripts will determine that for themselves.
|
||||
let mut base = self.cc[target].0.args().iter()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// If we're compiling on OSX then we add a few unconditional flags
|
||||
// indicating that we want libc++ (more filled out than libstdc++) and
|
||||
// we want to compile for 10.7. This way we can ensure that
|
||||
// LLVM/jemalloc/etc are all properly compiled.
|
||||
if target.contains("apple-darwin") {
|
||||
base.push("-stdlib=libc++".into());
|
||||
base.push("-mmacosx-version-min=10.7".into());
|
||||
}
|
||||
// This is a hack, because newer binutils broke things on some vms/distros
|
||||
// (i.e., linking against unknown relocs disabled by the following flag)
|
||||
// See: https://github.com/rust-lang/rust/issues/34978
|
||||
match target {
|
||||
"i586-unknown-linux-gnu" |
|
||||
"i686-unknown-linux-musl" |
|
||||
"x86_64-unknown-linux-musl" => {
|
||||
base.push("-Wa,-mrelax-relocations=no".into());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
/// Returns the path to the `ar` archive utility for the target specified.
|
||||
fn ar(&self, target: &str) -> Option<&Path> {
|
||||
self.cc[target].1.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// Returns the path to the C++ compiler for the target specified, may panic
|
||||
/// if no C++ compiler was configured for the target.
|
||||
fn cxx(&self, target: &str) -> &Path {
|
||||
self.cxx[target].path()
|
||||
}
|
||||
|
||||
/// Returns flags to pass to the compiler to generate code for `target`.
|
||||
fn rustc_flags(&self, target: &str) -> Vec<String> {
|
||||
// New flags should be added here with great caution!
|
||||
//
|
||||
// It's quite unfortunate to **require** flags to generate code for a
|
||||
// target, so it should only be passed here if absolutely necessary!
|
||||
// Most default configuration should be done through target specs rather
|
||||
// than an entry here.
|
||||
|
||||
let mut base = Vec::new();
|
||||
if target != self.config.build && !target.contains("msvc") {
|
||||
base.push(format!("-Clinker={}", self.cc(target).display()));
|
||||
}
|
||||
return base
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the `dylib_path_var()` environment variable, returning a list of
|
||||
/// paths that are members of this lookup path.
|
||||
pub fn dylib_path() -> Vec<PathBuf> {
|
||||
env::split_paths(&env::var_os(dylib_path_var()).unwrap_or(OsString::new()))
|
||||
.collect()
|
||||
impl<'a> Compiler<'a> {
|
||||
/// Creates a new complier for the specified stage/host
|
||||
fn new(stage: u32, host: &'a str) -> Compiler<'a> {
|
||||
Compiler { stage: stage, host: host }
|
||||
}
|
||||
|
||||
/// Returns whether this is a snapshot compiler for `build`'s configuration
|
||||
fn is_snapshot(&self, build: &Build) -> bool {
|
||||
self.stage == 0 && self.host == build.config.build
|
||||
}
|
||||
}
|
||||
|
||||
549
src/bootstrap/native.rs
Normal file
549
src/bootstrap/native.rs
Normal file
@ -0,0 +1,549 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Compilation of native dependencies like LLVM.
|
||||
//!
|
||||
//! Native projects like LLVM unfortunately aren't suited just yet for
|
||||
//! compilation in build scripts that Cargo has. This is because thie
|
||||
//! compilation takes a *very* long time but also because we don't want to
|
||||
//! compile LLVM 3 times as part of a normal bootstrap (we want it cached).
|
||||
//!
|
||||
//! LLVM and compiler-rt are essentially just wired up to everything else to
|
||||
//! ensure that they're always in place if needed.
|
||||
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::fs::{self, File};
|
||||
|
||||
use build_helper::output;
|
||||
use cmake;
|
||||
use gcc;
|
||||
|
||||
use Build;
|
||||
use util::{staticlib, up_to_date};
|
||||
|
||||
/// Compile LLVM for `target`.
|
||||
pub fn llvm(build: &Build, target: &str) {
|
||||
// If we're using a custom LLVM bail out here, but we can only use a
|
||||
// custom LLVM for the build triple.
|
||||
if let Some(config) = build.config.target_config.get(target) {
|
||||
if let Some(ref s) = config.llvm_config {
|
||||
return check_llvm_version(build, s);
|
||||
}
|
||||
}
|
||||
|
||||
// If the cleaning trigger is newer than our built artifacts (or if the
|
||||
// artifacts are missing) then we keep going, otherwise we bail out.
|
||||
let dst = build.llvm_out(target);
|
||||
let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
|
||||
let done_stamp = dst.join("llvm-finished-building");
|
||||
build.clear_if_dirty(&dst, &stamp);
|
||||
if fs::metadata(&done_stamp).is_ok() {
|
||||
return
|
||||
}
|
||||
|
||||
println!("Building LLVM for {}", target);
|
||||
|
||||
let _ = fs::remove_dir_all(&dst.join("build"));
|
||||
t!(fs::create_dir_all(&dst.join("build")));
|
||||
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
|
||||
|
||||
// http://llvm.org/docs/CMake.html
|
||||
let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
|
||||
if build.config.ninja {
|
||||
cfg.generator("Ninja");
|
||||
}
|
||||
cfg.target(target)
|
||||
.host(&build.config.build)
|
||||
.out_dir(&dst)
|
||||
.profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
|
||||
.define("LLVM_ENABLE_ASSERTIONS", assertions)
|
||||
.define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC")
|
||||
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
||||
.define("LLVM_INCLUDE_TESTS", "OFF")
|
||||
.define("LLVM_INCLUDE_DOCS", "OFF")
|
||||
.define("LLVM_ENABLE_ZLIB", "OFF")
|
||||
.define("WITH_POLLY", "OFF")
|
||||
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
||||
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
||||
.define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string());
|
||||
|
||||
if target.starts_with("i686") {
|
||||
cfg.define("LLVM_BUILD_32_BITS", "ON");
|
||||
}
|
||||
|
||||
// http://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
if target != build.config.build {
|
||||
// FIXME: if the llvm root for the build triple is overridden then we
|
||||
// should use llvm-tblgen from there, also should verify that it
|
||||
// actually exists most of the time in normal installs of LLVM.
|
||||
let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
|
||||
cfg.define("CMAKE_CROSSCOMPILING", "True")
|
||||
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
|
||||
.define("LLVM_TABLEGEN", &host)
|
||||
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
|
||||
}
|
||||
|
||||
// MSVC handles compiler business itself
|
||||
if !target.contains("msvc") {
|
||||
if build.config.ccache {
|
||||
cfg.define("CMAKE_C_COMPILER", "ccache")
|
||||
.define("CMAKE_C_COMPILER_ARG1", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", "ccache")
|
||||
.define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
|
||||
} else {
|
||||
cfg.define("CMAKE_C_COMPILER", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", build.cxx(target));
|
||||
}
|
||||
cfg.build_arg("-j").build_arg(build.jobs().to_string());
|
||||
|
||||
cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
|
||||
cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
|
||||
}
|
||||
|
||||
// FIXME: we don't actually need to build all LLVM tools and all LLVM
|
||||
// libraries here, e.g. we just want a few components and a few
|
||||
// tools. Figure out how to filter them down and only build the right
|
||||
// tools and libs on all platforms.
|
||||
cfg.build();
|
||||
|
||||
t!(File::create(&done_stamp));
|
||||
}
|
||||
|
||||
fn check_llvm_version(build: &Build, llvm_config: &Path) {
|
||||
if !build.config.llvm_version_check {
|
||||
return
|
||||
}
|
||||
|
||||
let mut cmd = Command::new(llvm_config);
|
||||
let version = output(cmd.arg("--version"));
|
||||
if version.starts_with("3.5") || version.starts_with("3.6") ||
|
||||
version.starts_with("3.7") {
|
||||
return
|
||||
}
|
||||
panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
|
||||
}
|
||||
|
||||
/// Compiles the `compiler-rt` library, or at least the builtins part of it.
|
||||
///
|
||||
/// Note that while compiler-rt has a build system associated with it, we
|
||||
/// specifically don't use it here. The compiler-rt build system, written in
|
||||
/// CMake, is actually *very* difficult to work with in terms of getting it to
|
||||
/// compile on all the relevant platforms we want it to compile on. In the end
|
||||
/// it became so much pain to work with local patches, work around the oddities
|
||||
/// of the build system, etc, that we're just building everything by hand now.
|
||||
///
|
||||
/// In general compiler-rt is just a bunch of intrinsics that are in practice
|
||||
/// *very* stable. We just need to make sure that all the relevant functions and
|
||||
/// such are compiled somewhere and placed in an object file somewhere.
|
||||
/// Eventually, these should all be written in Rust!
|
||||
///
|
||||
/// So below you'll find a listing of every single file in the compiler-rt repo
|
||||
/// that we're compiling. We just reach in and compile with the `gcc` crate
|
||||
/// which should have all the relevant flags and such already configured.
|
||||
///
|
||||
/// The risk here is that if we update compiler-rt we may need to compile some
|
||||
/// new intrinsics, but to be honest we surely don't use all of the intrinsics
|
||||
/// listed below today so the likelihood of us actually needing a new intrinsic
|
||||
/// is quite low. The failure case is also just that someone reports a link
|
||||
/// error (if any) and then we just add it to the list. Overall, that cost is
|
||||
/// far far less than working with compiler-rt's build system over time.
|
||||
pub fn compiler_rt(build: &Build, target: &str) {
|
||||
let build_dir = build.compiler_rt_out(target);
|
||||
let output = build_dir.join(staticlib("compiler-rt", target));
|
||||
build.compiler_rt_built.borrow_mut().insert(target.to_string(),
|
||||
output.clone());
|
||||
t!(fs::create_dir_all(&build_dir));
|
||||
|
||||
let mut cfg = gcc::Config::new();
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&build_dir)
|
||||
.target(target)
|
||||
.host(&build.config.build)
|
||||
.opt_level(2)
|
||||
.debug(false);
|
||||
|
||||
if target.contains("msvc") {
|
||||
// Don't pull in extra libraries on MSVC
|
||||
cfg.flag("/Zl");
|
||||
|
||||
// Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
|
||||
cfg.define("__func__", Some("__FUNCTION__"));
|
||||
} else {
|
||||
// Turn off various features of gcc and such, mostly copying
|
||||
// compiler-rt's build system already
|
||||
cfg.flag("-fno-builtin");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag("-fomit-frame-pointer");
|
||||
cfg.flag("-ffreestanding");
|
||||
}
|
||||
|
||||
let mut sources = vec![
|
||||
"absvdi2.c",
|
||||
"absvsi2.c",
|
||||
"adddf3.c",
|
||||
"addsf3.c",
|
||||
"addvdi3.c",
|
||||
"addvsi3.c",
|
||||
"apple_versioning.c",
|
||||
"ashldi3.c",
|
||||
"ashrdi3.c",
|
||||
"clear_cache.c",
|
||||
"clzdi2.c",
|
||||
"clzsi2.c",
|
||||
"cmpdi2.c",
|
||||
"comparedf2.c",
|
||||
"comparesf2.c",
|
||||
"ctzdi2.c",
|
||||
"ctzsi2.c",
|
||||
"divdc3.c",
|
||||
"divdf3.c",
|
||||
"divdi3.c",
|
||||
"divmoddi4.c",
|
||||
"divmodsi4.c",
|
||||
"divsc3.c",
|
||||
"divsf3.c",
|
||||
"divsi3.c",
|
||||
"divxc3.c",
|
||||
"extendsfdf2.c",
|
||||
"extendhfsf2.c",
|
||||
"ffsdi2.c",
|
||||
"fixdfdi.c",
|
||||
"fixdfsi.c",
|
||||
"fixsfdi.c",
|
||||
"fixsfsi.c",
|
||||
"fixunsdfdi.c",
|
||||
"fixunsdfsi.c",
|
||||
"fixunssfdi.c",
|
||||
"fixunssfsi.c",
|
||||
"fixunsxfdi.c",
|
||||
"fixunsxfsi.c",
|
||||
"fixxfdi.c",
|
||||
"floatdidf.c",
|
||||
"floatdisf.c",
|
||||
"floatdixf.c",
|
||||
"floatsidf.c",
|
||||
"floatsisf.c",
|
||||
"floatundidf.c",
|
||||
"floatundisf.c",
|
||||
"floatundixf.c",
|
||||
"floatunsidf.c",
|
||||
"floatunsisf.c",
|
||||
"int_util.c",
|
||||
"lshrdi3.c",
|
||||
"moddi3.c",
|
||||
"modsi3.c",
|
||||
"muldc3.c",
|
||||
"muldf3.c",
|
||||
"muldi3.c",
|
||||
"mulodi4.c",
|
||||
"mulosi4.c",
|
||||
"muloti4.c",
|
||||
"mulsc3.c",
|
||||
"mulsf3.c",
|
||||
"mulvdi3.c",
|
||||
"mulvsi3.c",
|
||||
"mulxc3.c",
|
||||
"negdf2.c",
|
||||
"negdi2.c",
|
||||
"negsf2.c",
|
||||
"negvdi2.c",
|
||||
"negvsi2.c",
|
||||
"paritydi2.c",
|
||||
"paritysi2.c",
|
||||
"popcountdi2.c",
|
||||
"popcountsi2.c",
|
||||
"powidf2.c",
|
||||
"powisf2.c",
|
||||
"powixf2.c",
|
||||
"subdf3.c",
|
||||
"subsf3.c",
|
||||
"subvdi3.c",
|
||||
"subvsi3.c",
|
||||
"truncdfhf2.c",
|
||||
"truncdfsf2.c",
|
||||
"truncsfhf2.c",
|
||||
"ucmpdi2.c",
|
||||
"udivdi3.c",
|
||||
"udivmoddi4.c",
|
||||
"udivmodsi4.c",
|
||||
"udivsi3.c",
|
||||
"umoddi3.c",
|
||||
"umodsi3.c",
|
||||
];
|
||||
|
||||
if !target.contains("ios") {
|
||||
sources.extend(vec![
|
||||
"absvti2.c",
|
||||
"addtf3.c",
|
||||
"addvti3.c",
|
||||
"ashlti3.c",
|
||||
"ashrti3.c",
|
||||
"clzti2.c",
|
||||
"cmpti2.c",
|
||||
"ctzti2.c",
|
||||
"divtf3.c",
|
||||
"divti3.c",
|
||||
"ffsti2.c",
|
||||
"fixdfti.c",
|
||||
"fixsfti.c",
|
||||
"fixunsdfti.c",
|
||||
"fixunssfti.c",
|
||||
"fixunsxfti.c",
|
||||
"fixxfti.c",
|
||||
"floattidf.c",
|
||||
"floattisf.c",
|
||||
"floattixf.c",
|
||||
"floatuntidf.c",
|
||||
"floatuntisf.c",
|
||||
"floatuntixf.c",
|
||||
"lshrti3.c",
|
||||
"modti3.c",
|
||||
"multf3.c",
|
||||
"multi3.c",
|
||||
"mulvti3.c",
|
||||
"negti2.c",
|
||||
"negvti2.c",
|
||||
"parityti2.c",
|
||||
"popcountti2.c",
|
||||
"powitf2.c",
|
||||
"subtf3.c",
|
||||
"subvti3.c",
|
||||
"trampoline_setup.c",
|
||||
"ucmpti2.c",
|
||||
"udivmodti4.c",
|
||||
"udivti3.c",
|
||||
"umodti3.c",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("apple") {
|
||||
sources.extend(vec![
|
||||
"atomic_flag_clear.c",
|
||||
"atomic_flag_clear_explicit.c",
|
||||
"atomic_flag_test_and_set.c",
|
||||
"atomic_flag_test_and_set_explicit.c",
|
||||
"atomic_signal_fence.c",
|
||||
"atomic_thread_fence.c",
|
||||
]);
|
||||
}
|
||||
|
||||
if !target.contains("windows") {
|
||||
sources.push("emutls.c");
|
||||
}
|
||||
|
||||
if target.contains("msvc") {
|
||||
if target.contains("x86_64") {
|
||||
sources.extend(vec![
|
||||
"x86_64/floatdidf.c",
|
||||
"x86_64/floatdisf.c",
|
||||
"x86_64/floatdixf.c",
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if !target.contains("freebsd") {
|
||||
sources.push("gcc_personality_v0.c");
|
||||
}
|
||||
|
||||
if target.contains("x86_64") {
|
||||
sources.extend(vec![
|
||||
"x86_64/chkstk.S",
|
||||
"x86_64/chkstk2.S",
|
||||
"x86_64/floatdidf.c",
|
||||
"x86_64/floatdisf.c",
|
||||
"x86_64/floatdixf.c",
|
||||
"x86_64/floatundidf.S",
|
||||
"x86_64/floatundisf.S",
|
||||
"x86_64/floatundixf.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("i386") ||
|
||||
target.contains("i586") ||
|
||||
target.contains("i686") {
|
||||
sources.extend(vec![
|
||||
"i386/ashldi3.S",
|
||||
"i386/ashrdi3.S",
|
||||
"i386/chkstk.S",
|
||||
"i386/chkstk2.S",
|
||||
"i386/divdi3.S",
|
||||
"i386/floatdidf.S",
|
||||
"i386/floatdisf.S",
|
||||
"i386/floatdixf.S",
|
||||
"i386/floatundidf.S",
|
||||
"i386/floatundisf.S",
|
||||
"i386/floatundixf.S",
|
||||
"i386/lshrdi3.S",
|
||||
"i386/moddi3.S",
|
||||
"i386/muldi3.S",
|
||||
"i386/udivdi3.S",
|
||||
"i386/umoddi3.S",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if target.contains("arm") && !target.contains("ios") {
|
||||
sources.extend(vec![
|
||||
"arm/aeabi_cdcmp.S",
|
||||
"arm/aeabi_cdcmpeq_check_nan.c",
|
||||
"arm/aeabi_cfcmp.S",
|
||||
"arm/aeabi_cfcmpeq_check_nan.c",
|
||||
"arm/aeabi_dcmp.S",
|
||||
"arm/aeabi_div0.c",
|
||||
"arm/aeabi_drsub.c",
|
||||
"arm/aeabi_fcmp.S",
|
||||
"arm/aeabi_frsub.c",
|
||||
"arm/aeabi_idivmod.S",
|
||||
"arm/aeabi_ldivmod.S",
|
||||
"arm/aeabi_memcmp.S",
|
||||
"arm/aeabi_memcpy.S",
|
||||
"arm/aeabi_memmove.S",
|
||||
"arm/aeabi_memset.S",
|
||||
"arm/aeabi_uidivmod.S",
|
||||
"arm/aeabi_uldivmod.S",
|
||||
"arm/bswapdi2.S",
|
||||
"arm/bswapsi2.S",
|
||||
"arm/clzdi2.S",
|
||||
"arm/clzsi2.S",
|
||||
"arm/comparesf2.S",
|
||||
"arm/divmodsi4.S",
|
||||
"arm/divsi3.S",
|
||||
"arm/modsi3.S",
|
||||
"arm/switch16.S",
|
||||
"arm/switch32.S",
|
||||
"arm/switch8.S",
|
||||
"arm/switchu8.S",
|
||||
"arm/sync_synchronize.S",
|
||||
"arm/udivmodsi4.S",
|
||||
"arm/udivsi3.S",
|
||||
"arm/umodsi3.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("armv7") {
|
||||
sources.extend(vec![
|
||||
"arm/sync_fetch_and_add_4.S",
|
||||
"arm/sync_fetch_and_add_8.S",
|
||||
"arm/sync_fetch_and_and_4.S",
|
||||
"arm/sync_fetch_and_and_8.S",
|
||||
"arm/sync_fetch_and_max_4.S",
|
||||
"arm/sync_fetch_and_max_8.S",
|
||||
"arm/sync_fetch_and_min_4.S",
|
||||
"arm/sync_fetch_and_min_8.S",
|
||||
"arm/sync_fetch_and_nand_4.S",
|
||||
"arm/sync_fetch_and_nand_8.S",
|
||||
"arm/sync_fetch_and_or_4.S",
|
||||
"arm/sync_fetch_and_or_8.S",
|
||||
"arm/sync_fetch_and_sub_4.S",
|
||||
"arm/sync_fetch_and_sub_8.S",
|
||||
"arm/sync_fetch_and_umax_4.S",
|
||||
"arm/sync_fetch_and_umax_8.S",
|
||||
"arm/sync_fetch_and_umin_4.S",
|
||||
"arm/sync_fetch_and_umin_8.S",
|
||||
"arm/sync_fetch_and_xor_4.S",
|
||||
"arm/sync_fetch_and_xor_8.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("eabihf") {
|
||||
sources.extend(vec![
|
||||
"arm/adddf3vfp.S",
|
||||
"arm/addsf3vfp.S",
|
||||
"arm/divdf3vfp.S",
|
||||
"arm/divsf3vfp.S",
|
||||
"arm/eqdf2vfp.S",
|
||||
"arm/eqsf2vfp.S",
|
||||
"arm/extendsfdf2vfp.S",
|
||||
"arm/fixdfsivfp.S",
|
||||
"arm/fixsfsivfp.S",
|
||||
"arm/fixunsdfsivfp.S",
|
||||
"arm/fixunssfsivfp.S",
|
||||
"arm/floatsidfvfp.S",
|
||||
"arm/floatsisfvfp.S",
|
||||
"arm/floatunssidfvfp.S",
|
||||
"arm/floatunssisfvfp.S",
|
||||
"arm/gedf2vfp.S",
|
||||
"arm/gesf2vfp.S",
|
||||
"arm/gtdf2vfp.S",
|
||||
"arm/gtsf2vfp.S",
|
||||
"arm/ledf2vfp.S",
|
||||
"arm/lesf2vfp.S",
|
||||
"arm/ltdf2vfp.S",
|
||||
"arm/ltsf2vfp.S",
|
||||
"arm/muldf3vfp.S",
|
||||
"arm/mulsf3vfp.S",
|
||||
"arm/negdf2vfp.S",
|
||||
"arm/negsf2vfp.S",
|
||||
"arm/nedf2vfp.S",
|
||||
"arm/nesf2vfp.S",
|
||||
"arm/restore_vfp_d8_d15_regs.S",
|
||||
"arm/save_vfp_d8_d15_regs.S",
|
||||
"arm/subdf3vfp.S",
|
||||
"arm/subsf3vfp.S",
|
||||
"arm/truncdfsf2vfp.S",
|
||||
"arm/unorddf2vfp.S",
|
||||
"arm/unordsf2vfp.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("aarch64") {
|
||||
sources.extend(vec![
|
||||
"comparetf2.c",
|
||||
"extenddftf2.c",
|
||||
"extendsftf2.c",
|
||||
"fixtfdi.c",
|
||||
"fixtfsi.c",
|
||||
"fixtfti.c",
|
||||
"fixunstfdi.c",
|
||||
"fixunstfsi.c",
|
||||
"fixunstfti.c",
|
||||
"floatditf.c",
|
||||
"floatsitf.c",
|
||||
"floatunditf.c",
|
||||
"floatunsitf.c",
|
||||
"multc3.c",
|
||||
"trunctfdf2.c",
|
||||
"trunctfsf2.c",
|
||||
]);
|
||||
}
|
||||
|
||||
let mut out_of_date = false;
|
||||
for src in sources {
|
||||
let src = build.src.join("src/compiler-rt/lib/builtins").join(src);
|
||||
out_of_date = out_of_date || !up_to_date(&src, &output);
|
||||
cfg.file(src);
|
||||
}
|
||||
if !out_of_date {
|
||||
return
|
||||
}
|
||||
cfg.compile("libcompiler-rt.a");
|
||||
}
|
||||
|
||||
/// Compiles the `rust_test_helpers.c` library which we used in various
|
||||
/// `run-pass` test suites for ABI testing.
|
||||
pub fn test_helpers(build: &Build, target: &str) {
|
||||
let dst = build.test_helpers_out(target);
|
||||
let src = build.src.join("src/rt/rust_test_helpers.c");
|
||||
if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
|
||||
return
|
||||
}
|
||||
|
||||
println!("Building test helpers");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
let mut cfg = gcc::Config::new();
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&dst)
|
||||
.target(target)
|
||||
.host(&build.config.build)
|
||||
.opt_level(0)
|
||||
.debug(false)
|
||||
.file(build.src.join("src/rt/rust_test_helpers.c"))
|
||||
.compile("librust_test_helpers.a");
|
||||
}
|
||||
@ -26,11 +26,20 @@ use std::process::Command;
|
||||
|
||||
use build_helper::output;
|
||||
|
||||
use build::Build;
|
||||
use Build;
|
||||
|
||||
pub fn check(build: &mut Build) {
|
||||
let mut checked = HashSet::new();
|
||||
let path = env::var_os("PATH").unwrap_or(OsString::new());
|
||||
// On Windows, quotes are invalid characters for filename paths, and if
|
||||
// one is present as part of the PATH then that can lead to the system
|
||||
// being unable to identify the files properly. See
|
||||
// https://github.com/rust-lang/rust/issues/34959 for more details.
|
||||
if cfg!(windows) {
|
||||
if path.to_string_lossy().contains("\"") {
|
||||
panic!("PATH contains invalid character '\"'");
|
||||
}
|
||||
}
|
||||
let mut need_cmd = |cmd: &OsStr| {
|
||||
if !checked.insert(cmd.to_owned()) {
|
||||
return
|
||||
@ -89,7 +98,8 @@ pub fn check(build: &mut Build) {
|
||||
if target.contains("rumprun") ||
|
||||
target.contains("bitrig") ||
|
||||
target.contains("openbsd") ||
|
||||
target.contains("msvc") {
|
||||
target.contains("msvc") ||
|
||||
target.contains("emscripten") {
|
||||
build.config.use_jemalloc = false;
|
||||
}
|
||||
|
||||
@ -100,7 +110,7 @@ pub fn check(build: &mut Build) {
|
||||
}
|
||||
|
||||
// Make sure musl-root is valid if specified
|
||||
if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
|
||||
if target.contains("musl") && !target.contains("mips") {
|
||||
match build.config.musl_root {
|
||||
Some(ref root) => {
|
||||
if fs::metadata(root.join("lib/libc.a")).is_err() {
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use build::{Build, Compiler};
|
||||
use {Build, Compiler};
|
||||
|
||||
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
|
||||
pub struct Step<'a> {
|
||||
@ -124,6 +124,7 @@ macro_rules! targets {
|
||||
(check_codegen_units, CheckCodegenUnits { compiler: Compiler<'a> }),
|
||||
(check_incremental, CheckIncremental { compiler: Compiler<'a> }),
|
||||
(check_ui, CheckUi { compiler: Compiler<'a> }),
|
||||
(check_mir_opt, CheckMirOpt { compiler: Compiler<'a> }),
|
||||
(check_debuginfo, CheckDebuginfo { compiler: Compiler<'a> }),
|
||||
(check_rustdoc, CheckRustdoc { compiler: Compiler<'a> }),
|
||||
(check_docs, CheckDocs { compiler: Compiler<'a> }),
|
||||
@ -139,6 +140,7 @@ macro_rules! targets {
|
||||
(dist_mingw, DistMingw { _dummy: () }),
|
||||
(dist_rustc, DistRustc { stage: u32 }),
|
||||
(dist_std, DistStd { compiler: Compiler<'a> }),
|
||||
(dist_src, DistSrc { _dummy: () }),
|
||||
|
||||
// Misc targets
|
||||
(android_copy_libs, AndroidCopyLibs { compiler: Compiler<'a> }),
|
||||
@ -347,9 +349,7 @@ impl<'a> Step<'a> {
|
||||
vec![self.libstd(compiler),
|
||||
self.target(host).rustc(compiler.stage)]
|
||||
}
|
||||
Source::CompilerRt { _dummy } => {
|
||||
vec![self.llvm(()).target(&build.config.build)]
|
||||
}
|
||||
Source::CompilerRt { _dummy } => Vec::new(),
|
||||
Source::Llvm { _dummy } => Vec::new(),
|
||||
Source::TestHelpers { _dummy } => Vec::new(),
|
||||
Source::DebuggerScripts { stage: _ } => Vec::new(),
|
||||
@ -380,10 +380,18 @@ impl<'a> Step<'a> {
|
||||
vec![self.doc_test(stage)]
|
||||
}
|
||||
Source::Doc { stage } => {
|
||||
vec![self.doc_book(stage), self.doc_nomicon(stage),
|
||||
self.doc_style(stage), self.doc_standalone(stage),
|
||||
self.doc_std(stage),
|
||||
self.doc_error_index(stage)]
|
||||
let mut deps = vec![
|
||||
self.doc_book(stage), self.doc_nomicon(stage),
|
||||
self.doc_style(stage), self.doc_standalone(stage),
|
||||
self.doc_std(stage),
|
||||
self.doc_error_index(stage),
|
||||
];
|
||||
|
||||
if build.config.compiler_docs {
|
||||
deps.push(self.doc_rustc(stage));
|
||||
}
|
||||
|
||||
deps
|
||||
}
|
||||
Source::Check { stage, compiler } => {
|
||||
// Check is just a pseudo step which means check all targets,
|
||||
@ -444,6 +452,7 @@ impl<'a> Step<'a> {
|
||||
self.check_pretty_rfail_full(compiler),
|
||||
self.check_rpass_valgrind(compiler),
|
||||
self.check_rmake(compiler),
|
||||
self.check_mir_opt(compiler),
|
||||
|
||||
// crates
|
||||
self.check_crate_rustc(compiler),
|
||||
@ -471,6 +480,7 @@ impl<'a> Step<'a> {
|
||||
Source::CheckTidy { stage } => {
|
||||
vec![self.tool_tidy(stage)]
|
||||
}
|
||||
Source::CheckMirOpt { compiler} |
|
||||
Source::CheckPrettyRPass { compiler } |
|
||||
Source::CheckPrettyRFail { compiler } |
|
||||
Source::CheckRFail { compiler } |
|
||||
@ -559,12 +569,14 @@ impl<'a> Step<'a> {
|
||||
vec![self.libtest(compiler)]
|
||||
}
|
||||
}
|
||||
Source::DistSrc { _dummy: _ } => Vec::new(),
|
||||
|
||||
Source::Dist { stage } => {
|
||||
let mut base = Vec::new();
|
||||
|
||||
for host in build.config.host.iter() {
|
||||
let host = self.target(host);
|
||||
base.push(host.dist_src(()));
|
||||
base.push(host.dist_rustc(stage));
|
||||
if host.target.contains("windows-gnu") {
|
||||
base.push(host.dist_mingw(()));
|
||||
@ -14,11 +14,11 @@
|
||||
//! not a lot of interesting happenings here unfortunately.
|
||||
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use bootstrap::{dylib_path, dylib_path_var};
|
||||
use filetime::FileTime;
|
||||
|
||||
/// Returns the `name` as the filename of a static library for `target`.
|
||||
@ -67,6 +67,35 @@ pub fn cp_r(src: &Path, dst: &Path) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
|
||||
/// when this function is called. Unwanted files or directories can be skipped
|
||||
/// by returning `false` from the filter function.
|
||||
pub fn cp_filtered<F: Fn(&Path) -> bool>(src: &Path, dst: &Path, filter: &F) {
|
||||
// Inner function does the actual work
|
||||
fn recurse<F: Fn(&Path) -> bool>(src: &Path, dst: &Path, relative: &Path, filter: &F) {
|
||||
for f in t!(fs::read_dir(src)) {
|
||||
let f = t!(f);
|
||||
let path = f.path();
|
||||
let name = path.file_name().unwrap();
|
||||
let dst = dst.join(name);
|
||||
let relative = relative.join(name);
|
||||
// Only copy file or directory if the filter function returns true
|
||||
if filter(&relative) {
|
||||
if t!(f.file_type()).is_dir() {
|
||||
let _ = fs::remove_dir_all(&dst);
|
||||
t!(fs::create_dir(&dst));
|
||||
recurse(&path, &dst, &relative, filter);
|
||||
} else {
|
||||
let _ = fs::remove_file(&dst);
|
||||
copy(&path, &dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Immediately recurse with an empty relative path
|
||||
recurse(src, dst, Path::new(""), filter)
|
||||
}
|
||||
|
||||
/// Given an executable called `name`, return the filename for the
|
||||
/// executable for a particular target.
|
||||
pub fn exe(name: &str, target: &str) -> String {
|
||||
@ -103,7 +132,10 @@ pub fn add_lib_path(path: Vec<PathBuf>, cmd: &mut Command) {
|
||||
/// Uses last-modified time checks to verify this.
|
||||
pub fn up_to_date(src: &Path, dst: &Path) -> bool {
|
||||
let threshold = mtime(dst);
|
||||
let meta = t!(fs::metadata(src));
|
||||
let meta = match fs::metadata(src) {
|
||||
Ok(meta) => meta,
|
||||
Err(e) => panic!("source {:?} failed to get metadata: {}", src, e),
|
||||
};
|
||||
if meta.is_dir() {
|
||||
dir_up_to_date(src, &threshold)
|
||||
} else {
|
||||
@ -121,3 +153,22 @@ fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the environment variable which the dynamic library lookup path
|
||||
/// resides in for this platform.
|
||||
pub fn dylib_path_var() -> &'static str {
|
||||
if cfg!(target_os = "windows") {
|
||||
"PATH"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"DYLD_LIBRARY_PATH"
|
||||
} else {
|
||||
"LD_LIBRARY_PATH"
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the `dylib_path_var()` environment variable, returning a list of
|
||||
/// paths that are members of this lookup path.
|
||||
pub fn dylib_path() -> Vec<PathBuf> {
|
||||
env::split_paths(&env::var_os(dylib_path_var()).unwrap_or(OsString::new()))
|
||||
.collect()
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
"project_id" : "compiler-rt",
|
||||
"conduit_uri" : "http://reviews.llvm.org/"
|
||||
"conduit_uri" : "https://reviews.llvm.org/"
|
||||
}
|
||||
|
||||
@ -11,80 +11,34 @@
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
project(CompilerRT C CXX ASM)
|
||||
set(COMPILER_RT_STANDALONE_BUILD TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_STANDALONE_BUILD FALSE)
|
||||
endif()
|
||||
|
||||
# The CompilerRT build system requires CMake version 2.8.8 or higher in order
|
||||
# to use its support for building convenience "libraries" as a collection of
|
||||
# .o files. This is particularly useful in producing larger, more complex
|
||||
# runtime libraries.
|
||||
if (NOT MSVC)
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
else()
|
||||
# Version 2.8.12.1 is required to build with Visual Studio 2013.
|
||||
cmake_minimum_required(VERSION 2.8.12.1)
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.4.3)
|
||||
# FIXME:
|
||||
# The OLD behavior (pre 3.2) for this policy is to not set the value of the
|
||||
# CMAKE_EXE_LINKER_FLAGS variable in the generated test project. The NEW behavior
|
||||
# for this policy is to set the value of the CMAKE_EXE_LINKER_FLAGS variable
|
||||
# in the test project to the same as it is in the calling project. The new
|
||||
# behavior cause the compiler_rt test to fail during try_compile: see
|
||||
# projects/compiler-rt/cmake/Modules/CompilerRTUtils.cmake:121 such that
|
||||
# CAN_TARGET_${arch} is not set properly. This results in COMPILER_RT_SUPPORTED_ARCH
|
||||
# not being updated properly leading to poblems.
|
||||
cmake_policy(SET CMP0056 OLD)
|
||||
|
||||
# FIXME: It may be removed when we use 2.8.12.
|
||||
if(CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
# Invalidate a couple of keywords.
|
||||
set(cmake_2_8_12_INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE)
|
||||
else()
|
||||
# Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().
|
||||
set(cmake_2_8_12_INTERFACE INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE PRIVATE)
|
||||
if(POLICY CMP0022)
|
||||
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
|
||||
endif()
|
||||
endif()
|
||||
# Add path for custom compiler-rt modules.
|
||||
list(INSERT CMAKE_MODULE_PATH 0
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
|
||||
)
|
||||
|
||||
# Top level target used to build all compiler-rt libraries.
|
||||
add_custom_target(compiler-rt ALL)
|
||||
include(base-config-ix)
|
||||
|
||||
option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON)
|
||||
mark_as_advanced(COMPILER_RT_BUILD_BUILTINS)
|
||||
option(COMPILER_RT_BUILD_SANITIZERS "Build sanitizers" ON)
|
||||
mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS)
|
||||
|
||||
if (NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
# Compute the Clang version from the LLVM version.
|
||||
# FIXME: We should be able to reuse CLANG_VERSION variable calculated
|
||||
# in Clang cmake files, instead of copying the rules here.
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
|
||||
${PACKAGE_VERSION})
|
||||
# Setup the paths where compiler-rt runtimes and headers should be stored.
|
||||
set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
|
||||
set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
|
||||
set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
|
||||
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
|
||||
${LLVM_INCLUDE_TESTS})
|
||||
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
|
||||
${LLVM_ENABLE_WERROR})
|
||||
# Use just-built Clang to compile/link tests on all platforms, except for
|
||||
# Windows where we need to use clang-cl instead.
|
||||
if(NOT MSVC)
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
|
||||
else()
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe)
|
||||
endif()
|
||||
else()
|
||||
# Take output dir and install path from the user.
|
||||
set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH
|
||||
"Path where built compiler-rt libraries should be stored.")
|
||||
set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH
|
||||
"Path where built compiler-rt executables should be stored.")
|
||||
set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH
|
||||
"Path where built compiler-rt libraries should be installed.")
|
||||
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF)
|
||||
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
|
||||
# Use a host compiler to compile/link tests.
|
||||
set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing")
|
||||
|
||||
if (COMPILER_RT_STANDALONE_BUILD)
|
||||
if (NOT LLVM_CONFIG_PATH)
|
||||
find_program(LLVM_CONFIG_PATH "llvm-config"
|
||||
DOC "Path to llvm-config binary")
|
||||
@ -107,7 +61,7 @@ else()
|
||||
|
||||
# Make use of LLVM CMake modules.
|
||||
file(TO_CMAKE_PATH ${LLVM_BINARY_DIR} LLVM_BINARY_DIR_CMAKE_STYLE)
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/share/llvm/cmake")
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
|
||||
# Get some LLVM variables from LLVMConfig.
|
||||
include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
|
||||
@ -132,14 +86,6 @@ else()
|
||||
set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
|
||||
endif()
|
||||
|
||||
if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
|
||||
set(COMPILER_RT_TEST_COMPILER_ID Clang)
|
||||
elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
|
||||
set(COMPILER_RT_TEST_COMPILER_ID Clang)
|
||||
else()
|
||||
set(COMPILER_RT_TEST_COMPILER_ID GNU)
|
||||
endif()
|
||||
|
||||
set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${TARGET_TRIPLE} CACHE STRING
|
||||
"Default triple for which compiler-rt runtimes will be built.")
|
||||
if(DEFINED COMPILER_RT_TEST_TARGET_TRIPLE)
|
||||
@ -159,23 +105,9 @@ if(NOT COMPILER_RT_DEFAULT_TARGET_TRIPLE STREQUAL TARGET_TRIPLE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE FALSE)
|
||||
endif()
|
||||
|
||||
if ("${COMPILER_RT_DEFAULT_TARGET_ABI}" STREQUAL "androideabi")
|
||||
set(ANDROID 1)
|
||||
endif()
|
||||
|
||||
string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
|
||||
set(COMPILER_RT_LIBRARY_OUTPUT_DIR
|
||||
${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
|
||||
set(COMPILER_RT_LIBRARY_INSTALL_DIR
|
||||
${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
|
||||
|
||||
# Add path for custom compiler-rt modules.
|
||||
set(CMAKE_MODULE_PATH
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
|
||||
${CMAKE_MODULE_PATH}
|
||||
)
|
||||
include(CompilerRTUtils)
|
||||
|
||||
set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@ -200,13 +132,18 @@ pythonize_bool(COMPILER_RT_DEBUG)
|
||||
#================================
|
||||
# Setup Compiler Flags
|
||||
#================================
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(unwind.h HAVE_UNWIND_H)
|
||||
|
||||
include(config-ix)
|
||||
|
||||
if(MSVC)
|
||||
append_string_if(COMPILER_RT_HAS_W3_FLAG /W3 CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
# Override any existing /W flags with /W4. This is what LLVM does. Failing to
|
||||
# remove other /W[0-4] flags will result in a warning about overriding a
|
||||
# previous flag.
|
||||
if (COMPILER_RT_HAS_W4_FLAG)
|
||||
string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
append_string_if(COMPILER_RT_HAS_W4_FLAG /W4 CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
endif()
|
||||
else()
|
||||
append_string_if(COMPILER_RT_HAS_WALL_FLAG -Wall CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
endif()
|
||||
@ -226,7 +163,9 @@ endif()
|
||||
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_FNO_BUILTIN_FLAG -fno-builtin SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)
|
||||
if(NOT COMPILER_RT_DEBUG)
|
||||
append_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)
|
||||
endif()
|
||||
append_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS)
|
||||
@ -241,6 +180,8 @@ if(MSVC)
|
||||
# FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214.
|
||||
if(COMPILER_RT_HAS_MT_FLAG)
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/M[DT]d" "/MT" ${flag_var} "${${flag_var}}")
|
||||
@ -250,6 +191,12 @@ if(MSVC)
|
||||
endif()
|
||||
append_list_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_GS_FLAG /GS- SANITIZER_COMMON_CFLAGS)
|
||||
# VS 2015 (version 1900) added support for thread safe static initialization.
|
||||
# However, ASan interceptors run before CRT initialization, which causes the
|
||||
# new thread safe code to crash. Disable this feature for now.
|
||||
if (MSVC_VERSION GREATER 1899)
|
||||
list(APPEND SANITIZER_COMMON_CFLAGS /Zc:threadSafeInit-)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 SANITIZER_COMMON_CFLAGS)
|
||||
@ -292,10 +239,15 @@ append_list_if(COMPILER_RT_HAS_WD4391_FLAG /wd4391 SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_WD4722_FLAG /wd4722 SANITIZER_COMMON_CFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_WD4800_FLAG /wd4800 SANITIZER_COMMON_CFLAGS)
|
||||
|
||||
# Warnings to turn off for all libraries, not just sanitizers.
|
||||
append_string_if(COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG -Wno-unused-parameter CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
|
||||
if(APPLE AND SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.9")
|
||||
# Mac OS X prior to 10.9 had problems with exporting symbols from
|
||||
# libc++/libc++abi.
|
||||
set(SANITIZER_CAN_USE_CXXABI FALSE)
|
||||
elseif(MSVC)
|
||||
set(SANITIZER_CAN_USE_CXXABI FALSE)
|
||||
else()
|
||||
set(SANITIZER_CAN_USE_CXXABI TRUE)
|
||||
endif()
|
||||
|
||||
@ -24,10 +24,6 @@ N: Howard Hinnant
|
||||
E: howard.hinnant@gmail.com
|
||||
D: builtins library
|
||||
|
||||
N: Sergey Matveev
|
||||
E: earthdok@google.com
|
||||
D: LeakSanitizer
|
||||
|
||||
N: Alexander Potapenko
|
||||
E: glider@google.com
|
||||
D: MacOS/iOS port of sanitizers
|
||||
@ -38,7 +34,7 @@ D: CMake build, test suite
|
||||
|
||||
N: Kostya Serebryany
|
||||
E: kcc@google.com
|
||||
D: AddressSanitizer, sanitizer_common, porting sanitizers to another platforms
|
||||
D: AddressSanitizer, sanitizer_common, porting sanitizers to another platforms, LeakSanitizer
|
||||
|
||||
N: Richard Smith
|
||||
E: richard-llvm@metafoo.co.uk
|
||||
|
||||
@ -14,7 +14,7 @@ Full text of the relevant licenses is included below.
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
|
||||
Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -1,7 +1,28 @@
|
||||
include(AddLLVM)
|
||||
include(ExternalProject)
|
||||
include(CompilerRTUtils)
|
||||
|
||||
function(set_target_output_directories target output_dir)
|
||||
# For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators
|
||||
# append a per-configuration subdirectory to the specified directory.
|
||||
# To avoid the appended folder, the configuration specific variable must be
|
||||
# set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}':
|
||||
# RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ...
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
"ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
|
||||
"LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
|
||||
"RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir})
|
||||
endforeach()
|
||||
else()
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${output_dir}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${output_dir}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${output_dir})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Tries to add an "object library" target for a given list of OSs and/or
|
||||
# architectures with name "<name>.<arch>" for non-Darwin platforms if
|
||||
# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
|
||||
@ -32,13 +53,14 @@ function(add_compiler_rt_object_libraries name)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
foreach(libname ${libnames})
|
||||
add_library(${libname} OBJECT ${LIB_SOURCES})
|
||||
set_target_compile_flags(${libname}
|
||||
${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS})
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS ${LIB_DEFS})
|
||||
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
|
||||
if(APPLE)
|
||||
set_target_properties(${libname} PROPERTIES
|
||||
OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
|
||||
@ -107,7 +129,8 @@ function(add_compiler_rt_runtime name type)
|
||||
set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
|
||||
else()
|
||||
set(libname "${name}-dynamic-${arch}")
|
||||
set(extra_linkflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS} ${LIB_LINKFLAGS})
|
||||
set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
|
||||
set(extra_linkflags_${libname} ${TARGET_${arch}_LINKFLAGS} ${LIB_LINKFLAGS})
|
||||
if(WIN32)
|
||||
set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})
|
||||
else()
|
||||
@ -126,21 +149,42 @@ function(add_compiler_rt_runtime name type)
|
||||
endif()
|
||||
|
||||
if(LIB_PARENT_TARGET)
|
||||
set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
|
||||
# If the parent targets aren't created we should create them
|
||||
if(NOT TARGET ${LIB_PARENT_TARGET})
|
||||
add_custom_target(${LIB_PARENT_TARGET})
|
||||
endif()
|
||||
if(NOT TARGET install-${LIB_PARENT_TARGET})
|
||||
# The parent install target specifies the parent component to scrape up
|
||||
# anything not installed by the individual install targets, and to handle
|
||||
# installation when running the multi-configuration generators.
|
||||
add_custom_target(install-${LIB_PARENT_TARGET}
|
||||
DEPENDS ${LIB_PARENT_TARGET}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
set_target_properties(install-${LIB_PARENT_TARGET} PROPERTIES
|
||||
FOLDER "Compiler-RT Misc")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(libname ${libnames})
|
||||
# If you are using a multi-configuration generator we don't generate
|
||||
# per-library install rules, so we fall back to the parent target COMPONENT
|
||||
if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET)
|
||||
set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
|
||||
else()
|
||||
set(COMPONENT_OPTION COMPONENT ${libname})
|
||||
endif()
|
||||
|
||||
add_library(${libname} ${type} ${sources_${libname}})
|
||||
set_target_compile_flags(${libname} ${extra_cflags_${libname}})
|
||||
set_target_link_flags(${libname} ${extra_linkflags_${libname}})
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS ${LIB_DEFS})
|
||||
set_target_properties(${libname} PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
|
||||
set_target_output_directories(${libname} ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
|
||||
set_target_properties(${libname} PROPERTIES
|
||||
OUTPUT_NAME ${output_name_${libname}})
|
||||
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
|
||||
if(LIB_LINK_LIBS AND ${type} STREQUAL "SHARED")
|
||||
target_link_libraries(${libname} ${LIB_LINK_LIBS})
|
||||
endif()
|
||||
@ -151,6 +195,21 @@ function(add_compiler_rt_runtime name type)
|
||||
${COMPONENT_OPTION}
|
||||
RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
|
||||
${COMPONENT_OPTION})
|
||||
|
||||
# We only want to generate per-library install targets if you aren't using
|
||||
# an IDE because the extra targets get cluttered in IDEs.
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${libname}
|
||||
DEPENDS ${libname}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${libname}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
# If you have a parent target specified, we bind the new install target
|
||||
# to the parent install target.
|
||||
if(LIB_PARENT_TARGET)
|
||||
add_dependencies(install-${LIB_PARENT_TARGET} install-${libname})
|
||||
endif()
|
||||
endif()
|
||||
if(APPLE)
|
||||
set_target_properties(${libname} PROPERTIES
|
||||
OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
|
||||
@ -165,7 +224,10 @@ function(add_compiler_rt_runtime name type)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set(COMPILER_RT_TEST_CFLAGS)
|
||||
# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help
|
||||
# in compilation and linking of unittests.
|
||||
string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
|
||||
set(COMPILER_RT_UNITTEST_LINKFLAGS ${COMPILER_RT_UNITTEST_CFLAGS})
|
||||
|
||||
# Unittests support.
|
||||
set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
|
||||
@ -177,14 +239,14 @@ set(COMPILER_RT_GTEST_CFLAGS
|
||||
-I${COMPILER_RT_GTEST_PATH}
|
||||
)
|
||||
|
||||
append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_TEST_CFLAGS)
|
||||
append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS)
|
||||
|
||||
if(MSVC)
|
||||
# clang doesn't support exceptions on Windows yet.
|
||||
list(APPEND COMPILER_RT_TEST_CFLAGS -D_HAS_EXCEPTIONS=0)
|
||||
list(APPEND COMPILER_RT_UNITTEST_CFLAGS -D_HAS_EXCEPTIONS=0)
|
||||
|
||||
# We should teach clang to understand "#pragma intrinsic", see PR19898.
|
||||
list(APPEND COMPILER_RT_TEST_CFLAGS -Wno-undefined-inline)
|
||||
list(APPEND COMPILER_RT_UNITTEST_CFLAGS -Wno-undefined-inline)
|
||||
|
||||
# Clang doesn't support SEH on Windows yet.
|
||||
list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0)
|
||||
@ -209,14 +271,18 @@ endif()
|
||||
# LINK_FLAGS <link flags>)
|
||||
macro(add_compiler_rt_test test_suite test_name)
|
||||
cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})
|
||||
set(output_bin ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(TEST_SUBDIR)
|
||||
set(output_bin "${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUBDIR}/${test_name}")
|
||||
else()
|
||||
set(output_bin "${CMAKE_CURRENT_BINARY_DIR}/${test_name}")
|
||||
set(output_bin "${output_bin}/${TEST_SUBDIR}")
|
||||
endif()
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set(output_bin "${output_bin}/${CMAKE_CFG_INTDIR}")
|
||||
endif()
|
||||
set(output_bin "${output_bin}/${test_name}")
|
||||
if(MSVC)
|
||||
set(output_bin "${output_bin}.exe")
|
||||
endif()
|
||||
|
||||
# Use host compiler in a standalone build, and just-built Clang otherwise.
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND TEST_DEPS clang)
|
||||
@ -236,11 +302,13 @@ macro(add_compiler_rt_test test_suite test_name)
|
||||
-o "${output_bin}"
|
||||
${TEST_LINK_FLAGS}
|
||||
DEPENDS ${TEST_DEPS})
|
||||
set_target_properties(${test_name} PROPERTIES FOLDER "Compiler-RT Tests")
|
||||
|
||||
# Make the test suite depend on the binary.
|
||||
add_dependencies(${test_suite} ${test_name})
|
||||
endmacro()
|
||||
|
||||
macro(add_compiler_rt_resource_file target_name file_name)
|
||||
macro(add_compiler_rt_resource_file target_name file_name component)
|
||||
set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
|
||||
set(dst_file "${COMPILER_RT_OUTPUT_DIR}/${file_name}")
|
||||
add_custom_command(OUTPUT ${dst_file}
|
||||
@ -249,7 +317,12 @@ macro(add_compiler_rt_resource_file target_name file_name)
|
||||
COMMENT "Copying ${file_name}...")
|
||||
add_custom_target(${target_name} DEPENDS ${dst_file})
|
||||
# Install in Clang resource directory.
|
||||
install(FILES ${file_name} DESTINATION ${COMPILER_RT_INSTALL_PATH})
|
||||
install(FILES ${file_name}
|
||||
DESTINATION ${COMPILER_RT_INSTALL_PATH}
|
||||
COMPONENT ${component})
|
||||
add_dependencies(${component} ${target_name})
|
||||
|
||||
set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
|
||||
endmacro()
|
||||
|
||||
macro(add_compiler_rt_script name)
|
||||
@ -321,6 +394,10 @@ function(rt_externalize_debuginfo name)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
|
||||
set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_CXX_FLAGS MATCHES "-flto"
|
||||
OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
|
||||
@ -331,7 +408,7 @@ function(rt_externalize_debuginfo name)
|
||||
endif()
|
||||
add_custom_command(TARGET ${name} POST_BUILD
|
||||
COMMAND xcrun dsymutil $<TARGET_FILE:${name}>
|
||||
COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
|
||||
${strip_command})
|
||||
else()
|
||||
message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")
|
||||
endif()
|
||||
|
||||
62
src/compiler-rt/cmake/Modules/BuiltinTests.cmake
Normal file
62
src/compiler-rt/cmake/Modules/BuiltinTests.cmake
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
# This function takes an OS and a list of architectures and identifies the
|
||||
# subset of the architectures list that the installed toolchain can target.
|
||||
function(try_compile_only output)
|
||||
set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
|
||||
file(WRITE ${SIMPLE_C} "int foo(int x, int y) { return x + y; }\n")
|
||||
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions
|
||||
${CMAKE_C_COMPILE_OBJECT})
|
||||
string(REPLACE ";" " " extra_flags "${ARGN}")
|
||||
|
||||
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}")
|
||||
foreach(substitution ${substitutions})
|
||||
if(substitution STREQUAL "<CMAKE_C_COMPILER>")
|
||||
string(REPLACE "<CMAKE_C_COMPILER>"
|
||||
"${CMAKE_C_COMPILER}" test_compile_command ${test_compile_command})
|
||||
elseif(substitution STREQUAL "<OBJECT>")
|
||||
string(REPLACE "<OBJECT>"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/test.o"
|
||||
test_compile_command ${test_compile_command})
|
||||
elseif(substitution STREQUAL "<SOURCE>")
|
||||
string(REPLACE "<SOURCE>" "${SIMPLE_C}" test_compile_command
|
||||
${test_compile_command})
|
||||
elseif(substitution STREQUAL "<FLAGS>")
|
||||
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}"
|
||||
test_compile_command ${test_compile_command})
|
||||
else()
|
||||
string(REPLACE "${substitution}" "" test_compile_command
|
||||
${test_compile_command})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
string(REPLACE " " ";" test_compile_command "${test_compile_command}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${test_compile_command}
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE TEST_OUTPUT
|
||||
ERROR_VARIABLE TEST_ERROR
|
||||
)
|
||||
if(result EQUAL 0)
|
||||
set(${output} True PARENT_SCOPE)
|
||||
else()
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Testing compiler for supporting " ${ARGN} ":\n"
|
||||
"Command: ${test_compile_command}\n"
|
||||
"${TEST_OUTPUT}\n${TEST_ERROR}\n${result}\n")
|
||||
set(${output} False PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(builtin_check_c_compiler_flag flag output)
|
||||
if(NOT DEFINED ${output})
|
||||
message(STATUS "Performing Test ${output}")
|
||||
try_compile_only(result ${flag})
|
||||
set(${output} ${result} CACHE INTERNAL "Compiler supports ${flag}")
|
||||
if(${result})
|
||||
message(STATUS "Performing Test ${output} - Success")
|
||||
else()
|
||||
message(STATUS "Performing Test ${output} - Failed")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
@ -90,8 +90,8 @@ macro(clang_compiler_add_cxx_check)
|
||||
" fi"
|
||||
" echo 'This can also be fixed by checking out the libcxx project from llvm.org and installing the headers'"
|
||||
" echo 'into your build directory:'"
|
||||
" echo ' cd ${LLVM_SOURCE_DIR}/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx'"
|
||||
" echo ' cd ${LLVM_BINARY_DIR} && make -C ${LLVM_SOURCE_DIR}/projects/libcxx installheaders HEADER_DIR=${LLVM_BINARY_DIR}/include'"
|
||||
" echo ' cd ${LLVM_MAIN_SRC_DIR}/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx'"
|
||||
" echo ' cd ${LLVM_BINARY_DIR} && make -C ${LLVM_MAIN_SRC_DIR}/projects/libcxx installheaders HEADER_DIR=${LLVM_BINARY_DIR}/include'"
|
||||
" echo"
|
||||
" false"
|
||||
"fi"
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
include(CMakeParseArguments)
|
||||
|
||||
# On OS X SDKs can be installed anywhere on the base system and xcode-select can
|
||||
# set the default Xcode to use. This function finds the SDKs that are present in
|
||||
# the current Xcode.
|
||||
@ -16,6 +18,8 @@ function(find_darwin_sdk_dir var sdk_name)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_FILE /dev/null
|
||||
)
|
||||
else()
|
||||
set(${var}_INTERNAL ${var_internal} PARENT_SCOPE)
|
||||
endif()
|
||||
set(${var} ${var_internal} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@ -52,30 +56,36 @@ function(darwin_test_archs os valid_archs)
|
||||
endif()
|
||||
|
||||
set(archs ${ARGN})
|
||||
message(STATUS "Finding valid architectures for ${os}...")
|
||||
set(SIMPLE_CPP ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cpp)
|
||||
file(WRITE ${SIMPLE_CPP} "#include <iostream>\nint main() { std::cout << std::endl; return 0; }\n")
|
||||
|
||||
set(os_linker_flags)
|
||||
foreach(flag ${DARWIN_${os}_LINKFLAGS})
|
||||
set(os_linker_flags "${os_linker_flags} ${flag}")
|
||||
endforeach()
|
||||
if(NOT TEST_COMPILE_ONLY)
|
||||
message(STATUS "Finding valid architectures for ${os}...")
|
||||
set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
|
||||
file(WRITE ${SIMPLE_C} "#include <stdio.h>\nint main() { printf(__FILE__); return 0; }\n")
|
||||
|
||||
set(os_linker_flags)
|
||||
foreach(flag ${DARWIN_${os}_LINKFLAGS})
|
||||
set(os_linker_flags "${os_linker_flags} ${flag}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# The simple program will build for x86_64h on the simulator because it is
|
||||
# compatible with x86_64 libraries (mostly), but since x86_64h isn't actually
|
||||
# a valid or useful architecture for the iOS simulator we should drop it.
|
||||
if(${os} STREQUAL "iossim")
|
||||
if(${os} MATCHES "^(iossim|tvossim|watchossim)$")
|
||||
list(REMOVE_ITEM archs "x86_64h")
|
||||
endif()
|
||||
|
||||
set(working_archs)
|
||||
foreach(arch ${archs})
|
||||
|
||||
|
||||
set(arch_linker_flags "-arch ${arch} ${os_linker_flags}")
|
||||
try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_CPP}
|
||||
COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS}
|
||||
CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${arch_linker_flags}"
|
||||
OUTPUT_VARIABLE TEST_OUTPUT)
|
||||
if(TEST_COMPILE_ONLY)
|
||||
try_compile_only(CAN_TARGET_${os}_${arch} -v -arch ${arch} ${DARWIN_${os}_CFLAGS})
|
||||
else()
|
||||
try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_C}
|
||||
COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS}
|
||||
CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${arch_linker_flags}"
|
||||
OUTPUT_VARIABLE TEST_OUTPUT)
|
||||
endif()
|
||||
if(${CAN_TARGET_${os}_${arch}})
|
||||
list(APPEND working_archs ${arch})
|
||||
else()
|
||||
@ -169,43 +179,14 @@ macro(darwin_add_builtin_library name suffix)
|
||||
"PARENT_TARGET;OS;ARCH"
|
||||
"SOURCES;CFLAGS;DEFS"
|
||||
${ARGN})
|
||||
|
||||
# --- Workaround ---
|
||||
# The REF_OS variable was introduced to workaround linking problems when
|
||||
# compiler-rt is build for the iOS simulator.
|
||||
#
|
||||
# Without this workaround, trying to link compiler-rt into an executable for
|
||||
# the iOS simulator would produce an error like
|
||||
#
|
||||
# ld: warning: URGENT: building for iOS simulator, but linking in object
|
||||
# file built for OSX. Note: This will be an error in the future.
|
||||
#
|
||||
# The underlying reason is that the iOS simulator specific configuration is
|
||||
# stored in variables named like DARWIN_iossim_SYSROOT and not
|
||||
# DARWIN_macho_embedded_SYSROOT. Thus, with the current setup, compiler-rt
|
||||
# would be compiled against the OS X SDK and not the iPhone Simulator SDK.
|
||||
#
|
||||
# As a workaround we manually override macho_embedded with iossim when
|
||||
# accessing the DARWIN_*_SYSROOT and DARWIN_*_BUILTIN_MIN_VER_FLAG variables.
|
||||
#
|
||||
# This workaround probably break builds of compiler-rt for the watchOS and
|
||||
# tvOS simulators (if they weren't broken already).
|
||||
#
|
||||
# See also rust-lang/rust#34617.
|
||||
if(${LIB_OS} STREQUAL "macho_embedded")
|
||||
set(REF_OS iossim)
|
||||
else()
|
||||
set(REF_OS ${LIB_OS})
|
||||
endif()
|
||||
|
||||
set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
|
||||
add_library(${libname} STATIC ${LIB_SOURCES})
|
||||
if(DARWIN_${LIB_OS}_SYSROOT)
|
||||
set(sysroot_flag -isysroot ${DARWIN_${REF_OS}_SYSROOT})
|
||||
set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
|
||||
endif()
|
||||
set_target_compile_flags(${libname}
|
||||
${sysroot_flag}
|
||||
${DARWIN_${REF_OS}_BUILTIN_MIN_VER_FLAG}
|
||||
${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}
|
||||
${LIB_CFLAGS})
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS ${LIB_DEFS})
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
# Because compiler-rt spends a lot of time setting up custom compile flags,
|
||||
# define a handy helper function for it. The compile flags setting in CMake
|
||||
# has serious issues that make its syntax challenging at best.
|
||||
@ -45,9 +48,14 @@ macro(append_string_if condition value)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(append_no_rtti_flag list)
|
||||
append_list_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list})
|
||||
append_list_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list})
|
||||
macro(append_rtti_flag polarity list)
|
||||
if(polarity)
|
||||
append_list_if(COMPILER_RT_HAS_FRTTI_FLAG -frtti ${list})
|
||||
append_list_if(COMPILER_RT_HAS_GR_FLAG /GR ${list})
|
||||
else()
|
||||
append_list_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list})
|
||||
append_list_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(append_have_file_definition filename varname list)
|
||||
@ -67,3 +75,94 @@ macro(list_intersect output input1 input2)
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# Takes ${ARGN} and puts only supported architectures in @out_var list.
|
||||
function(filter_available_targets out_var)
|
||||
set(archs ${${out_var}})
|
||||
foreach(arch ${ARGN})
|
||||
list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
|
||||
if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})
|
||||
list(APPEND archs ${arch})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${out_var} ${archs} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(check_compile_definition def argstring out_var)
|
||||
if("${def}" STREQUAL "")
|
||||
set(${out_var} TRUE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}")
|
||||
check_symbol_exists(${def} "" ${out_var})
|
||||
cmake_pop_check_state()
|
||||
endfunction()
|
||||
|
||||
# test_target_arch(<arch> <def> <target flags...>)
|
||||
# Checks if architecture is supported: runs host compiler with provided
|
||||
# flags to verify that:
|
||||
# 1) <def> is defined (if non-empty)
|
||||
# 2) simple file can be successfully built.
|
||||
# If successful, saves target flags for this architecture.
|
||||
macro(test_target_arch arch def)
|
||||
set(TARGET_${arch}_CFLAGS ${ARGN})
|
||||
set(TARGET_${arch}_LINKFLAGS ${ARGN})
|
||||
set(argstring "")
|
||||
foreach(arg ${ARGN})
|
||||
set(argstring "${argstring} ${arg}")
|
||||
endforeach()
|
||||
check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF)
|
||||
if(NOT HAS_${arch}_DEF)
|
||||
set(CAN_TARGET_${arch} FALSE)
|
||||
elseif(TEST_COMPILE_ONLY)
|
||||
try_compile_only(CAN_TARGET_${arch} ${TARGET_${arch}_CFLAGS})
|
||||
else()
|
||||
set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}")
|
||||
try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE}
|
||||
COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}"
|
||||
OUTPUT_VARIABLE TARGET_${arch}_OUTPUT
|
||||
CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}")
|
||||
endif()
|
||||
if(${CAN_TARGET_${arch}})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "${arch}" AND
|
||||
COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE)
|
||||
# Bail out if we cannot target the architecture we plan to test.
|
||||
message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(detect_target_arch)
|
||||
check_symbol_exists(__arm__ "" __ARM)
|
||||
check_symbol_exists(__aarch64__ "" __AARCH64)
|
||||
check_symbol_exists(__x86_64__ "" __X86_64)
|
||||
check_symbol_exists(__i686__ "" __I686)
|
||||
check_symbol_exists(__i386__ "" __I386)
|
||||
check_symbol_exists(__mips__ "" __MIPS)
|
||||
check_symbol_exists(__mips64__ "" __MIPS64)
|
||||
check_symbol_exists(__s390x__ "" __S390X)
|
||||
check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32)
|
||||
check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64)
|
||||
if(__ARM)
|
||||
add_default_target_arch(arm)
|
||||
elseif(__AARCH64)
|
||||
add_default_target_arch(aarch64)
|
||||
elseif(__X86_64)
|
||||
add_default_target_arch(x86_64)
|
||||
elseif(__I686)
|
||||
add_default_target_arch(i686)
|
||||
elseif(__I386)
|
||||
add_default_target_arch(i386)
|
||||
elseif(__MIPS64) # must be checked before __MIPS
|
||||
add_default_target_arch(mips64)
|
||||
elseif(__MIPS)
|
||||
add_default_target_arch(mips)
|
||||
elseif(__S390X)
|
||||
add_default_target_arch(s390x)
|
||||
elseif(__WEBASSEMBLY32)
|
||||
add_default_target_arch(wasm32)
|
||||
elseif(__WEBASSEMBLY64)
|
||||
add_default_target_arch(wasm64)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@ -38,22 +38,8 @@ macro(add_sanitizer_rt_symbols name)
|
||||
DEPENDS ${stamp}
|
||||
SOURCES ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA})
|
||||
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
install(FILES $<TARGET_FILE:${target_name}>.syms
|
||||
DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
|
||||
else()
|
||||
# Per-config install location.
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
foreach(c ${CMAKE_CONFIGURATION_TYPES})
|
||||
get_target_property(libfile ${target_name} LOCATION_${c})
|
||||
install(FILES ${libfile}.syms CONFIGURATIONS ${c}
|
||||
install(FILES $<TARGET_FILE:${target_name}>.syms
|
||||
DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
|
||||
endforeach()
|
||||
else()
|
||||
get_target_property(libfile ${target_name} LOCATION_${CMAKE_BUILD_TYPE})
|
||||
install(FILES ${libfile}.syms DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
|
||||
endif()
|
||||
endif()
|
||||
if(ARG_PARENT_TARGET)
|
||||
add_dependencies(${ARG_PARENT_TARGET} ${target_name}-symbols)
|
||||
endif()
|
||||
@ -84,9 +70,9 @@ macro(add_sanitizer_rt_version_list name)
|
||||
endmacro()
|
||||
|
||||
# Add target to check code style for sanitizer runtimes.
|
||||
if(UNIX)
|
||||
if(CMAKE_HOST_UNIX)
|
||||
add_custom_target(SanitizerLintCheck
|
||||
COMMAND LLVM_CHECKOUT=${LLVM_MAIN_SRC_DIR} SILENT=1 TMPDIR=
|
||||
COMMAND env LLVM_CHECKOUT=${LLVM_MAIN_SRC_DIR} SILENT=1 TMPDIR=
|
||||
PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
|
||||
COMPILER_RT=${COMPILER_RT_SOURCE_DIR}
|
||||
${SANITIZER_LINT_SCRIPT}
|
||||
|
||||
169
src/compiler-rt/cmake/base-config-ix.cmake
Normal file
169
src/compiler-rt/cmake/base-config-ix.cmake
Normal file
@ -0,0 +1,169 @@
|
||||
# The CompilerRT build system requires CMake version 2.8.8 or higher in order
|
||||
# to use its support for building convenience "libraries" as a collection of
|
||||
# .o files. This is particularly useful in producing larger, more complex
|
||||
# runtime libraries.
|
||||
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(unwind.h HAVE_UNWIND_H)
|
||||
|
||||
# Top level target used to build all compiler-rt libraries.
|
||||
add_custom_target(compiler-rt ALL)
|
||||
set_target_properties(compiler-rt PROPERTIES FOLDER "Compiler-RT Misc")
|
||||
|
||||
# Setting these variables from an LLVM build is sufficient that compiler-rt can
|
||||
# construct the output paths, so it can behave as if it were in-tree here.
|
||||
if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
|
||||
set(LLVM_TREE_AVAILABLE On)
|
||||
endif()
|
||||
|
||||
if (LLVM_TREE_AVAILABLE)
|
||||
# Compute the Clang version from the LLVM version.
|
||||
# FIXME: We should be able to reuse CLANG_VERSION variable calculated
|
||||
# in Clang cmake files, instead of copying the rules here.
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
|
||||
${PACKAGE_VERSION})
|
||||
# Setup the paths where compiler-rt runtimes and headers should be stored.
|
||||
set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
|
||||
set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
|
||||
set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
|
||||
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
|
||||
${LLVM_INCLUDE_TESTS})
|
||||
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
|
||||
${LLVM_ENABLE_WERROR})
|
||||
# Use just-built Clang to compile/link tests on all platforms, except for
|
||||
# Windows where we need to use clang-cl instead.
|
||||
if(NOT MSVC)
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
|
||||
else()
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe)
|
||||
endif()
|
||||
else()
|
||||
# Take output dir and install path from the user.
|
||||
set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH
|
||||
"Path where built compiler-rt libraries should be stored.")
|
||||
set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH
|
||||
"Path where built compiler-rt executables should be stored.")
|
||||
set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH
|
||||
"Path where built compiler-rt libraries should be installed.")
|
||||
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF)
|
||||
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
|
||||
# Use a host compiler to compile/link tests.
|
||||
set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing")
|
||||
endif()
|
||||
|
||||
if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
|
||||
set(COMPILER_RT_TEST_COMPILER_ID Clang)
|
||||
elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
|
||||
set(COMPILER_RT_TEST_COMPILER_ID Clang)
|
||||
else()
|
||||
set(COMPILER_RT_TEST_COMPILER_ID GNU)
|
||||
endif()
|
||||
|
||||
string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
|
||||
set(COMPILER_RT_LIBRARY_OUTPUT_DIR
|
||||
${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
|
||||
set(COMPILER_RT_LIBRARY_INSTALL_DIR
|
||||
${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
|
||||
|
||||
if(APPLE)
|
||||
# On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
|
||||
# the command line tools. If this is the case, we need to find the OS X
|
||||
# sysroot to pass to clang.
|
||||
if(NOT EXISTS /usr/include)
|
||||
execute_process(COMMAND xcodebuild -version -sdk macosx Path
|
||||
OUTPUT_VARIABLE OSX_SYSROOT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
|
||||
endif()
|
||||
|
||||
option(COMPILER_RT_ENABLE_IOS "Enable building for iOS" Off)
|
||||
option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
|
||||
option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
|
||||
endif()
|
||||
|
||||
macro(test_targets)
|
||||
# Find and run MSVC (not clang-cl) and get its version. This will tell clang-cl
|
||||
# what version of MSVC to pretend to be so that the STL works.
|
||||
set(MSVC_VERSION_FLAG "")
|
||||
if (MSVC)
|
||||
# Find and run MSVC (not clang-cl) and get its version. This will tell
|
||||
# clang-cl what version of MSVC to pretend to be so that the STL works.
|
||||
execute_process(COMMAND "$ENV{VSINSTALLDIR}/VC/bin/cl.exe"
|
||||
OUTPUT_QUIET
|
||||
ERROR_VARIABLE MSVC_COMPAT_VERSION
|
||||
)
|
||||
string(REGEX REPLACE "^.*Compiler Version ([0-9.]+) for .*$" "\\1"
|
||||
MSVC_COMPAT_VERSION "${MSVC_COMPAT_VERSION}")
|
||||
if (MSVC_COMPAT_VERSION MATCHES "^[0-9].+$")
|
||||
set(MSVC_VERSION_FLAG "-fms-compatibility-version=${MSVC_COMPAT_VERSION}")
|
||||
# Add this flag into the host build if this is clang-cl.
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
append("${MSVC_VERSION_FLAG}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
elseif (COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
|
||||
# Add this flag to test compiles to suppress clang's auto-detection
|
||||
# logic.
|
||||
append("${MSVC_VERSION_FLAG}" COMPILER_RT_TEST_COMPILER_CFLAGS)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Generate the COMPILER_RT_SUPPORTED_ARCH list.
|
||||
if(ANDROID)
|
||||
# Examine compiler output to determine target architecture.
|
||||
detect_target_arch()
|
||||
set(COMPILER_RT_OS_SUFFIX "-android")
|
||||
elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
|
||||
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64")
|
||||
if(NOT MSVC)
|
||||
test_target_arch(x86_64 "" "-m64")
|
||||
# FIXME: We build runtimes for both i686 and i386, as "clang -m32" may
|
||||
# target different variant than "$CMAKE_C_COMPILER -m32". This part should
|
||||
# be gone after we resolve PR14109.
|
||||
test_target_arch(i686 __i686__ "-m32")
|
||||
test_target_arch(i386 __i386__ "-m32")
|
||||
else()
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
test_target_arch(i386 "" "")
|
||||
else()
|
||||
test_target_arch(x86_64 "" "")
|
||||
endif()
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
|
||||
TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
|
||||
if(HOST_IS_BIG_ENDIAN)
|
||||
test_target_arch(powerpc64 "" "-m64")
|
||||
else()
|
||||
test_target_arch(powerpc64le "" "-m64")
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x")
|
||||
test_target_arch(s390x "" "")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el")
|
||||
# Gcc doesn't accept -m32/-m64 so we do the next best thing and use
|
||||
# -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match
|
||||
# clang's default CPU's. In the 64-bit case, we must also specify the ABI
|
||||
# since the default ABI differs between gcc and clang.
|
||||
# FIXME: Ideally, we would build the N32 library too.
|
||||
test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu")
|
||||
test_target_arch(mips64el "" "-mips64r2" "--target=mips64el-linux-gnu" "-mabi=64")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips")
|
||||
test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
|
||||
test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=64")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
|
||||
test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft")
|
||||
test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
|
||||
test_target_arch(aarch32 "" "-march=armv8-a")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
|
||||
test_target_arch(aarch64 "" "-march=armv8-a")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32")
|
||||
test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64")
|
||||
test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown")
|
||||
endif()
|
||||
set(COMPILER_RT_OS_SUFFIX "")
|
||||
endif()
|
||||
endmacro()
|
||||
169
src/compiler-rt/cmake/builtin-config-ix.cmake
Normal file
169
src/compiler-rt/cmake/builtin-config-ix.cmake
Normal file
@ -0,0 +1,169 @@
|
||||
include(BuiltinTests)
|
||||
|
||||
# Make all the tests only check the compiler
|
||||
set(TEST_COMPILE_ONLY On)
|
||||
|
||||
builtin_check_c_compiler_flag(-fPIC COMPILER_RT_HAS_FPIC_FLAG)
|
||||
builtin_check_c_compiler_flag(-fPIE COMPILER_RT_HAS_FPIE_FLAG)
|
||||
builtin_check_c_compiler_flag(-fno-builtin COMPILER_RT_HAS_FNO_BUILTIN_FLAG)
|
||||
builtin_check_c_compiler_flag(-std=c99 COMPILER_RT_HAS_STD_C99_FLAG)
|
||||
builtin_check_c_compiler_flag(-fvisibility=hidden COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG)
|
||||
builtin_check_c_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG)
|
||||
builtin_check_c_compiler_flag(-ffreestanding COMPILER_RT_HAS_FREESTANDING_FLAG)
|
||||
builtin_check_c_compiler_flag(-mfloat-abi=soft COMPILER_RT_HAS_FLOAT_ABI_SOFT_FLAG)
|
||||
builtin_check_c_compiler_flag(-mfloat-abi=hard COMPILER_RT_HAS_FLOAT_ABI_HARD_FLAG)
|
||||
builtin_check_c_compiler_flag(-static COMPILER_RT_HAS_STATIC_FLAG)
|
||||
|
||||
set(ARM64 aarch64)
|
||||
set(ARM32 arm armhf)
|
||||
set(X86 i386 i686)
|
||||
set(X86_64 x86_64)
|
||||
set(MIPS32 mips mipsel)
|
||||
set(MIPS64 mips64 mips64el)
|
||||
set(PPC64 powerpc64 powerpc64le)
|
||||
set(WASM32 wasm32)
|
||||
set(WASM64 wasm64)
|
||||
|
||||
if(APPLE)
|
||||
set(ARM64 arm64)
|
||||
set(ARM32 armv7 armv7k armv7s)
|
||||
set(X86_64 x86_64 x86_64h)
|
||||
endif()
|
||||
|
||||
set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
|
||||
${MIPS32} ${MIPS64} ${WASM32} ${WASM64})
|
||||
|
||||
include(CompilerRTUtils)
|
||||
include(CompilerRTDarwinUtils)
|
||||
|
||||
if(APPLE)
|
||||
|
||||
find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
|
||||
find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
|
||||
find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
|
||||
find_darwin_sdk_dir(DARWIN_watchossim_SYSROOT watchsimulator)
|
||||
find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos)
|
||||
find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator)
|
||||
find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos)
|
||||
|
||||
set(DARWIN_EMBEDDED_PLATFORMS)
|
||||
set(DARWIN_osx_BUILTIN_MIN_VER 10.5)
|
||||
set(DARWIN_osx_BUILTIN_MIN_VER_FLAG
|
||||
-mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER})
|
||||
|
||||
if(COMPILER_RT_ENABLE_IOS)
|
||||
list(APPEND DARWIN_EMBEDDED_PLATFORMS ios)
|
||||
set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
if(COMPILER_RT_ENABLE_WATCHOS)
|
||||
list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
|
||||
set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
|
||||
set(DARWIN_watchos_BUILTIN_MIN_VER 2.0)
|
||||
set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
if(COMPILER_RT_ENABLE_TVOS)
|
||||
list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
|
||||
set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
|
||||
set(DARWIN_tvos_BUILTIN_MIN_VER 9.0)
|
||||
set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
|
||||
set(BUILTIN_SUPPORTED_OS osx)
|
||||
|
||||
# We're setting the flag manually for each target OS
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||
|
||||
if(NOT DARWIN_osx_ARCHS)
|
||||
set(DARWIN_osx_ARCHS i386 x86_64 x86_64h)
|
||||
endif()
|
||||
|
||||
set(DARWIN_sim_ARCHS i386 x86_64)
|
||||
set(DARWIN_device_ARCHS armv7 armv7s armv7k arm64)
|
||||
|
||||
message(STATUS "OSX supported arches: ${DARWIN_osx_ARCHS}")
|
||||
foreach(arch ${DARWIN_osx_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
|
||||
# Need to build a 10.4 compatible libclang_rt
|
||||
set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT})
|
||||
set(DARWIN_10.4_BUILTIN_MIN_VER 10.4)
|
||||
set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG
|
||||
-mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER})
|
||||
set(DARWIN_10.4_SKIP_CC_KEXT On)
|
||||
darwin_test_archs(10.4 DARWIN_10.4_ARCHS i386 x86_64)
|
||||
message(STATUS "OSX 10.4 supported builtin arches: ${DARWIN_10.4_ARCHS}")
|
||||
if(DARWIN_10.4_ARCHS)
|
||||
# don't include the Haswell slice in the 10.4 compatibility library
|
||||
list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS 10.4)
|
||||
endif()
|
||||
|
||||
foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
|
||||
if(DARWIN_${platform}sim_SYSROOT)
|
||||
set(DARWIN_${platform}sim_BUILTIN_MIN_VER
|
||||
${DARWIN_${platform}_BUILTIN_MIN_VER})
|
||||
set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG})
|
||||
|
||||
set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
|
||||
|
||||
set(test_arches ${DARWIN_sim_ARCHS})
|
||||
if(DARWIN_${platform}sim_ARCHS)
|
||||
set(test_arches DARWIN_${platform}sim_ARCHS)
|
||||
endif()
|
||||
|
||||
darwin_test_archs(${platform}sim
|
||||
DARWIN_${platform}sim_ARCHS
|
||||
${test_arches})
|
||||
message(STATUS "${platform} Simulator supported builtin arches: ${DARWIN_${platform}sim_ARCHS}")
|
||||
if(DARWIN_${platform}sim_ARCHS)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim)
|
||||
endif()
|
||||
foreach(arch ${DARWIN_${platform}sim_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(DARWIN_${platform}_SYSROOT)
|
||||
set(test_arches ${DARWIN_device_ARCHS})
|
||||
if(DARWIN_${platform}_ARCHS)
|
||||
set(test_arches DARWIN_${platform}_ARCHS)
|
||||
endif()
|
||||
|
||||
darwin_test_archs(${platform}
|
||||
DARWIN_${platform}_ARCHS
|
||||
${test_arches})
|
||||
message(STATUS "${platform} supported builtin arches: ${DARWIN_${platform}_ARCHS}")
|
||||
if(DARWIN_${platform}_ARCHS)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ${platform})
|
||||
endif()
|
||||
foreach(arch ${DARWIN_${platform}_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list_intersect(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH COMPILER_RT_SUPPORTED_ARCH)
|
||||
|
||||
else()
|
||||
# If we're not building the builtins standalone, just rely on the tests in
|
||||
# config-ix.cmake to tell us what to build. Otherwise we need to do some leg
|
||||
# work here...
|
||||
if(COMPILER_RT_BUILTINS_STANDALONE_BUILD)
|
||||
test_targets()
|
||||
endif()
|
||||
# Architectures supported by compiler-rt libraries.
|
||||
filter_available_targets(BUILTIN_SUPPORTED_ARCH
|
||||
${ALL_BUILTIN_SUPPORTED_ARCH})
|
||||
endif()
|
||||
|
||||
message(STATUS "Builtin supported architectures: ${BUILTIN_SUPPORTED_ARCH}")
|
||||
15
src/compiler-rt/cmake/caches/Apple.cmake
Normal file
15
src/compiler-rt/cmake/caches/Apple.cmake
Normal file
@ -0,0 +1,15 @@
|
||||
# This file sets up a CMakeCache for Apple-style builds of compiler-rt.
|
||||
# This configuration matches Apple uses when shipping Xcode releases.
|
||||
|
||||
set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_HAS_SAFESTACK OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
|
||||
set(CMAKE_MACOSX_RPATH ON CACHE BOOL "")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "")
|
||||
set(CMAKE_ASM_FLAGS_RELEASE "-O3" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "")
|
||||
@ -21,6 +21,7 @@ check_cxx_compiler_flag(-funwind-tables COMPILER_RT_HAS_FUNWIND_TABLES_FLAG
|
||||
check_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG)
|
||||
check_cxx_compiler_flag(-fno-sanitize=safe-stack COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG)
|
||||
check_cxx_compiler_flag(-fvisibility=hidden COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)
|
||||
check_cxx_compiler_flag(-frtti COMPILER_RT_HAS_FRTTI_FLAG)
|
||||
check_cxx_compiler_flag(-fno-rtti COMPILER_RT_HAS_FNO_RTTI_FLAG)
|
||||
check_cxx_compiler_flag(-ffreestanding COMPILER_RT_HAS_FFREESTANDING_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -fno-function-sections" COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG)
|
||||
@ -28,7 +29,6 @@ check_cxx_compiler_flag(-std=c++11 COMPILER_RT_HAS_STD_CXX11_FLAG)
|
||||
check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC)
|
||||
check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
|
||||
check_cxx_compiler_flag(-std=c99 COMPILER_RT_HAS_STD_C99_FLAG)
|
||||
check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)
|
||||
|
||||
if(NOT WIN32 AND NOT CYGWIN)
|
||||
@ -55,11 +55,13 @@ check_cxx_compiler_flag("-Werror -Wc99-extensions" COMPILER_RT_HAS_WC99_EXTE
|
||||
check_cxx_compiler_flag("-Werror -Wgnu" COMPILER_RT_HAS_WGNU_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -Wnon-virtual-dtor" COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -Wvariadic-macros" COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -Wunused-parameter" COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG)
|
||||
|
||||
check_cxx_compiler_flag(/W3 COMPILER_RT_HAS_W3_FLAG)
|
||||
check_cxx_compiler_flag(/W4 COMPILER_RT_HAS_W4_FLAG)
|
||||
check_cxx_compiler_flag(/WX COMPILER_RT_HAS_WX_FLAG)
|
||||
check_cxx_compiler_flag(/wd4146 COMPILER_RT_HAS_WD4146_FLAG)
|
||||
check_cxx_compiler_flag(/wd4291 COMPILER_RT_HAS_WD4291_FLAG)
|
||||
check_cxx_compiler_flag(/wd4221 COMPILER_RT_HAS_WD4221_FLAG)
|
||||
check_cxx_compiler_flag(/wd4391 COMPILER_RT_HAS_WD4391_FLAG)
|
||||
check_cxx_compiler_flag(/wd4722 COMPILER_RT_HAS_WD4722_FLAG)
|
||||
check_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG)
|
||||
@ -93,48 +95,6 @@ set(COMPILER_RT_SUPPORTED_ARCH)
|
||||
set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc)
|
||||
file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <limits>\nint main() {}\n")
|
||||
|
||||
function(check_compile_definition def argstring out_var)
|
||||
if("${def}" STREQUAL "")
|
||||
set(${out_var} TRUE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}")
|
||||
check_symbol_exists(${def} "" ${out_var})
|
||||
cmake_pop_check_state()
|
||||
endfunction()
|
||||
|
||||
# test_target_arch(<arch> <def> <target flags...>)
|
||||
# Checks if architecture is supported: runs host compiler with provided
|
||||
# flags to verify that:
|
||||
# 1) <def> is defined (if non-empty)
|
||||
# 2) simple file can be successfully built.
|
||||
# If successful, saves target flags for this architecture.
|
||||
macro(test_target_arch arch def)
|
||||
set(TARGET_${arch}_CFLAGS ${ARGN})
|
||||
set(argstring "")
|
||||
foreach(arg ${ARGN})
|
||||
set(argstring "${argstring} ${arg}")
|
||||
endforeach()
|
||||
check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF)
|
||||
if(NOT HAS_${arch}_DEF)
|
||||
set(CAN_TARGET_${arch} FALSE)
|
||||
else()
|
||||
set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}")
|
||||
try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE}
|
||||
COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}"
|
||||
OUTPUT_VARIABLE TARGET_${arch}_OUTPUT
|
||||
CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}")
|
||||
endif()
|
||||
if(${CAN_TARGET_${arch}})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "${arch}" AND
|
||||
COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE)
|
||||
# Bail out if we cannot target the architecture we plan to test.
|
||||
message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Add $arch as supported with no additional flags.
|
||||
macro(add_default_target_arch arch)
|
||||
set(TARGET_${arch}_CFLAGS "")
|
||||
@ -142,38 +102,6 @@ macro(add_default_target_arch arch)
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
endmacro()
|
||||
|
||||
macro(detect_target_arch)
|
||||
check_symbol_exists(__arm__ "" __ARM)
|
||||
check_symbol_exists(__aarch64__ "" __AARCH64)
|
||||
check_symbol_exists(__x86_64__ "" __X86_64)
|
||||
check_symbol_exists(__i686__ "" __I686)
|
||||
check_symbol_exists(__i386__ "" __I386)
|
||||
check_symbol_exists(__mips__ "" __MIPS)
|
||||
check_symbol_exists(__mips64__ "" __MIPS64)
|
||||
check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32)
|
||||
check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64)
|
||||
if(__ARM)
|
||||
# Android shouldn't use Thumb2 instructions but can use VFP instructions.
|
||||
add_default_target_arch(armhf)
|
||||
elseif(__AARCH64)
|
||||
add_default_target_arch(aarch64)
|
||||
elseif(__X86_64)
|
||||
add_default_target_arch(x86_64)
|
||||
elseif(__I686)
|
||||
add_default_target_arch(i686)
|
||||
elseif(__I386)
|
||||
add_default_target_arch(i386)
|
||||
elseif(__MIPS64) # must be checked before __MIPS
|
||||
add_default_target_arch(mips64)
|
||||
elseif(__MIPS)
|
||||
add_default_target_arch(mips)
|
||||
elseif(__WEBASSEMBLY32)
|
||||
add_default_target_arch(wasm32)
|
||||
elseif(__WEBASSEMBLY64)
|
||||
add_default_target_arch(wasm64)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Detect whether the current target platform is 32-bit or 64-bit, and setup
|
||||
# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
|
||||
@ -181,77 +109,7 @@ if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
|
||||
message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
|
||||
endif()
|
||||
|
||||
# Generate the COMPILER_RT_SUPPORTED_ARCH list.
|
||||
if(ANDROID)
|
||||
# Examine compiler output to determine target architecture.
|
||||
detect_target_arch()
|
||||
set(COMPILER_RT_OS_SUFFIX "-android")
|
||||
elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
|
||||
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64")
|
||||
if(NOT MSVC)
|
||||
test_target_arch(x86_64 "" "-m64")
|
||||
# FIXME: We build runtimes for both i686 and i386, as "clang -m32" may
|
||||
# target different variant than "$CMAKE_C_COMPILER -m32". This part should
|
||||
# be gone after we resolve PR14109.
|
||||
test_target_arch(i686 __i686__ "-m32")
|
||||
test_target_arch(i386 __i386__ "-m32")
|
||||
else()
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
test_target_arch(i386 "" "")
|
||||
else()
|
||||
test_target_arch(x86_64 "" "")
|
||||
endif()
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
|
||||
TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
|
||||
if(HOST_IS_BIG_ENDIAN)
|
||||
test_target_arch(powerpc "" "-m32")
|
||||
test_target_arch(powerpc64 "" "-m64")
|
||||
else()
|
||||
test_target_arch(powerpc64le "" "-m64")
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el")
|
||||
# Gcc doesn't accept -m32/-m64 so we do the next best thing and use
|
||||
# -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match
|
||||
# clang's default CPU's. In the 64-bit case, we must also specify the ABI
|
||||
# since the default ABI differs between gcc and clang.
|
||||
# FIXME: Ideally, we would build the N32 library too.
|
||||
test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu")
|
||||
test_target_arch(mips64el "" "-mips64r2" "--target=mips64el-linux-gnu" "-mabi=n64")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips")
|
||||
test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
|
||||
test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
|
||||
if("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "armv7")
|
||||
test_target_arch(armv7 "" "${CMAKE_C_FLAGS}")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "eabihf")
|
||||
test_target_arch(armhf "" "${CMAKE_C_FLAGS}")
|
||||
else()
|
||||
test_target_arch(arm "" "${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
|
||||
test_target_arch(aarch32 "" "-march=armv8-a")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
|
||||
test_target_arch(aarch64 "" "-march=armv8-a")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32")
|
||||
test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64")
|
||||
test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown")
|
||||
endif()
|
||||
set(COMPILER_RT_OS_SUFFIX "")
|
||||
endif()
|
||||
|
||||
# Takes ${ARGN} and puts only supported architectures in @out_var list.
|
||||
function(filter_available_targets out_var)
|
||||
set(archs ${${out_var}})
|
||||
foreach(arch ${ARGN})
|
||||
list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
|
||||
if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})
|
||||
list(APPEND archs ${arch})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${out_var} ${archs} PARENT_SCOPE)
|
||||
endfunction()
|
||||
test_targets()
|
||||
|
||||
# Returns a list of architecture specific target cflags in @out_var list.
|
||||
function(get_target_flags_for_arch arch out_var)
|
||||
@ -271,57 +129,42 @@ function(get_target_flags_for_arch arch out_var)
|
||||
endfunction()
|
||||
|
||||
set(ARM64 aarch64)
|
||||
set(ARM32 arm armhf armv7)
|
||||
set(ARM32 arm armhf)
|
||||
set(X86 i386 i686)
|
||||
set(X86_64 x86_64)
|
||||
set(MIPS32 mips mipsel)
|
||||
set(MIPS64 mips64 mips64el)
|
||||
set(PPC powerpc)
|
||||
set(PPC64 powerpc64 powerpc64le)
|
||||
set(S390X s390x)
|
||||
set(WASM32 wasm32)
|
||||
set(WASM64 wasm64)
|
||||
|
||||
if(APPLE)
|
||||
set(ARM64 arm64)
|
||||
set(ARM32 armv7 armv7s)
|
||||
set(ARM32 armv7 armv7s armv7k)
|
||||
set(X86_64 x86_64 x86_64h)
|
||||
endif()
|
||||
|
||||
set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
|
||||
${MIPS32} ${MIPS64} ${WASM32} ${WASM64} ${PPC} ${PPC64})
|
||||
set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64}
|
||||
${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
|
||||
${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X})
|
||||
set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
|
||||
${MIPS32} ${MIPS64} ${PPC64})
|
||||
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
|
||||
set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
|
||||
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
|
||||
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
|
||||
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}
|
||||
${MIPS32} ${MIPS64})
|
||||
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
|
||||
set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
|
||||
${MIPS32} ${MIPS64} ${PPC64})
|
||||
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})
|
||||
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64})
|
||||
${MIPS32} ${MIPS64} ${PPC64} ${S390X})
|
||||
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64})
|
||||
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64})
|
||||
set(ALL_ESAN_SUPPORTED_ARCH ${X86_64})
|
||||
set(ALL_SCUDO_SUPPORTED_ARCH ${X86_64})
|
||||
|
||||
if(APPLE)
|
||||
include(CompilerRTDarwinUtils)
|
||||
|
||||
# On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
|
||||
# the command line tools. If this is the case, we need to find the OS X
|
||||
# sysroot to pass to clang.
|
||||
if(NOT EXISTS /usr/include)
|
||||
execute_process(COMMAND xcodebuild -version -sdk macosx Path
|
||||
OUTPUT_VARIABLE OSX_SYSROOT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
|
||||
endif()
|
||||
|
||||
option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
|
||||
option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
|
||||
option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
|
||||
|
||||
find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
|
||||
find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
|
||||
find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
|
||||
@ -335,33 +178,23 @@ if(APPLE)
|
||||
set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
|
||||
set(DARWIN_ios_SANITIZER_MIN_VER_FLAG
|
||||
${DARWIN_ios_MIN_VER_FLAG}=7.0)
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
if(COMPILER_RT_ENABLE_WATCHOS)
|
||||
list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
|
||||
set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
|
||||
set(DARWIN_watchos_SANITIZER_MIN_VER_FLAG
|
||||
${DARWIN_watchos_MIN_VER_FLAG}=2.0)
|
||||
set(DARWIN_watchos_BUILTIN_MIN_VER 2.0)
|
||||
set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
if(COMPILER_RT_ENABLE_TVOS)
|
||||
list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
|
||||
set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
|
||||
set(DARWIN_tvos_SANITIZER_MIN_VER_FLAG
|
||||
${DARWIN_tvos_MIN_VER_FLAG}=9.0)
|
||||
set(DARWIN_tvos_BUILTIN_MIN_VER 9.0)
|
||||
set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER})
|
||||
endif()
|
||||
|
||||
# Note: In order to target x86_64h on OS X the minimum deployment target must
|
||||
# be 10.8 or higher.
|
||||
set(SANITIZER_COMMON_SUPPORTED_OS osx)
|
||||
set(BUILTIN_SUPPORTED_OS osx)
|
||||
set(PROFILE_SUPPORTED_OS osx)
|
||||
set(TSAN_SUPPORTED_OS osx)
|
||||
if(NOT SANITIZER_MIN_OSX_VERSION)
|
||||
@ -381,13 +214,13 @@ if(APPLE)
|
||||
|
||||
# We're setting the flag manually for each target OS
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||
|
||||
|
||||
set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
|
||||
set(DARWIN_COMMON_LINKFLAGS
|
||||
-stdlib=libc++
|
||||
-lc++
|
||||
-lc++abi)
|
||||
|
||||
|
||||
check_linker_flag("-fapplication-extension" COMPILER_RT_HAS_APP_EXTENSION)
|
||||
if(COMPILER_RT_HAS_APP_EXTENSION)
|
||||
list(APPEND DARWIN_COMMON_LINKFLAGS "-fapplication-extension")
|
||||
@ -399,9 +232,6 @@ if(APPLE)
|
||||
set(DARWIN_osx_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
-mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
|
||||
set(DARWIN_osx_BUILTIN_MIN_VER 10.5)
|
||||
set(DARWIN_osx_BUILTIN_MIN_VER_FLAG
|
||||
-mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER})
|
||||
|
||||
if(DARWIN_osx_SYSROOT)
|
||||
list(APPEND DARWIN_osx_CFLAGS -isysroot ${DARWIN_osx_SYSROOT})
|
||||
@ -411,7 +241,7 @@ if(APPLE)
|
||||
# Figure out which arches to use for each OS
|
||||
darwin_get_toolchain_supported_archs(toolchain_arches)
|
||||
message(STATUS "Toolchain supported arches: ${toolchain_arches}")
|
||||
|
||||
|
||||
if(NOT MACOSX_VERSION_MIN_FLAG)
|
||||
darwin_test_archs(osx
|
||||
DARWIN_osx_ARCHS
|
||||
@ -422,46 +252,28 @@ if(APPLE)
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
|
||||
# Need to build a 10.4 compatible libclang_rt
|
||||
set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT})
|
||||
set(DARWIN_10.4_BUILTIN_MIN_VER 10.4)
|
||||
set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG
|
||||
-mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER})
|
||||
set(DARWIN_10.4_SKIP_CC_KEXT On)
|
||||
darwin_test_archs(10.4
|
||||
DARWIN_10.4_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "OSX 10.4 supported arches: ${DARWIN_10.4_ARCHS}")
|
||||
if(DARWIN_10.4_ARCHS)
|
||||
# don't include the Haswell slice in the 10.4 compatibility library
|
||||
list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS 10.4)
|
||||
endif()
|
||||
|
||||
foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
|
||||
if(DARWIN_${platform}sim_SYSROOT)
|
||||
set(DARWIN_${platform}sim_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_iossim_SYSROOT})
|
||||
-isysroot ${DARWIN_${platform}sim_SYSROOT})
|
||||
set(DARWIN_${platform}sim_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}sim_SYSROOT})
|
||||
set(DARWIN_${platform}sim_BUILTIN_MIN_VER
|
||||
${DARWIN_${platform}_BUILTIN_MIN_VER})
|
||||
set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG
|
||||
${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG})
|
||||
|
||||
set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
|
||||
darwin_test_archs(${platform}sim
|
||||
DARWIN_${platform}sim_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}")
|
||||
if(DARWIN_iossim_ARCHS)
|
||||
if(DARWIN_${platform}_ARCHS)
|
||||
list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}sim)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim)
|
||||
list(APPEND PROFILE_SUPPORTED_OS ${platform}sim)
|
||||
if(DARWIN_${platform}_SYSROOT_INTERNAL)
|
||||
list(APPEND TSAN_SUPPORTED_OS ${platform}sim)
|
||||
endif()
|
||||
endif()
|
||||
foreach(arch ${DARWIN_${platform}sim_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
@ -485,7 +297,6 @@ if(APPLE)
|
||||
message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}")
|
||||
if(DARWIN_${platform}_ARCHS)
|
||||
list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform})
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ${platform})
|
||||
list(APPEND PROFILE_SUPPORTED_OS ${platform})
|
||||
endif()
|
||||
foreach(arch ${DARWIN_${platform}_ARCHS})
|
||||
@ -499,7 +310,6 @@ if(APPLE)
|
||||
# for list_intersect
|
||||
include(CompilerRTUtils)
|
||||
|
||||
list_intersect(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH toolchain_arches)
|
||||
|
||||
list_intersect(SANITIZER_COMMON_SUPPORTED_ARCH
|
||||
ALL_SANITIZER_COMMON_SUPPORTED_ARCH
|
||||
@ -534,10 +344,14 @@ if(APPLE)
|
||||
list_intersect(CFI_SUPPORTED_ARCH
|
||||
ALL_CFI_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_intersect(ESAN_SUPPORTED_ARCH
|
||||
ALL_ESAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_intersect(SCUDO_SUPPORTED_ARCH
|
||||
ALL_SCUDO_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
else()
|
||||
# Architectures supported by compiler-rt libraries.
|
||||
filter_available_targets(BUILTIN_SUPPORTED_ARCH
|
||||
${ALL_BUILTIN_SUPPORTED_ARCH})
|
||||
filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
|
||||
${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})
|
||||
# LSan and UBSan common files should be available on all architectures
|
||||
@ -556,6 +370,21 @@ else()
|
||||
filter_available_targets(SAFESTACK_SUPPORTED_ARCH
|
||||
${ALL_SAFESTACK_SUPPORTED_ARCH})
|
||||
filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
|
||||
filter_available_targets(ESAN_SUPPORTED_ARCH ${ALL_ESAN_SUPPORTED_ARCH})
|
||||
filter_available_targets(SCUDO_SUPPORTED_ARCH
|
||||
${ALL_SCUDO_SUPPORTED_ARCH})
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# See if the DIA SDK is available and usable.
|
||||
set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK")
|
||||
if (IS_DIRECTORY ${MSVC_DIA_SDK_DIR})
|
||||
set(CAN_SYMBOLIZE 1)
|
||||
else()
|
||||
set(CAN_SYMBOLIZE 0)
|
||||
endif()
|
||||
else()
|
||||
set(CAN_SYMBOLIZE 1)
|
||||
endif()
|
||||
|
||||
message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}")
|
||||
@ -574,15 +403,13 @@ else()
|
||||
set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
|
||||
endif()
|
||||
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND
|
||||
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON)
|
||||
set(COMPILER_RT_HAS_INTERCEPTION TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_INTERCEPTION FALSE)
|
||||
endif()
|
||||
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND
|
||||
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH)
|
||||
set(COMPILER_RT_HAS_ASAN TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_ASAN FALSE)
|
||||
@ -651,3 +478,18 @@ if (COMPILER_RT_HAS_SANITIZER_COMMON AND CFI_SUPPORTED_ARCH AND
|
||||
else()
|
||||
set(COMPILER_RT_HAS_CFI FALSE)
|
||||
endif()
|
||||
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ESAN_SUPPORTED_ARCH AND
|
||||
OS_NAME MATCHES "Linux")
|
||||
set(COMPILER_RT_HAS_ESAN TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_ESAN FALSE)
|
||||
endif()
|
||||
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND
|
||||
OS_NAME MATCHES "Linux")
|
||||
set(COMPILER_RT_HAS_SCUDO TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_SCUDO FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ set(SANITIZER_HEADERS
|
||||
sanitizer/common_interface_defs.h
|
||||
sanitizer/coverage_interface.h
|
||||
sanitizer/dfsan_interface.h
|
||||
sanitizer/esan_interface.h
|
||||
sanitizer/linux_syscall_hooks.h
|
||||
sanitizer/lsan_interface.h
|
||||
sanitizer/msan_interface.h
|
||||
@ -25,6 +26,7 @@ endforeach( f )
|
||||
|
||||
add_custom_target(compiler-rt-headers ALL DEPENDS ${out_files})
|
||||
add_dependencies(compiler-rt compiler-rt-headers)
|
||||
set_target_properties(compiler-rt-headers PROPERTIES FOLDER "Compiler-RT Misc")
|
||||
|
||||
# Install sanitizer headers.
|
||||
install(FILES ${SANITIZER_HEADERS}
|
||||
|
||||
@ -59,6 +59,23 @@ extern "C" {
|
||||
deallocation of "ptr". */
|
||||
void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);
|
||||
void __sanitizer_free_hook(const volatile void *ptr);
|
||||
|
||||
/* Installs a pair of hooks for malloc/free.
|
||||
Several (currently, 5) hook pairs may be installed, they are executed
|
||||
in the order they were installed and after calling
|
||||
__sanitizer_malloc_hook/__sanitizer_free_hook.
|
||||
Unlike __sanitizer_malloc_hook/__sanitizer_free_hook these hooks can be
|
||||
chained and do not rely on weak symbols working on the platform, but
|
||||
require __sanitizer_install_malloc_and_free_hooks to be called at startup
|
||||
and thus will not be called on malloc/free very early in the process.
|
||||
Returns the number of hooks currently installed or 0 on failure.
|
||||
Not thread-safe, should be called in the main thread before starting
|
||||
other threads.
|
||||
*/
|
||||
int __sanitizer_install_malloc_and_free_hooks(
|
||||
void (*malloc_hook)(const volatile void *, size_t),
|
||||
void (*free_hook)(const volatile void *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@ -41,6 +41,9 @@ extern "C" {
|
||||
|
||||
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
|
||||
void __sanitizer_set_report_path(const char *path);
|
||||
// Tell the tools to write their reports to the provided file descriptor
|
||||
// (casted to void *).
|
||||
void __sanitizer_set_report_fd(void *fd);
|
||||
|
||||
// Notify the tools that the sandbox is going to be turned on. The reserved
|
||||
// parameter will be used in the future to hold a structure with functions
|
||||
@ -128,8 +131,45 @@ extern "C" {
|
||||
const void *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, size_t n, int result);
|
||||
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
|
||||
const char *s2, int result);
|
||||
void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
|
||||
const char *s2, char *result);
|
||||
void __sanitizer_weak_hook_memmem(void *called_pc,
|
||||
const void *s1, size_t len1,
|
||||
const void *s2, size_t len2, void *result);
|
||||
|
||||
// Prints stack traces for all live heap allocations ordered by total
|
||||
// allocation size until `top_percent` of total live heap is shown.
|
||||
// `top_percent` should be between 1 and 100.
|
||||
// Experimental feature currently available only with asan on Linux/x86_64.
|
||||
void __sanitizer_print_memory_profile(size_t top_percent);
|
||||
|
||||
// Fiber annotation interface.
|
||||
// Before switching to a different stack, one must call
|
||||
// __sanitizer_start_switch_fiber with a pointer to the bottom of the
|
||||
// destination stack and its size. When code starts running on the new stack,
|
||||
// it must call __sanitizer_finish_switch_fiber to finalize the switch.
|
||||
// The start_switch function takes a void** to store the current fake stack if
|
||||
// there is one (it is needed when detect_stack_use_after_return is enabled).
|
||||
// When restoring a stack, this pointer must be given to the finish_switch
|
||||
// function. In most cases, this void* can be stored on the stack just before
|
||||
// switching. When leaving a fiber definitely, null must be passed as first
|
||||
// argument to the start_switch function so that the fake stack is destroyed.
|
||||
// If you do not want support for stack use-after-return detection, you can
|
||||
// always pass null to these two functions.
|
||||
// Note that the fake stack mechanism is disabled during fiber switch, so if a
|
||||
// signal callback runs during the switch, it will not benefit from the stack
|
||||
// use-after-return detection.
|
||||
void __sanitizer_start_switch_fiber(void **fake_stack_save,
|
||||
const void *bottom, size_t size);
|
||||
void __sanitizer_finish_switch_fiber(void *fake_stack_save);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
46
src/compiler-rt/include/sanitizer/esan_interface.h
Normal file
46
src/compiler-rt/include/sanitizer/esan_interface.h
Normal file
@ -0,0 +1,46 @@
|
||||
//===-- sanitizer/esan_interface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of EfficiencySanitizer, a family of performance tuners.
|
||||
//
|
||||
// Public interface header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_ESAN_INTERFACE_H
|
||||
#define SANITIZER_ESAN_INTERFACE_H
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
|
||||
// We declare our interface routines as weak to allow the user to avoid
|
||||
// ifdefs and instead use this pattern to allow building the same sources
|
||||
// with and without our runtime library:
|
||||
// if (__esan_report)
|
||||
// __esan_report();
|
||||
#ifdef _MSC_VER
|
||||
/* selectany is as close to weak as we'll get. */
|
||||
#define COMPILER_RT_WEAK __declspec(selectany)
|
||||
#elif __GNUC__
|
||||
#define COMPILER_RT_WEAK __attribute__((weak))
|
||||
#else
|
||||
#define COMPILER_RT_WEAK
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This function can be called mid-run (or at the end of a run for
|
||||
// a server process that doesn't shut down normally) to request that
|
||||
// data for that point in the run be reported from the tool.
|
||||
void COMPILER_RT_WEAK __esan_report();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_ESAN_INTERFACE_H
|
||||
@ -1835,6 +1835,17 @@
|
||||
__sanitizer_syscall_pre_impl_vfork()
|
||||
#define __sanitizer_syscall_post_vfork(res) \
|
||||
__sanitizer_syscall_post_impl_vfork(res)
|
||||
#define __sanitizer_syscall_pre_sigaction(signum, act, oldact) \
|
||||
__sanitizer_syscall_pre_impl_sigaction((long)signum, (long)act, (long)oldact)
|
||||
#define __sanitizer_syscall_post_sigaction(res, signum, act, oldact) \
|
||||
__sanitizer_syscall_post_impl_sigaction(res, (long)signum, (long)act, \
|
||||
(long)oldact)
|
||||
#define __sanitizer_syscall_pre_rt_sigaction(signum, act, oldact, sz) \
|
||||
__sanitizer_syscall_pre_impl_rt_sigaction((long)signum, (long)act, \
|
||||
(long)oldact, (long)sz)
|
||||
#define __sanitizer_syscall_post_rt_sigaction(res, signum, act, oldact, sz) \
|
||||
__sanitizer_syscall_post_impl_rt_sigaction(res, (long)signum, (long)act, \
|
||||
(long)oldact, (long)sz)
|
||||
|
||||
// And now a few syscalls we don't handle yet.
|
||||
#define __sanitizer_syscall_pre_afs_syscall(...)
|
||||
@ -1889,7 +1900,6 @@
|
||||
#define __sanitizer_syscall_pre_query_module(...)
|
||||
#define __sanitizer_syscall_pre_readahead(...)
|
||||
#define __sanitizer_syscall_pre_readdir(...)
|
||||
#define __sanitizer_syscall_pre_rt_sigaction(...)
|
||||
#define __sanitizer_syscall_pre_rt_sigreturn(...)
|
||||
#define __sanitizer_syscall_pre_rt_sigsuspend(...)
|
||||
#define __sanitizer_syscall_pre_security(...)
|
||||
@ -1903,7 +1913,6 @@
|
||||
#define __sanitizer_syscall_pre_setreuid32(...)
|
||||
#define __sanitizer_syscall_pre_set_thread_area(...)
|
||||
#define __sanitizer_syscall_pre_setuid32(...)
|
||||
#define __sanitizer_syscall_pre_sigaction(...)
|
||||
#define __sanitizer_syscall_pre_sigaltstack(...)
|
||||
#define __sanitizer_syscall_pre_sigreturn(...)
|
||||
#define __sanitizer_syscall_pre_sigsuspend(...)
|
||||
@ -1971,7 +1980,6 @@
|
||||
#define __sanitizer_syscall_post_query_module(res, ...)
|
||||
#define __sanitizer_syscall_post_readahead(res, ...)
|
||||
#define __sanitizer_syscall_post_readdir(res, ...)
|
||||
#define __sanitizer_syscall_post_rt_sigaction(res, ...)
|
||||
#define __sanitizer_syscall_post_rt_sigreturn(res, ...)
|
||||
#define __sanitizer_syscall_post_rt_sigsuspend(res, ...)
|
||||
#define __sanitizer_syscall_post_security(res, ...)
|
||||
@ -1985,7 +1993,6 @@
|
||||
#define __sanitizer_syscall_post_setreuid32(res, ...)
|
||||
#define __sanitizer_syscall_post_set_thread_area(res, ...)
|
||||
#define __sanitizer_syscall_post_setuid32(res, ...)
|
||||
#define __sanitizer_syscall_post_sigaction(res, ...)
|
||||
#define __sanitizer_syscall_post_sigaltstack(res, ...)
|
||||
#define __sanitizer_syscall_post_sigreturn(res, ...)
|
||||
#define __sanitizer_syscall_post_sigsuspend(res, ...)
|
||||
@ -3062,7 +3069,13 @@ void __sanitizer_syscall_pre_impl_fork();
|
||||
void __sanitizer_syscall_post_impl_fork(long res);
|
||||
void __sanitizer_syscall_pre_impl_vfork();
|
||||
void __sanitizer_syscall_post_impl_vfork(long res);
|
||||
|
||||
void __sanitizer_syscall_pre_impl_sigaction(long signum, long act, long oldact);
|
||||
void __sanitizer_syscall_post_impl_sigaction(long res, long signum, long act,
|
||||
long oldact);
|
||||
void __sanitizer_syscall_pre_impl_rt_sigaction(long signum, long act,
|
||||
long oldact, long sz);
|
||||
void __sanitizer_syscall_post_impl_rt_sigaction(long res, long signum, long act,
|
||||
long oldact, long sz);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@ -15,6 +15,7 @@ if(COMPILER_RT_BUILD_SANITIZERS)
|
||||
|
||||
if(COMPILER_RT_HAS_SANITIZER_COMMON)
|
||||
add_subdirectory(sanitizer_common)
|
||||
add_subdirectory(stats)
|
||||
add_subdirectory(lsan)
|
||||
add_subdirectory(ubsan)
|
||||
endif()
|
||||
@ -47,4 +48,12 @@ if(COMPILER_RT_BUILD_SANITIZERS)
|
||||
if(COMPILER_RT_HAS_CFI)
|
||||
add_subdirectory(cfi)
|
||||
endif()
|
||||
|
||||
if(COMPILER_RT_HAS_ESAN)
|
||||
add_subdirectory(esan)
|
||||
endif()
|
||||
|
||||
if(COMPILER_RT_HAS_SCUDO)
|
||||
add_subdirectory(scudo)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -10,10 +10,4 @@
|
||||
SubDirs :=
|
||||
|
||||
# Add submodules.
|
||||
SubDirs += asan
|
||||
SubDirs += builtins
|
||||
SubDirs += interception
|
||||
SubDirs += lsan
|
||||
SubDirs += profile
|
||||
SubDirs += sanitizer_common
|
||||
SubDirs += ubsan
|
||||
|
||||
@ -13,6 +13,7 @@ set(ASAN_SOURCES
|
||||
asan_malloc_linux.cc
|
||||
asan_malloc_mac.cc
|
||||
asan_malloc_win.cc
|
||||
asan_memory_profile.cc
|
||||
asan_poisoning.cc
|
||||
asan_posix.cc
|
||||
asan_report.cc
|
||||
@ -32,7 +33,7 @@ set(ASAN_PREINIT_SOURCES
|
||||
include_directories(..)
|
||||
|
||||
set(ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
|
||||
append_no_rtti_flag(ASAN_CFLAGS)
|
||||
append_rtti_flag(OFF ASAN_CFLAGS)
|
||||
|
||||
set(ASAN_COMMON_DEFINITIONS
|
||||
ASAN_HAS_EXCEPTIONS=1)
|
||||
@ -62,7 +63,7 @@ append_list_if(WIN32 INTERCEPTION_DYNAMIC_CRT ASAN_DYNAMIC_DEFINITIONS)
|
||||
set(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})
|
||||
append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
|
||||
-ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)
|
||||
append_list_if(MSVC /DEBUG ASAN_DYNAMIC_CFLAGS)
|
||||
append_list_if(MSVC /DEBUG ASAN_DYNAMIC_LINK_FLAGS)
|
||||
|
||||
append_list_if(COMPILER_RT_HAS_LIBC c ASAN_DYNAMIC_LIBS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)
|
||||
@ -74,7 +75,7 @@ append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_DYNAMIC_LIBS)
|
||||
|
||||
# Compile ASan sources into an object library.
|
||||
|
||||
add_compiler_rt_object_libraries(RTAsan_dynamic
|
||||
add_compiler_rt_object_libraries(RTAsan_dynamic
|
||||
OS ${SANITIZER_COMMON_SUPPORTED_OS}
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
|
||||
@ -82,15 +83,15 @@ add_compiler_rt_object_libraries(RTAsan_dynamic
|
||||
DEFS ${ASAN_DYNAMIC_DEFINITIONS})
|
||||
|
||||
if(NOT APPLE)
|
||||
add_compiler_rt_object_libraries(RTAsan
|
||||
add_compiler_rt_object_libraries(RTAsan
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS})
|
||||
add_compiler_rt_object_libraries(RTAsan_cxx
|
||||
add_compiler_rt_object_libraries(RTAsan_cxx
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
SOURCES ${ASAN_CXX_SOURCES} CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS})
|
||||
add_compiler_rt_object_libraries(RTAsan_preinit
|
||||
add_compiler_rt_object_libraries(RTAsan_preinit
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS})
|
||||
@ -105,6 +106,8 @@ endif()
|
||||
|
||||
# Build ASan runtimes shipped with Clang.
|
||||
add_custom_target(asan)
|
||||
set_target_properties(asan PROPERTIES FOLDER "Compiler-RT Misc")
|
||||
|
||||
if(APPLE)
|
||||
add_compiler_rt_runtime(clang_rt.asan
|
||||
SHARED
|
||||
@ -121,40 +124,40 @@ if(APPLE)
|
||||
PARENT_TARGET asan)
|
||||
else()
|
||||
# Build separate libraries for each target.
|
||||
|
||||
set(ASAN_COMMON_RUNTIME_OBJECT_LIBS
|
||||
RTInterception
|
||||
RTSanitizerCommon
|
||||
RTSanitizerCommonLibc
|
||||
RTLSanCommon
|
||||
RTUbsan)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.asan
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_preinit
|
||||
RTAsan
|
||||
${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
set(ASAN_COMMON_RUNTIME_OBJECT_LIBS
|
||||
RTInterception
|
||||
RTSanitizerCommon
|
||||
RTSanitizerCommonLibc
|
||||
RTLSanCommon
|
||||
RTUbsan)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.asan_cxx
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_cxx
|
||||
RTUbsan_cxx
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
add_compiler_rt_runtime(clang_rt.asan
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_preinit
|
||||
RTAsan
|
||||
${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.asan-preinit
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_preinit
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
add_compiler_rt_runtime(clang_rt.asan_cxx
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_cxx
|
||||
RTUbsan_cxx
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.asan-preinit
|
||||
STATIC
|
||||
ARCHS ${ASAN_SUPPORTED_ARCH}
|
||||
OBJECT_LIBS RTAsan_preinit
|
||||
CFLAGS ${ASAN_CFLAGS}
|
||||
DEFS ${ASAN_COMMON_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
|
||||
foreach(arch ${ASAN_SUPPORTED_ARCH})
|
||||
if (UNIX AND NOT ${arch} MATCHES "i386|i686")
|
||||
@ -165,8 +168,8 @@ else()
|
||||
-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
|
||||
PROPERTIES
|
||||
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
|
||||
PROPERTIES
|
||||
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
|
||||
else()
|
||||
set(VERSION_SCRIPT_FLAG)
|
||||
endif()
|
||||
@ -194,7 +197,7 @@ else()
|
||||
ARCHS ${arch})
|
||||
add_dependencies(asan clang_rt.asan_cxx-${arch}-symbols)
|
||||
add_sanitizer_rt_symbols(clang_rt.asan
|
||||
ARCHS ${arch}
|
||||
ARCHS ${arch}
|
||||
EXTRA asan.syms.extra)
|
||||
add_dependencies(asan clang_rt.asan-${arch}-symbols)
|
||||
endif()
|
||||
@ -219,8 +222,7 @@ else()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt)
|
||||
add_dependencies(asan asan_blacklist)
|
||||
add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt asan)
|
||||
add_dependencies(compiler-rt asan)
|
||||
|
||||
add_subdirectory(scripts)
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
#===- lib/asan/Makefile.mk ---------------------------------*- Makefile -*--===#
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
ModuleName := asan
|
||||
SubDirs :=
|
||||
|
||||
CCSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))
|
||||
CXXOnlySources := asan_new_delete.cc
|
||||
COnlySources := $(filter-out $(CXXOnlySources),$(CCSources))
|
||||
SSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))
|
||||
Sources := $(CCSources) $(SSources)
|
||||
ObjNames := $(CCSources:%.cc=%.o) $(SSources:%.S=%.o)
|
||||
|
||||
Implementation := Generic
|
||||
|
||||
# FIXME: use automatic dependencies?
|
||||
Dependencies := $(wildcard $(Dir)/*.h)
|
||||
Dependencies += $(wildcard $(Dir)/../interception/*.h)
|
||||
Dependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)
|
||||
|
||||
# Define a convenience variable for all the asan functions.
|
||||
AsanFunctions := $(COnlySources:%.cc=%) $(SSources:%.S=%)
|
||||
AsanCXXFunctions := $(CXXOnlySources:%.cc=%)
|
||||
@ -47,6 +47,7 @@ static struct AsanDeactivatedFlags {
|
||||
FlagParser parser;
|
||||
RegisterActivationFlags(&parser, &f, &cf);
|
||||
|
||||
cf.SetDefaults();
|
||||
// Copy the current activation flags.
|
||||
allocator_options.CopyTo(&f, &cf);
|
||||
cf.malloc_context_size = malloc_context_size;
|
||||
@ -61,7 +62,7 @@ static struct AsanDeactivatedFlags {
|
||||
parser.ParseString(env);
|
||||
}
|
||||
|
||||
SetVerbosity(cf.verbosity);
|
||||
InitializeCommonFlags(&cf);
|
||||
|
||||
if (Verbosity()) ReportUnrecognizedFlags();
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ void AllocatorOptions::CopyTo(Flags *f, CommonFlags *cf) {
|
||||
|
||||
struct Allocator {
|
||||
static const uptr kMaxAllowedMallocSize =
|
||||
FIRST_32_SECOND_64(3UL << 30, 1UL << 40);
|
||||
FIRST_32_SECOND_64(3UL << 30, 1ULL << 40);
|
||||
static const uptr kMaxThreadLocalQuarantine =
|
||||
FIRST_32_SECOND_64(1 << 18, 1 << 20);
|
||||
|
||||
@ -457,29 +457,28 @@ struct Allocator {
|
||||
return res;
|
||||
}
|
||||
|
||||
void AtomicallySetQuarantineFlag(AsanChunk *m, void *ptr,
|
||||
// Set quarantine flag if chunk is allocated, issue ASan error report on
|
||||
// available and quarantined chunks. Return true on success, false otherwise.
|
||||
bool AtomicallySetQuarantineFlagIfAllocated(AsanChunk *m, void *ptr,
|
||||
BufferedStackTrace *stack) {
|
||||
u8 old_chunk_state = CHUNK_ALLOCATED;
|
||||
// Flip the chunk_state atomically to avoid race on double-free.
|
||||
if (!atomic_compare_exchange_strong((atomic_uint8_t*)m, &old_chunk_state,
|
||||
CHUNK_QUARANTINE, memory_order_acquire))
|
||||
if (!atomic_compare_exchange_strong((atomic_uint8_t *)m, &old_chunk_state,
|
||||
CHUNK_QUARANTINE,
|
||||
memory_order_acquire)) {
|
||||
ReportInvalidFree(ptr, old_chunk_state, stack);
|
||||
// It's not safe to push a chunk in quarantine on invalid free.
|
||||
return false;
|
||||
}
|
||||
CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Expects the chunk to already be marked as quarantined by using
|
||||
// AtomicallySetQuarantineFlag.
|
||||
// AtomicallySetQuarantineFlagIfAllocated.
|
||||
void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
|
||||
|
||||
if (m->alloc_type != alloc_type) {
|
||||
if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) {
|
||||
ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,
|
||||
(AllocType)alloc_type);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_GE(m->alloc_tid, 0);
|
||||
if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area.
|
||||
CHECK_EQ(m->free_tid, kInvalidTid);
|
||||
@ -516,13 +515,24 @@ struct Allocator {
|
||||
|
||||
uptr chunk_beg = p - kChunkHeaderSize;
|
||||
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
|
||||
if (delete_size && flags()->new_delete_type_mismatch &&
|
||||
delete_size != m->UsedSize()) {
|
||||
ReportNewDeleteSizeMismatch(p, delete_size, stack);
|
||||
}
|
||||
|
||||
ASAN_FREE_HOOK(ptr);
|
||||
// Must mark the chunk as quarantined before any changes to its metadata.
|
||||
AtomicallySetQuarantineFlag(m, ptr, stack);
|
||||
// Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag.
|
||||
if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack)) return;
|
||||
|
||||
if (m->alloc_type != alloc_type) {
|
||||
if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) {
|
||||
ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,
|
||||
(AllocType)alloc_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (delete_size && flags()->new_delete_type_mismatch &&
|
||||
delete_size != m->UsedSize()) {
|
||||
ReportNewDeleteSizeMismatch(p, m->UsedSize(), delete_size, stack);
|
||||
}
|
||||
|
||||
QuarantineChunk(m, ptr, stack, alloc_type);
|
||||
}
|
||||
|
||||
@ -655,6 +665,9 @@ static AsanAllocator &get_allocator() {
|
||||
bool AsanChunkView::IsValid() {
|
||||
return chunk_ && chunk_->chunk_state != CHUNK_AVAILABLE;
|
||||
}
|
||||
bool AsanChunkView::IsAllocated() {
|
||||
return chunk_ && chunk_->chunk_state == CHUNK_ALLOCATED;
|
||||
}
|
||||
uptr AsanChunkView::Beg() { return chunk_->Beg(); }
|
||||
uptr AsanChunkView::End() { return Beg() + UsedSize(); }
|
||||
uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); }
|
||||
@ -668,12 +681,15 @@ static StackTrace GetStackTraceFromId(u32 id) {
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 AsanChunkView::GetAllocStackId() { return chunk_->alloc_context_id; }
|
||||
u32 AsanChunkView::GetFreeStackId() { return chunk_->free_context_id; }
|
||||
|
||||
StackTrace AsanChunkView::GetAllocStack() {
|
||||
return GetStackTraceFromId(chunk_->alloc_context_id);
|
||||
return GetStackTraceFromId(GetAllocStackId());
|
||||
}
|
||||
|
||||
StackTrace AsanChunkView::GetFreeStack() {
|
||||
return GetStackTraceFromId(chunk_->free_context_id);
|
||||
return GetStackTraceFromId(GetFreeStackId());
|
||||
}
|
||||
|
||||
void InitializeAllocator(const AllocatorOptions &options) {
|
||||
@ -754,7 +770,7 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp) {
|
||||
uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp) {
|
||||
if (!ptr) return 0;
|
||||
uptr usable_size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));
|
||||
if (flags()->check_malloc_usable_size && (usable_size == 0)) {
|
||||
|
||||
@ -49,14 +49,17 @@ void GetAllocatorOptions(AllocatorOptions *options);
|
||||
class AsanChunkView {
|
||||
public:
|
||||
explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
|
||||
bool IsValid(); // Checks if AsanChunkView points to a valid allocated
|
||||
// or quarantined chunk.
|
||||
uptr Beg(); // First byte of user memory.
|
||||
uptr End(); // Last byte of user memory.
|
||||
uptr UsedSize(); // Size requested by the user.
|
||||
bool IsValid(); // Checks if AsanChunkView points to a valid allocated
|
||||
// or quarantined chunk.
|
||||
bool IsAllocated(); // Checks if the memory is currently allocated.
|
||||
uptr Beg(); // First byte of user memory.
|
||||
uptr End(); // Last byte of user memory.
|
||||
uptr UsedSize(); // Size requested by the user.
|
||||
uptr AllocTid();
|
||||
uptr FreeTid();
|
||||
bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
|
||||
u32 GetAllocStackId();
|
||||
u32 GetFreeStackId();
|
||||
StackTrace GetAllocStack();
|
||||
StackTrace GetFreeStack();
|
||||
bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {
|
||||
@ -171,7 +174,7 @@ void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
|
||||
|
||||
int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp);
|
||||
uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp);
|
||||
|
||||
uptr asan_mz_size(const void *ptr);
|
||||
void asan_mz_force_lock();
|
||||
|
||||
@ -31,7 +31,7 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
|
||||
CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3.
|
||||
u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
|
||||
if (class_id <= 6) {
|
||||
for (uptr i = 0; i < (1U << class_id); i++) {
|
||||
for (uptr i = 0; i < (((uptr)1) << class_id); i++) {
|
||||
shadow[i] = magic;
|
||||
// Make sure this does not become memset.
|
||||
SanitizerBreakOptimization(nullptr);
|
||||
@ -121,7 +121,7 @@ uptr FakeStack::AddrIsInFakeStack(uptr ptr, uptr *frame_beg, uptr *frame_end) {
|
||||
uptr class_id = (ptr - beg) >> stack_size_log;
|
||||
uptr base = beg + (class_id << stack_size_log);
|
||||
CHECK_LE(base, ptr);
|
||||
CHECK_LT(ptr, base + (1UL << stack_size_log));
|
||||
CHECK_LT(ptr, base + (((uptr)1) << stack_size_log));
|
||||
uptr pos = (ptr - base) >> (kMinStackFrameSizeLog + class_id);
|
||||
uptr res = base + pos * BytesInSizeClass(class_id);
|
||||
*frame_end = res + BytesInSizeClass(class_id);
|
||||
|
||||
@ -69,12 +69,12 @@ class FakeStack {
|
||||
|
||||
// stack_size_log is at least 15 (stack_size >= 32K).
|
||||
static uptr SizeRequiredForFlags(uptr stack_size_log) {
|
||||
return 1UL << (stack_size_log + 1 - kMinStackFrameSizeLog);
|
||||
return ((uptr)1) << (stack_size_log + 1 - kMinStackFrameSizeLog);
|
||||
}
|
||||
|
||||
// Each size class occupies stack_size bytes.
|
||||
static uptr SizeRequiredForFrames(uptr stack_size_log) {
|
||||
return (1ULL << stack_size_log) * kNumberOfSizeClasses;
|
||||
return (((uptr)1) << stack_size_log) * kNumberOfSizeClasses;
|
||||
}
|
||||
|
||||
// Number of bytes requires for the whole object.
|
||||
@ -91,12 +91,12 @@ class FakeStack {
|
||||
// and so on.
|
||||
static uptr FlagsOffset(uptr stack_size_log, uptr class_id) {
|
||||
uptr t = kNumberOfSizeClasses - 1 - class_id;
|
||||
const uptr all_ones = (1 << (kNumberOfSizeClasses - 1)) - 1;
|
||||
const uptr all_ones = (((uptr)1) << (kNumberOfSizeClasses - 1)) - 1;
|
||||
return ((all_ones >> t) << t) << (stack_size_log - 15);
|
||||
}
|
||||
|
||||
static uptr NumberOfFrames(uptr stack_size_log, uptr class_id) {
|
||||
return 1UL << (stack_size_log - kMinStackFrameSizeLog - class_id);
|
||||
return ((uptr)1) << (stack_size_log - kMinStackFrameSizeLog - class_id);
|
||||
}
|
||||
|
||||
// Divide n by the numbe of frames in size class.
|
||||
@ -114,7 +114,8 @@ class FakeStack {
|
||||
u8 *GetFrame(uptr stack_size_log, uptr class_id, uptr pos) {
|
||||
return reinterpret_cast<u8 *>(this) + kFlagsOffset +
|
||||
SizeRequiredForFlags(stack_size_log) +
|
||||
(1 << stack_size_log) * class_id + BytesInSizeClass(class_id) * pos;
|
||||
(((uptr)1) << stack_size_log) * class_id +
|
||||
BytesInSizeClass(class_id) * pos;
|
||||
}
|
||||
|
||||
// Allocate the fake frame.
|
||||
@ -137,7 +138,7 @@ class FakeStack {
|
||||
|
||||
// Number of bytes in a fake frame of this size class.
|
||||
static uptr BytesInSizeClass(uptr class_id) {
|
||||
return 1UL << (class_id + kMinStackFrameSizeLog);
|
||||
return ((uptr)1) << (class_id + kMinStackFrameSizeLog);
|
||||
}
|
||||
|
||||
// The fake frame is guaranteed to have a right redzone.
|
||||
@ -159,7 +160,7 @@ class FakeStack {
|
||||
static const uptr kFlagsOffset = 4096; // This is were the flags begin.
|
||||
// Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
|
||||
COMPILER_CHECK(kNumberOfSizeClasses == 11);
|
||||
static const uptr kMaxStackMallocSize = 1 << kMaxStackFrameSizeLog;
|
||||
static const uptr kMaxStackMallocSize = ((uptr)1) << kMaxStackFrameSizeLog;
|
||||
|
||||
uptr hint_position_[kNumberOfSizeClasses];
|
||||
uptr stack_size_log_;
|
||||
|
||||
@ -116,7 +116,7 @@ void InitializeFlags() {
|
||||
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
|
||||
#endif
|
||||
|
||||
SetVerbosity(common_flags()->verbosity);
|
||||
InitializeCommonFlags();
|
||||
|
||||
// TODO(eugenis): dump all flags at verbosity>=2?
|
||||
if (Verbosity()) ReportUnrecognizedFlags();
|
||||
@ -159,6 +159,14 @@ void InitializeFlags() {
|
||||
(ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
|
||||
f->quarantine_size_mb = kDefaultQuarantineSizeMb;
|
||||
}
|
||||
if (!f->replace_str && common_flags()->intercept_strlen) {
|
||||
Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
|
||||
"Use intercept_strlen=0 to disable it.");
|
||||
}
|
||||
if (!f->replace_str && common_flags()->intercept_strchr) {
|
||||
Report("WARNING: strchr* interceptors are enabled even though "
|
||||
"replace_str=0. Use intercept_strchr=0 to disable them.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
@ -43,7 +43,7 @@ ASAN_FLAG(
|
||||
"If set, uses custom wrappers and replacements for libc string functions "
|
||||
"to find more errors.")
|
||||
ASAN_FLAG(bool, replace_intrin, true,
|
||||
"If set, uses custom wrappers for memset/memcpy/memmove intinsics.")
|
||||
"If set, uses custom wrappers for memset/memcpy/memmove intrinsics.")
|
||||
ASAN_FLAG(bool, detect_stack_use_after_return, false,
|
||||
"Enables stack-use-after-return checking at run-time.")
|
||||
ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.
|
||||
@ -77,6 +77,8 @@ ASAN_FLAG(bool, print_stats, false,
|
||||
"Print various statistics after printing an error message or if "
|
||||
"atexit=1.")
|
||||
ASAN_FLAG(bool, print_legend, true, "Print the legend for the shadow bytes.")
|
||||
ASAN_FLAG(bool, print_scariness, false,
|
||||
"Print the scariness score. Experimental.")
|
||||
ASAN_FLAG(bool, atexit, false,
|
||||
"If set, prints ASan exit stats even after program terminates "
|
||||
"successfully.")
|
||||
@ -104,7 +106,7 @@ ASAN_FLAG(bool, alloc_dealloc_mismatch,
|
||||
"Report errors on malloc/delete, new/free, new/delete[], etc.")
|
||||
|
||||
ASAN_FLAG(bool, new_delete_type_mismatch, true,
|
||||
"Report errors on mismatch betwen size of new and delete.")
|
||||
"Report errors on mismatch between size of new and delete.")
|
||||
ASAN_FLAG(
|
||||
bool, strict_init_order, false,
|
||||
"If true, assume that dynamic initializers can never access globals from "
|
||||
@ -135,3 +137,5 @@ ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
|
||||
ASAN_FLAG(bool, halt_on_error, true,
|
||||
"Crash the program after printing the first error report "
|
||||
"(WARNING: USE AT YOUR OWN RISK!)")
|
||||
ASAN_FLAG(bool, use_odr_indicator, false,
|
||||
"Use special ODR indicator symbol for ODR violation detection")
|
||||
|
||||
@ -135,6 +135,70 @@ bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enum GlobalSymbolState {
|
||||
UNREGISTERED = 0,
|
||||
REGISTERED = 1
|
||||
};
|
||||
|
||||
// Check ODR violation for given global G via special ODR indicator. We use
|
||||
// this method in case compiler instruments global variables through their
|
||||
// local aliases.
|
||||
static void CheckODRViolationViaIndicator(const Global *g) {
|
||||
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
|
||||
if (*odr_indicator == UNREGISTERED) {
|
||||
*odr_indicator = REGISTERED;
|
||||
return;
|
||||
}
|
||||
// If *odr_indicator is DEFINED, some module have already registered
|
||||
// externally visible symbol with the same name. This is an ODR violation.
|
||||
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
|
||||
if (g->odr_indicator == l->g->odr_indicator &&
|
||||
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
|
||||
!IsODRViolationSuppressed(g->name))
|
||||
ReportODRViolation(g, FindRegistrationSite(g),
|
||||
l->g, FindRegistrationSite(l->g));
|
||||
}
|
||||
}
|
||||
|
||||
// Check ODR violation for given global G by checking if it's already poisoned.
|
||||
// We use this method in case compiler doesn't use private aliases for global
|
||||
// variables.
|
||||
static void CheckODRViolationViaPoisoning(const Global *g) {
|
||||
if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
|
||||
// This check may not be enough: if the first global is much larger
|
||||
// the entire redzone of the second global may be within the first global.
|
||||
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
|
||||
if (g->beg == l->g->beg &&
|
||||
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
|
||||
!IsODRViolationSuppressed(g->name))
|
||||
ReportODRViolation(g, FindRegistrationSite(g),
|
||||
l->g, FindRegistrationSite(l->g));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clang provides two different ways for global variables protection:
|
||||
// it can poison the global itself or its private alias. In former
|
||||
// case we may poison same symbol multiple times, that can help us to
|
||||
// cheaply detect ODR violation: if we try to poison an already poisoned
|
||||
// global, we have ODR violation error.
|
||||
// In latter case, we poison each symbol exactly once, so we use special
|
||||
// indicator symbol to perform similar check.
|
||||
// In either case, compiler provides a special odr_indicator field to Global
|
||||
// structure, that can contain two kinds of values:
|
||||
// 1) Non-zero value. In this case, odr_indicator is an address of
|
||||
// corresponding indicator variable for given global.
|
||||
// 2) Zero. This means that we don't use private aliases for global variables
|
||||
// and can freely check ODR violation with the first method.
|
||||
//
|
||||
// This routine chooses between two different methods of ODR violation
|
||||
// detection.
|
||||
static inline bool UseODRIndicator(const Global *g) {
|
||||
// Use ODR indicator method iff use_odr_indicator flag is set and
|
||||
// indicator symbol address is not 0.
|
||||
return flags()->use_odr_indicator && g->odr_indicator > 0;
|
||||
}
|
||||
|
||||
// Register a global variable.
|
||||
// This function may be called more than once for every global
|
||||
// so we store the globals in a map.
|
||||
@ -144,22 +208,24 @@ static void RegisterGlobal(const Global *g) {
|
||||
ReportGlobal(*g, "Added");
|
||||
CHECK(flags()->report_globals);
|
||||
CHECK(AddrIsInMem(g->beg));
|
||||
CHECK(AddrIsAlignedByGranularity(g->beg));
|
||||
if (!AddrIsAlignedByGranularity(g->beg)) {
|
||||
Report("The following global variable is not properly aligned.\n");
|
||||
Report("This may happen if another global with the same name\n");
|
||||
Report("resides in another non-instrumented module.\n");
|
||||
Report("Or the global comes from a C file built w/o -fno-common.\n");
|
||||
Report("In either case this is likely an ODR violation bug,\n");
|
||||
Report("but AddressSanitizer can not provide more details.\n");
|
||||
ReportODRViolation(g, FindRegistrationSite(g), g, FindRegistrationSite(g));
|
||||
CHECK(AddrIsAlignedByGranularity(g->beg));
|
||||
}
|
||||
CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
|
||||
if (flags()->detect_odr_violation) {
|
||||
// Try detecting ODR (One Definition Rule) violation, i.e. the situation
|
||||
// where two globals with the same name are defined in different modules.
|
||||
if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
|
||||
// This check may not be enough: if the first global is much larger
|
||||
// the entire redzone of the second global may be within the first global.
|
||||
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
|
||||
if (g->beg == l->g->beg &&
|
||||
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
|
||||
!IsODRViolationSuppressed(g->name))
|
||||
ReportODRViolation(g, FindRegistrationSite(g),
|
||||
l->g, FindRegistrationSite(l->g));
|
||||
}
|
||||
}
|
||||
if (UseODRIndicator(g))
|
||||
CheckODRViolationViaIndicator(g);
|
||||
else
|
||||
CheckODRViolationViaPoisoning(g);
|
||||
}
|
||||
if (CanPoisonMemory())
|
||||
PoisonRedZones(*g);
|
||||
@ -190,6 +256,12 @@ static void UnregisterGlobal(const Global *g) {
|
||||
// We unpoison the shadow memory for the global but we do not remove it from
|
||||
// the list because that would require O(n^2) time with the current list
|
||||
// implementation. It might not be worth doing anyway.
|
||||
|
||||
// Release ODR indicator.
|
||||
if (UseODRIndicator(g)) {
|
||||
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
|
||||
*odr_indicator = UNREGISTERED;
|
||||
}
|
||||
}
|
||||
|
||||
void StopInitOrderChecking() {
|
||||
@ -212,6 +284,25 @@ void StopInitOrderChecking() {
|
||||
// ---------------------- Interface ---------------- {{{1
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
|
||||
// Apply __asan_register_globals to all globals found in the same loaded
|
||||
// executable or shared library as `flag'. The flag tracks whether globals have
|
||||
// already been registered or not for this image.
|
||||
void __asan_register_image_globals(uptr *flag) {
|
||||
if (*flag)
|
||||
return;
|
||||
AsanApplyToGlobals(__asan_register_globals, flag);
|
||||
*flag = 1;
|
||||
}
|
||||
|
||||
// This mirrors __asan_register_image_globals.
|
||||
void __asan_unregister_image_globals(uptr *flag) {
|
||||
if (!*flag)
|
||||
return;
|
||||
AsanApplyToGlobals(__asan_unregister_globals, flag);
|
||||
*flag = 0;
|
||||
}
|
||||
|
||||
// Register an array of globals.
|
||||
void __asan_register_globals(__asan_global *globals, uptr n) {
|
||||
if (!flags()->report_globals) return;
|
||||
|
||||
@ -19,16 +19,20 @@ extern "C" {
|
||||
// Every time the ASan ABI changes we also change the version number in the
|
||||
// __asan_init function name. Objects built with incompatible ASan ABI
|
||||
// versions will not link with run-time.
|
||||
//
|
||||
// Changes between ABI versions:
|
||||
// v1=>v2: added 'module_name' to __asan_global
|
||||
// v2=>v3: stack frame description (created by the compiler)
|
||||
// contains the function PC as the 3-rd field (see
|
||||
// DescribeAddressIfStack).
|
||||
// v3=>v4: added '__asan_global_source_location' to __asan_global.
|
||||
// contains the function PC as the 3rd field (see
|
||||
// DescribeAddressIfStack)
|
||||
// v3=>v4: added '__asan_global_source_location' to __asan_global
|
||||
// v4=>v5: changed the semantics and format of __asan_stack_malloc_ and
|
||||
// __asan_stack_free_ functions.
|
||||
// __asan_stack_free_ functions
|
||||
// v5=>v6: changed the name of the version check symbol
|
||||
#define __asan_version_mismatch_check __asan_version_mismatch_check_v6
|
||||
// v6=>v7: added 'odr_indicator' to __asan_global
|
||||
// v7=>v8: added '__asan_(un)register_image_globals' functions for dead
|
||||
// stripping support on Mach-O platforms
|
||||
#define __asan_version_mismatch_check __asan_version_mismatch_check_v8
|
||||
}
|
||||
|
||||
#endif // ASAN_INIT_VERSION_H
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "asan_stack.h"
|
||||
#include "asan_stats.h"
|
||||
#include "asan_suppressions.h"
|
||||
#include "lsan/lsan_common.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
|
||||
#if SANITIZER_POSIX
|
||||
@ -110,7 +111,7 @@ static inline bool RangesOverlap(const char *offset1, uptr length1,
|
||||
} while (0)
|
||||
|
||||
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
|
||||
#if ASAN_INTERCEPT_STRNLEN
|
||||
#if SANITIZER_INTERCEPT_STRNLEN
|
||||
if (REAL(strnlen)) {
|
||||
return REAL(strnlen)(s, maxlen);
|
||||
}
|
||||
@ -143,6 +144,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
|
||||
(void) ctx; \
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
|
||||
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
||||
ASAN_INTERCEPT_FUNC_VER(name, ver)
|
||||
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
||||
ASAN_WRITE_RANGE(ctx, ptr, size)
|
||||
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
|
||||
@ -195,6 +198,10 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
|
||||
} else { \
|
||||
*begin = *end = 0; \
|
||||
}
|
||||
// Asan needs custom handling of these:
|
||||
#undef SANITIZER_INTERCEPT_MEMSET
|
||||
#undef SANITIZER_INTERCEPT_MEMMOVE
|
||||
#undef SANITIZER_INTERCEPT_MEMCPY
|
||||
#include "sanitizer_common/sanitizer_common_interceptors.inc"
|
||||
|
||||
// Syscall interceptors don't have contexts, we don't support suppressions
|
||||
@ -218,6 +225,7 @@ struct ThreadStartParam {
|
||||
atomic_uintptr_t is_registered;
|
||||
};
|
||||
|
||||
#if ASAN_INTERCEPT_PTHREAD_CREATE
|
||||
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
||||
ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
|
||||
AsanThread *t = nullptr;
|
||||
@ -228,7 +236,6 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
||||
return t->ThreadStart(GetTid(), ¶m->is_registered);
|
||||
}
|
||||
|
||||
#if ASAN_INTERCEPT_PTHREAD_CREATE
|
||||
INTERCEPTOR(int, pthread_create, void *thread,
|
||||
void *attr, void *(*start_routine)(void*), void *arg) {
|
||||
EnsureMainThreadIDIsCorrect();
|
||||
@ -242,7 +249,17 @@ INTERCEPTOR(int, pthread_create, void *thread,
|
||||
ThreadStartParam param;
|
||||
atomic_store(¶m.t, 0, memory_order_relaxed);
|
||||
atomic_store(¶m.is_registered, 0, memory_order_relaxed);
|
||||
int result = REAL(pthread_create)(thread, attr, asan_thread_start, ¶m);
|
||||
int result;
|
||||
{
|
||||
// Ignore all allocations made by pthread_create: thread stack/TLS may be
|
||||
// stored by pthread for future reuse even after thread destruction, and
|
||||
// the linked list it's stored in doesn't even hold valid pointers to the
|
||||
// objects, the latter are calculated by obscure pointer arithmetic.
|
||||
#if CAN_SANITIZE_LEAKS
|
||||
__lsan::ScopedInterceptorDisabler disabler;
|
||||
#endif
|
||||
result = REAL(pthread_create)(thread, attr, asan_thread_start, ¶m);
|
||||
}
|
||||
if (result == 0) {
|
||||
u32 current_tid = GetCurrentTidOrInvalid();
|
||||
AsanThread *t =
|
||||
@ -271,7 +288,8 @@ DEFINE_REAL_PTHREAD_FUNCTIONS
|
||||
|
||||
#if SANITIZER_ANDROID
|
||||
INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
|
||||
if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
|
||||
if (!IsHandledDeadlySignal(signum) ||
|
||||
common_flags()->allow_user_segv_handler) {
|
||||
return REAL(bsd_signal)(signum, handler);
|
||||
}
|
||||
return 0;
|
||||
@ -279,7 +297,8 @@ INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
|
||||
#endif
|
||||
|
||||
INTERCEPTOR(void*, signal, int signum, void *handler) {
|
||||
if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
|
||||
if (!IsHandledDeadlySignal(signum) ||
|
||||
common_flags()->allow_user_segv_handler) {
|
||||
return REAL(signal)(signum, handler);
|
||||
}
|
||||
return nullptr;
|
||||
@ -287,7 +306,8 @@ INTERCEPTOR(void*, signal, int signum, void *handler) {
|
||||
|
||||
INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact) {
|
||||
if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
|
||||
if (!IsHandledDeadlySignal(signum) ||
|
||||
common_flags()->allow_user_segv_handler) {
|
||||
return REAL(sigaction)(signum, act, oldact);
|
||||
}
|
||||
return 0;
|
||||
@ -453,25 +473,6 @@ INTERCEPTOR(void*, memset, void *block, int c, uptr size) {
|
||||
ASAN_MEMSET_IMPL(ctx, block, c, size);
|
||||
}
|
||||
|
||||
INTERCEPTOR(char*, strchr, const char *str, int c) {
|
||||
void *ctx;
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, strchr);
|
||||
if (UNLIKELY(!asan_inited)) return internal_strchr(str, c);
|
||||
// strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is
|
||||
// used.
|
||||
if (asan_init_is_running) {
|
||||
return REAL(strchr)(str, c);
|
||||
}
|
||||
ENSURE_ASAN_INITED();
|
||||
char *result = REAL(strchr)(str, c);
|
||||
if (flags()->replace_str) {
|
||||
uptr len = REAL(strlen)(str);
|
||||
uptr bytes_read = (result ? result - str : len) + 1;
|
||||
ASAN_READ_STRING_OF_LEN(ctx, str, len, bytes_read);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if ASAN_INTERCEPT_INDEX
|
||||
# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
|
||||
INTERCEPTOR(char*, index, const char *string, int c)
|
||||
@ -549,7 +550,6 @@ INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
|
||||
return REAL(strcpy)(to, from); // NOLINT
|
||||
}
|
||||
|
||||
#if ASAN_INTERCEPT_STRDUP
|
||||
INTERCEPTOR(char*, strdup, const char *s) {
|
||||
void *ctx;
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, strdup);
|
||||
@ -564,29 +564,28 @@ INTERCEPTOR(char*, strdup, const char *s) {
|
||||
REAL(memcpy)(new_mem, s, length + 1);
|
||||
return reinterpret_cast<char*>(new_mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
INTERCEPTOR(SIZE_T, strlen, const char *s) {
|
||||
#if ASAN_INTERCEPT___STRDUP
|
||||
INTERCEPTOR(char*, __strdup, const char *s) {
|
||||
void *ctx;
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, strlen);
|
||||
if (UNLIKELY(!asan_inited)) return internal_strlen(s);
|
||||
// strlen is called from malloc_default_purgeable_zone()
|
||||
// in __asan::ReplaceSystemAlloc() on Mac.
|
||||
if (asan_init_is_running) {
|
||||
return REAL(strlen)(s);
|
||||
}
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, strdup);
|
||||
if (UNLIKELY(!asan_inited)) return internal_strdup(s);
|
||||
ENSURE_ASAN_INITED();
|
||||
SIZE_T length = REAL(strlen)(s);
|
||||
uptr length = REAL(strlen)(s);
|
||||
if (flags()->replace_str) {
|
||||
ASAN_READ_RANGE(ctx, s, length + 1);
|
||||
}
|
||||
return length;
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
void *new_mem = asan_malloc(length + 1, &stack);
|
||||
REAL(memcpy)(new_mem, s, length + 1);
|
||||
return reinterpret_cast<char*>(new_mem);
|
||||
}
|
||||
#endif // ASAN_INTERCEPT___STRDUP
|
||||
|
||||
INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
|
||||
void *ctx;
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
|
||||
SIZE_T length = REAL(wcslen)(s);
|
||||
SIZE_T length = internal_wcslen(s);
|
||||
if (!asan_init_is_running) {
|
||||
ENSURE_ASAN_INITED();
|
||||
ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));
|
||||
@ -607,19 +606,6 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
|
||||
return REAL(strncpy)(to, from, size);
|
||||
}
|
||||
|
||||
#if ASAN_INTERCEPT_STRNLEN
|
||||
INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) {
|
||||
void *ctx;
|
||||
ASAN_INTERCEPTOR_ENTER(ctx, strnlen);
|
||||
ENSURE_ASAN_INITED();
|
||||
uptr length = REAL(strnlen)(s, maxlen);
|
||||
if (flags()->replace_str) {
|
||||
ASAN_READ_RANGE(ctx, s, Min(length + 1, maxlen));
|
||||
}
|
||||
return length;
|
||||
}
|
||||
#endif // ASAN_INTERCEPT_STRNLEN
|
||||
|
||||
INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
|
||||
char **endptr, int base) {
|
||||
void *ctx;
|
||||
@ -702,12 +688,12 @@ INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
|
||||
}
|
||||
#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
|
||||
|
||||
#if ASAN_INTERCEPT___CXA_ATEXIT
|
||||
static void AtCxaAtexit(void *unused) {
|
||||
(void)unused;
|
||||
StopInitOrderChecking();
|
||||
}
|
||||
|
||||
#if ASAN_INTERCEPT___CXA_ATEXIT
|
||||
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
|
||||
void *dso_handle) {
|
||||
#if SANITIZER_MAC
|
||||
@ -739,25 +725,23 @@ void InitializeAsanInterceptors() {
|
||||
InitializeCommonInterceptors();
|
||||
|
||||
// Intercept mem* functions.
|
||||
ASAN_INTERCEPT_FUNC(memmove);
|
||||
ASAN_INTERCEPT_FUNC(memcpy);
|
||||
ASAN_INTERCEPT_FUNC(memset);
|
||||
if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
|
||||
ASAN_INTERCEPT_FUNC(memcpy);
|
||||
// In asan, REAL(memmove) is not used, but it is used in msan.
|
||||
ASAN_INTERCEPT_FUNC(memmove);
|
||||
}
|
||||
CHECK(REAL(memcpy));
|
||||
|
||||
// Intercept str* functions.
|
||||
ASAN_INTERCEPT_FUNC(strcat); // NOLINT
|
||||
ASAN_INTERCEPT_FUNC(strchr);
|
||||
ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
|
||||
ASAN_INTERCEPT_FUNC(strlen);
|
||||
ASAN_INTERCEPT_FUNC(wcslen);
|
||||
ASAN_INTERCEPT_FUNC(strncat);
|
||||
ASAN_INTERCEPT_FUNC(strncpy);
|
||||
#if ASAN_INTERCEPT_STRDUP
|
||||
ASAN_INTERCEPT_FUNC(strdup);
|
||||
#endif
|
||||
#if ASAN_INTERCEPT_STRNLEN
|
||||
ASAN_INTERCEPT_FUNC(strnlen);
|
||||
#if ASAN_INTERCEPT___STRDUP
|
||||
ASAN_INTERCEPT_FUNC(__strdup);
|
||||
#endif
|
||||
#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
|
||||
ASAN_INTERCEPT_FUNC(index);
|
||||
|
||||
@ -23,14 +23,12 @@
|
||||
#if !SANITIZER_WINDOWS
|
||||
# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1
|
||||
# define ASAN_INTERCEPT__LONGJMP 1
|
||||
# define ASAN_INTERCEPT_STRDUP 1
|
||||
# define ASAN_INTERCEPT_INDEX 1
|
||||
# define ASAN_INTERCEPT_PTHREAD_CREATE 1
|
||||
# define ASAN_INTERCEPT_FORK 1
|
||||
#else
|
||||
# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
|
||||
# define ASAN_INTERCEPT__LONGJMP 0
|
||||
# define ASAN_INTERCEPT_STRDUP 0
|
||||
# define ASAN_INTERCEPT_INDEX 0
|
||||
# define ASAN_INTERCEPT_PTHREAD_CREATE 0
|
||||
# define ASAN_INTERCEPT_FORK 0
|
||||
@ -42,12 +40,6 @@
|
||||
# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_MAC
|
||||
# define ASAN_INTERCEPT_STRNLEN 1
|
||||
#else
|
||||
# define ASAN_INTERCEPT_STRNLEN 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
# define ASAN_INTERCEPT_SWAPCONTEXT 1
|
||||
#else
|
||||
@ -80,6 +72,12 @@
|
||||
# define ASAN_INTERCEPT___CXA_ATEXIT 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
# define ASAN_INTERCEPT___STRDUP 1
|
||||
#else
|
||||
# define ASAN_INTERCEPT___STRDUP 0
|
||||
#endif
|
||||
|
||||
DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
|
||||
DECLARE_REAL(void*, memcpy, void *to, const void *from, uptr size)
|
||||
DECLARE_REAL(void*, memset, void *block, int c, uptr size)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user