Commit Graph

181 Commits

Author SHA1 Message Date
bors
d3929b2c8a Auto merge of #30969 - Amanieu:extended_atomic_cmpxchg, r=alexcrichton
This is an implementation of rust-lang/rfcs#1443.
2016-02-22 19:10:13 +00:00
Alex Crichton
95761417c3 rustbuild: Sync some Cargo.toml/lib.rs dependencies
The standard library doesn't depend on rustc_bitflags, so move it to explicit
dependencies on all other crates. Additionally, the arena/fmt_macros deps could
be dropped from libsyntax.
2016-02-21 09:49:13 -08:00
Amanieu d'Antras
64ddcb33f4 Add intrinsics for compare_exchange and compare_exchange_weak 2016-02-18 19:07:05 +00:00
Corey Farwell
5850d16d52 Remove unnecessary explicit lifetime bounds.
These explicit lifetimes can be ommitted because of lifetime elision
rules. Instances were found using rust-clippy.
2016-02-18 08:37:10 -05:00
Alex Crichton
34f7364332 rustc_llvm: Tweak how initialization is performed
Refactor a bit to have less repetition and #[cfg] and try to bury it all inside
of a macro.
2016-02-11 11:12:33 -08:00
Alex Crichton
eac0a8bc30 bootstrap: Add directives to not double-link libs
Have all Cargo-built crates pass `--cfg cargobuild` and then add appropriate
`#[cfg]` definitions to all crates to avoid linking anything if this is passed.
This should help allow libstd to compile with both the makefiles and with Cargo.
2016-02-11 11:12:32 -08:00
Alex Crichton
4da4970767 bootstrap: Add build scripts for crates
This commits adds build scripts to the necessary Rust crates for all the native
dependencies. This is currently a duplication of the support found in mk/rt.mk
and is my best effort at representing the logic twice, but there may be some
unfortunate-and-inevitable divergence.

As a summary:

* alloc_jemalloc - build script to compile jemallocal
* flate - build script to compile miniz.c
* rustc_llvm - build script to run llvm-config and learn about how to link it.
  Note that this crucially (and will not ever) compile LLVM as that would take
  far too long.
* rustdoc - build script to compile hoedown
* std - script to determine lots of libraries/linkages as well as compile
  libbacktrace
2016-02-11 11:12:32 -08:00
Alex Crichton
2581b14147 bootstrap: Add a bunch of Cargo.toml files
These describe the structure of all our crate dependencies.
2016-02-11 11:12:32 -08:00
Alex Crichton
696a1da861 Remove old #[allow(trivial_casts)] annotations
These were added a long time ago but we long since switched the lint back to
allow-by-default, so these annotations shouldn't be necessary.
2016-02-08 09:35:09 -08:00
Alex Crichton
3e9589c0f4 trans: Reimplement unwinding on MSVC
This commit transitions the compiler to using the new exception handling
instructions in LLVM for implementing unwinding for MSVC. This affects both 32
and 64-bit MSVC as they're both now using SEH-based strategies. In terms of
standard library support, lots more details about how SEH unwinding is
implemented can be found in the commits.

In terms of trans, this change necessitated a few modifications:

* Branches were added to detect when the old landingpad instruction is used or
  the new cleanuppad instruction is used to `trans::cleanup`.
* The return value from `cleanuppad` is not stored in an `alloca` (because it
  cannot be).
* Each block in trans now has an `Option<LandingPad>` instead of `is_lpad: bool`
  for indicating whether it's in a landing pad or not. The new exception
  handling intrinsics require that on MSVC each `call` inside of a landing pad
  is annotated with which landing pad that it's in. This change to the basic
  block means that whenever a `call` or `invoke` instruction is generated we
  know whether to annotate it as part of a cleanuppad or not.
* Lots of modifications were made to the instruction builders to construct the
  new instructions as well as pass the tagging information for the call/invoke
  instructions.
* The translation of the `try` intrinsics for MSVC has been overhauled to use
  the new `catchpad` instruction. The filter function is now also a
  rustc-generated function instead of a purely libstd-defined function. The
  libstd definition still exists, it just has a stable ABI across architectures
  and leaves some of the really weird implementation details to the compiler
  (e.g. the `localescape` and `localrecover` intrinsics).
2016-01-29 16:25:20 -08:00
Alex Crichton
d1cace17af trans: Upgrade LLVM
This brings some routine upgrades to the bundled LLVM that we're using, the most
notable of which is a bug fix to the way we handle range asserts when loading
the discriminant of an enum. This fix ended up being very similar to f9d4149c
where we basically can't have a range assert when loading a discriminant due to
filling drop, and appropriate flags were added to communicate this to
`trans::adt`.
2016-01-29 16:25:20 -08:00
bors
4b615854f0 Auto merge of #31120 - alexcrichton:attribute-deny-warnings, r=brson
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.

Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
2016-01-26 22:10:10 +00:00
Corey Farwell
d9426210b1 Register LLVM passes with the correct LLVM pass manager.
LLVM was upgraded to a new version in this commit:

f9d4149c29

which was part of this pull request:

https://github.com/rust-lang/rust/issues/26025

Consider the following two lines from that commit:

f9d4149c29 (diff-a3b24dbe2ea7c1981f9ac79f9745f40aL462)

f9d4149c29 (diff-a3b24dbe2ea7c1981f9ac79f9745f40aL469)

The purpose of these lines is to register LLVM passes. Prior to the that
commit, the passes being handled were assumed to be ModulePasses (a
specific type of LLVM pass) since they were being added to a ModulePass
manager. After that commit, both lines were refactored (presumably in an
attempt to DRY out the code), but the ModulePasses were changed to be
registered to a FunctionPass manager. This change resulted in
ModulePasses being run, but a Function object was being passed as a
parameter to the pass instead of a Module, which resulted in
segmentation faults.

In this commit, I changed relevant sections of the code to check the
type of the passes being added and register them to the appropriate pass
manager.

Closes https://github.com/rust-lang/rust/issues/31067
2016-01-25 00:15:39 -05:00
Alex Crichton
2273b52023 mk: Move from -D warnings to #![deny(warnings)]
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.

Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
2016-01-24 20:35:55 -08:00
Steffen
9af75d2bec llvm: Add support for vectorcall (X86_VectorCall) convention 2015-12-26 21:40:40 +01:00
Alex Crichton
cd1848a1a6 Register new snapshots
Lots of cruft to remove!
2015-12-21 09:26:21 -08:00
bors
cef0d0f9a8 Auto merge of #30401 - DiamondLovesYou:pnacl-target, r=alexcrichton
r? @alexcrichton
2015-12-19 21:29:04 +00:00
Richard Diamond
0442be8e1c Add PNaCl target info to the makefile target cfgs and initialize the PNaCl target
machine if available.
2015-12-19 00:26:53 -06:00
Björn Steinbrink
88ffb26cf5 Fix emitting asm and object file output at the same time
LLVM doesn't really support reusing the same module to emit more than
one file. One bug this causes is that the IR is invalidated by the stack
coloring pass when emitting the first file, and then the IR verifier
complains by the time we try to emit the second file. Also, we get
different binaries with --emit=asm,link than with just --emit=link. In
some cases leading to segfaults.

Unfortunately, it seems that at this point in time, the most sensible
option to circumvent this problem is to just clone the whole llvm module
for the asm output if we need both, asm and obj file output.

Fixes #24876
Fixes #26235
2015-12-18 04:14:52 +01:00
Richard Diamond
7bd69f2248 Better support for --llvm-root.
This handles cases when the LLVM used isn't configured will the 'usual'
targets. Also, cases where LLVM is shared are also handled (ie with
`LD_LIBRARY_PATH` etc).
2015-12-13 15:05:43 -06:00
Alex Crichton
464cdff102 std: Stabilize APIs for the 1.6 release
This commit is the standard API stabilization commit for the 1.6 release cycle.
The list of issues and APIs below have all been through their cycle-long FCP and
the libs team decisions are listed below

Stabilized APIs

* `Read::read_exact`
* `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`)
* libcore -- this was a bit of a nuanced stabilization, the crate itself is now
  marked as `#[stable]` and the methods appearing via traits for primitives like
  `char` and `str` are now also marked as stable. Note that the extension traits
  themeselves are marked as unstable as they're imported via the prelude. The
  `try!` macro was also moved from the standard library into libcore to have the
  same interface. Otherwise the functions all have copied stability from the
  standard library now.
* The `#![no_std]` attribute
* `fs::DirBuilder`
* `fs::DirBuilder::new`
* `fs::DirBuilder::recursive`
* `fs::DirBuilder::create`
* `os::unix::fs::DirBuilderExt`
* `os::unix::fs::DirBuilderExt::mode`
* `vec::Drain`
* `vec::Vec::drain`
* `string::Drain`
* `string::String::drain`
* `vec_deque::Drain`
* `vec_deque::VecDeque::drain`
* `collections::hash_map::Drain`
* `collections::hash_map::HashMap::drain`
* `collections::hash_set::Drain`
* `collections::hash_set::HashSet::drain`
* `collections::binary_heap::Drain`
* `collections::binary_heap::BinaryHeap::drain`
* `Vec::extend_from_slice` (renamed from `push_all`)
* `Mutex::get_mut`
* `Mutex::into_inner`
* `RwLock::get_mut`
* `RwLock::into_inner`
* `Iterator::min_by_key` (renamed from `min_by`)
* `Iterator::max_by_key` (renamed from `max_by`)

Deprecated APIs

* `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`)
* `OsString::from_bytes`
* `OsStr::to_cstring`
* `OsStr::to_bytes`
* `fs::walk_dir` and `fs::WalkDir`
* `path::Components::peek`
* `slice::bytes::MutableByteVector`
* `slice::bytes::copy_memory`
* `Vec::push_all` (renamed to `extend_from_slice`)
* `Duration::span`
* `IpAddr`
* `SocketAddr::ip`
* `Read::tee`
* `io::Tee`
* `Write::broadcast`
* `io::Broadcast`
* `Iterator::min_by` (renamed to `min_by_key`)
* `Iterator::max_by` (renamed to `max_by_key`)
* `net::lookup_addr`

New APIs (still unstable)

* `<[T]>::sort_by_key` (added to mirror `min_by_key`)

Closes #27585
Closes #27704
Closes #27707
Closes #27710
Closes #27711
Closes #27727
Closes #27740
Closes #27744
Closes #27799
Closes #27801
cc #27801 (doesn't close as `Chars` is still unstable)
Closes #28968
2015-12-05 15:09:44 -08:00
Vadim Petrochenkov
be8ace8cac Remove all uses of #[staged_api] 2015-11-25 21:55:26 +03:00
Steve Klabnik
ff8859880b Rollup merge of #29933 - tbu-:pr_dont_opt_in_copy, r=nikomatsakis
It was introduced with the change that made copy opt-in. The
implementation gives a warning, because the struct contains a raw
pointer.
2015-11-24 09:43:46 -05:00
Brian Anderson
99741700e5 Remove segmented stack option from LLVMRustCreateTargetMachine. Unused. 2015-11-19 16:58:23 -08:00
Tobias Bucher
c5971a29da Remove unneeded #[derive(Copy)]
It was introduced with the change that made copy opt-in. The
implementation gives a warning, because the struct contains a raw
pointer.
2015-11-19 16:00:54 +00:00
Devon Hollowood
07e108f038 Remove 'raw_pointer_derive' lint (#14615) 2015-11-17 01:19:14 -08:00
Alex Crichton
3d28b8b98e std: Migrate to the new libc
* Delete `sys::unix::{c, sync}` as these are now all folded into libc itself
* Update all references to use `libc` as a result.
* Update all references to the new flat namespace.
* Moves all windows bindings into sys::c
2015-11-09 22:55:50 -08:00
Andrew Paseltiner
6031a58a20 Remove some trivial transmutes
`rbml::writer::Encoder::unsafe_clone` had no users across the entire
repo.
2015-10-17 20:29:49 -04:00
Alex Crichton
2972b77134 Add issue for the rustc_private feature everywhere 2015-08-15 18:09:17 -07:00
Alex Crichton
837ae4f3d4 rollup merge of #27678: alexcrichton/snapshots
* Lots of core prelude imports removed
* Makefile support for MSVC env vars and Rust crates removed
* Makefile support for morestack removed
2015-08-11 22:42:22 -07:00
Alex Crichton
737397c584 rollup merge of #27622: eefriedman/https-url
Also fixes a few outdated links.
2015-08-11 22:11:25 -07:00
Alex Crichton
938099a7eb Register new snapshots
* Lots of core prelude imports removed
* Makefile support for MSVC env vars and Rust crates removed
* Makefile support for morestack removed
2015-08-11 15:11:13 -07:00
Alex Crichton
e648c96c5f trans: Stop informing LLVM about dllexport
Rust's current compilation model makes it impossible on Windows to generate one
object file with a complete and final set of dllexport annotations. This is
because when an object is generated the compiler doesn't actually know if it
will later be included in a dynamic library or not. The compiler works around
this today by flagging *everything* as dllexport, but this has the drawback of
exposing too much.

Thankfully there are alternate methods of specifying the exported surface area
of a dll on Windows, one of which is passing a `*.def` file to the linker which
lists all public symbols of the dynamic library. This commit removes all
locations that add `dllexport` to LLVM variables and instead dynamically
generates a `*.def` file which is passed to the linker. This file will include
all the public symbols of the current object file as well as all upstream
libraries, and the crucial aspect is that it's only used when generating a
dynamic library. When generating an executable this file isn't generated, so all
the symbols aren't exported from an executable.

To ensure that statically included native libraries are reexported correctly,
the previously added support for the `#[linked_from]` attribute is used to
determine the set of FFI symbols that are exported from a dynamic library, and
this is required to get the compiler to link correctly.
2015-08-10 18:20:42 -07:00
Eli Friedman
bbbfed2f93 Use https URLs to refer to rust-lang.org where appropriate.
Also fixes a few outdated links.
2015-08-09 14:28:46 -07:00
Eli Friedman
6fa17b43d3 Rewrite the improper_ctypes lint.
Makes the lint a bit more accurate, and improves the quality of the diagnostic
messages by explicitly returning an error message.

The new lint is also a little more aggressive: specifically, it now
rejects tuples, and it recurses into function pointers.
2015-07-23 17:03:04 -07:00
Alex Crichton
c35b2bd226 trans: Move rust_try into the compiler
This commit moves the IR files in the distribution, rust_try.ll,
rust_try_msvc_64.ll, and rust_try_msvc_32.ll into the compiler from the main
distribution. There's a few reasons for this change:

* LLVM changes its IR syntax from time to time, so it's very difficult to
  have these files build across many LLVM versions simultaneously. We'll likely
  want to retain this ability for quite some time into the future.
* The implementation of these files is closely tied to the compiler and runtime
  itself, so it makes sense to fold it into a location which can do more
  platform-specific checks for various implementation details (such as MSVC 32
  vs 64-bit).
* This removes LLVM as a build-time dependency of the standard library. This may
  end up becoming very useful if we move towards building the standard library
  with Cargo.

In the immediate future, however, this commit should restore compatibility with
LLVM 3.5 and 3.6.
2015-07-21 16:08:11 -07:00
Alex Crichton
958d563825 trans: Clean up handling the LLVM data layout
Turns out for OSX our data layout was subtly wrong and the LLVM update must have
exposed this. Instead of fixing this I've removed all data layouts from the
compiler to just use the defaults that LLVM provides for all targets. All data
layouts (and a number of dead modules) are removed from the compiler here.
Custom target specifications can still provide a custom data layout, but it is
now an optional key as the default will be used if one isn't specified.
2015-07-16 20:25:52 -07:00
Alex Crichton
74e198126b trans: Add kind to writeArchive
Updates our LLVM bindings to be able to write out multiple kinds of archives.
This commit also enables using LLVM instead of the system ar on all current
targets.
2015-07-16 20:25:51 -07:00
Alex Crichton
7f0e733f1d rustc_trans: Update LLVMBuildLandingPad signature
The C API of this function changed so it no longer takes a personality function.
A shim was introduced to call the right LLVM function (depending on which
version we're compiled against) to set the personality function on the outer
function.

The compiler only ever sets one personality function for all generated
functions, so this should be equivalent.
2015-07-16 20:25:51 -07:00
Alex Crichton
4a824275b9 trans: Use LLVM's writeArchive to modify archives
We have previously always relied upon an external tool, `ar`, to modify archives
that the compiler produces (staticlibs, rlibs, etc). This approach, however, has
a number of downsides:

* Spawning a process is relatively expensive for small compilations
* Encoding arguments across process boundaries often incurs unnecessary overhead
  or lossiness. For example `ar` has a tough time dealing with files that have
  the same name in archives, and the compiler copies many files around to ensure
  they can be passed to `ar` in a reasonable fashion.
* Most `ar` programs found do **not** have the ability to target arbitrary
  platforms, so this is an extra tool which needs to be found/specified when
  cross compiling.

The LLVM project has had a tool called `llvm-ar` for quite some time now, but it
wasn't available in the standard LLVM libraries (it was just a standalone
program). Recently, however, in LLVM 3.7, this functionality has been moved to a
library and is now accessible by consumers of LLVM via the `writeArchive`
function.

This commit migrates our archive bindings to no longer invoke `ar` by default
but instead make a library call to LLVM to do various operations. This solves
all of the downsides listed above:

* Archive management is now much faster, for example creating a "hello world"
  staticlib is now 6x faster (50ms => 8ms). Linking dynamic libraries also
  recently started requiring modification of rlibs, and linking a hello world
  dynamic library is now 2x faster.
* The compiler is now one step closer to "hassle free" cross compilation because
  no external tool is needed for managing archives, LLVM does the right thing!

This commit does not remove support for calling a system `ar` utility currently.
We will continue to maintain compatibility with LLVM 3.5 and 3.6 looking forward
(so the system LLVM can be used wherever possible), and in these cases we must
shell out to a system utility. All nightly builds of Rust, however, will stop
needing a system `ar`.
2015-07-10 09:06:21 -07:00
Björn Steinbrink
dea5a9608c Simplify argument forwarding in the various shim generators 2015-06-20 03:35:24 +02:00
bors
9cc0b22475 Auto merge of #26192 - alexcrichton:features-clean, r=aturon
This commit shards the all-encompassing `core`, `std_misc`, `collections`, and `alloc` features into finer-grained components that are much more easily opted into and tracked. This reflects the effort to push forward current unstable APIs to either stabilization or removal. Keeping track of unstable features on a much more fine-grained basis will enable the library subteam to quickly analyze a feature and help prioritize internally about what APIs should be stabilized.

A few assorted APIs were deprecated along the way, but otherwise this change is just changing the feature name associated with each API. Soon we will have a dashboard for keeping track of all the unstable APIs in the standard library, and I'll also start making issues for each unstable API after performing a first-pass for stabilization.
2015-06-18 19:14:52 +00:00
Oliver Schneider
59638d15c1 remove unused functions from trans and llvm 2015-06-18 13:23:41 +02:00
Alex Crichton
d444d0c357 collections: Split the collections feature
This commit also deprecates the `as_string` and `as_slice` free functions in the
`string` and `vec` modules.
2015-06-17 09:06:59 -07:00
Alex Crichton
f9d4149c29 rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:

* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
  significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
  ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
  `PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
  `no-frame-pointer-elim` function attribute instead.

Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-06-16 22:56:42 -07:00
bors
71a8d313c8 Auto merge of #25627 - murarth:execution-engine-fix, r=nrc
* Removes `RustJITMemoryManager` from public API.
  This was really sort of an implementation detail to begin with.
* `__morestack` is linked to C++ wrapper code and this pointer
  is used when resolving the symbol for `ExecutionEngine` code.
* `__morestack_addr` is also resolved for `ExecutionEngine` code.
  This function is sometimes referenced in LLVM-generated code,
  but was not able to be resolved on Mac OS systems.
* Added Windows support to `ExecutionEngine` API.
* Added a test for basic `ExecutionEngine` functionality.
2015-06-09 04:28:57 +00:00
Murarth
021e48326d Changes to LLVM ExecutionEngine wrapper
* Removes `RustJITMemoryManager` from public API.
  This was really sort of an implementation detail to begin with.
* `__morestack` is linked to C++ wrapper code and this pointer
  is used when resolving the symbol for `ExecutionEngine` code.
* `__morestack_addr` is also resolved for `ExecutionEngine` code.
  This function is sometimes referenced in LLVM-generated code,
  but was not able to be resolved on Mac OS systems.
* Added Windows support to `ExecutionEngine` API.
* Added a test for basic `ExecutionEngine` functionality.
2015-06-08 16:54:50 -07:00
Luca Bruno
ce32f6412e rustc_trans: don't hardcode llvm version for conditional intrinsics
This commit introduce a third parameter for compatible_ifn!, as new
intrinsics are being added in recent LLVM releases and there is no
need to hardcode a specific case.

Signed-off-by: Luca Bruno <lucab@debian.org>
2015-06-07 22:47:00 -04:00
bors
43cf733bfa Auto merge of #25350 - alexcrichton:msvc, r=brson
Special thanks to @retep998 for the [excellent writeup](https://github.com/rust-lang/rfcs/issues/1061) of tasks to be done and @ricky26 for initially blazing the trail here!

# MSVC Support

This goal of this series of commits is to add MSVC support to the Rust compiler
and build system, allowing it more easily interoperate with Visual Studio
installations and native libraries compiled outside of MinGW.

The tl;dr; of this change is that there is a new target of the compiler,
`x86_64-pc-windows-msvc`, which will not interact with the MinGW toolchain at
all and will instead use `link.exe` to assemble output artifacts.

## Why try to use MSVC?

With today's Rust distribution, when you install a compiler on Windows you also
install `gcc.exe` and a number of supporting libraries by default (this can be
opted out of). This allows installations to remain independent of MinGW
installations, but it still generally requires native code to be linked with
MinGW instead of MSVC. Some more background can also be found in #1768 about the
incompatibilities between MinGW and MSVC.

Overall the current installation strategy is quite nice so long as you don't
interact with native code, but once you do the usage of a MinGW-based `gcc.exe`
starts to get quite painful.

Relying on a nonstandard Windows toolchain has also been a long-standing "code
smell" of Rust and has been slated for remedy for quite some time now. Using a
standard toolchain is a great motivational factor for improving the
interoperability of Rust code with the native system.

## What does it mean to use MSVC?

"Using MSVC" can be a bit of a nebulous concept, but this PR defines it as:

* The build system for Rust will build as much code as possible with the MSVC
  compiler, `cl.exe`.
* The build system will use native MSVC tools for managing archives.
* The compiler will link all output with `link.exe` instead of `gcc.exe`.

None of these are currently implemented today, but all are required for the
compiler to fluently interoperate with MSVC.

## How does this all work?

At the highest level, this PR adds a new target triple to the Rust compiler:

    x86_64-pc-windows-msvc

All logic for using MSVC or not is scoped within this triple and code can
conditionally build for MSVC or MinGW via:

    #[cfg(target_env = "msvc")]

It is expected that auto builders will be set up for MSVC-based compiles in
addition to the existing MinGW-based compiles, and we will likely soon start
shipping MSVC nightlies where `x86_64-pc-windows-msvc` is the host target triple
of the compiler.

# Summary of changes

Here I'll explain at a high level what many of the changes made were targeted
at, but many more details can be found in the commits themselves. Many thanks to
@retep998 for the excellent writeup in rust-lang/rfcs#1061 and @rick26 for a lot
of the initial proof-of-concept work!

## Build system changes

As is probably expected, a large chunk of this PR is changes to Rust's build
system to build with MSVC. At a high level **it is an explicit non goal** to
enable building outside of a MinGW shell, instead all Makefile infrastructure we
have today is retrofitted with support to use MSVC instead of the standard MSVC
toolchain. Some of the high-level changes are:

* The configure script now detects when MSVC is being targeted and adds a number
  of additional requirements about the build environment:
  * The `--msvc-root` option must be specified or `cl.exe` must be in PATH to
    discover where MSVC is installed. The compiler in use is also required to
    target x86_64.
  * Once the MSVC root is known, the INCLUDE/LIB environment variables are
    scraped so they can be reexported by the build system.
  * CMake is required to build LLVM with MSVC (and LLVM is also configured with
    CMake instead of the normal configure script).
  * jemalloc is currently unconditionally disabled for MSVC targets as jemalloc
    isn't a hard requirement and I don't know how to build it with MSVC.
* Invocations of a C and/or C++ compiler are now abstracted behind macros to
  appropriately call the underlying compiler with the correct format of
  arguments, for example there is now a macro for "assemble an archive from
  objects" instead of hard-coded invocations of `$(AR) crus liboutput.a ...`
* The output filenames for standard libraries such as morestack/compiler-rt are
  now "more correct" on windows as they are shipped as `foo.lib` instead of
  `libfoo.a`.
* Rust targets can now depend on native tools provided by LLVM, and as you'll
  see in the commits the entire MSVC target depends on `llvm-ar.exe`.
* Support for custom arbitrary makefile dependencies of Rust targets has been
  added. The MSVC target for `rustc_llvm` currently requires a custom `.DEF`
  file to be passed to the linker to get further linkages to complete.

## Compiler changes

The modifications made to the compiler have so far largely been minor tweaks
here and there, mostly just adding a layer of abstraction over whether MSVC or a
GNU-like linker is being used. At a high-level these changes are:

* The section name for metadata storage in dynamic libraries is called `.rustc`
  for MSVC-based platorms as section names cannot contain more than 8
  characters.
* The implementation of `rustc_back::Archive` was refactored, but the
  functionality has remained the same.
* Targets can now specify the default `ar` utility to use, and for MSVC this
  defaults to `llvm-ar.exe`
* The building of the linker command in `rustc_trans:🔙:link` has been
  abstracted behind a trait for the same code path to be used between GNU and
  MSVC linkers.

## Standard library changes

Only a few small changes were required to the stadnard library itself, and only
for minor differences between the C runtime of msvcrt.dll and MinGW's libc.a

* Some function names for floating point functions have leading underscores, and
  some are not present at all.
* Linkage to the `advapi32` library for crypto-related functions is now
  explicit.
* Some small bits of C code here and there were fixed for compatibility with
  MSVC's cl.exe compiler.

# Future Work

This commit is not yet a 100% complete port to using MSVC as there are still
some key components missing as well as some unimplemented optimizations. This PR
is already getting large enough that I wanted to draw the line here, but here's
a list of what is not implemented in this PR, on purpose:

## Unwinding

The revision of our LLVM submodule [does not seem to implement][llvm] does not
support lowering SEH exception handling on the Windows MSVC targets, so
unwinding support is not currently implemented for the standard library (it's
lowered to an abort).

[llvm]: https://github.com/rust-lang/llvm/blob/rust-llvm-2015-02-19/lib/CodeGen/Passes.cpp#L454-L461

It looks like, however, that upstream LLVM has quite a bit more support for SEH
unwinding and landing pads than the current revision we have, so adding support
will likely just involve updating LLVM and then adding some shims of our own
here and there.

## dllimport and dllexport

An interesting part of Windows which MSVC forces our hand on (and apparently
MinGW didn't) is the usage of `dllimport` and `dllexport` attributes in LLVM IR
as well as native dependencies (in C these correspond to
`__declspec(dllimport)`).

Whenever a dynamic library is built by MSVC it must have its public interface
specified by functions tagged with `dllexport` or otherwise they're not
available to be linked against. This poses a few problems for the compiler, some
of which are somewhat fundamental, but this commit alters the compiler to attach
the `dllexport` attribute to all LLVM functions that are reachable (e.g. they're
already tagged with external linkage). This is suboptimal for a few reasons:

* If an object file will never be included in a dynamic library, there's no need
  to attach the dllexport attribute. Most object files in Rust are not destined
  to become part of a dll as binaries are statically linked by default.
* If the compiler is emitting both an rlib and a dylib, the same source object
  file is currently used but with MSVC this may be less feasible. The compiler
  may be able to get around this, but it may involve some invasive changes to
  deal with this.

The flipside of this situation is that whenever you link to a dll and you import
a function from it, the import should be tagged with `dllimport`. At this time,
however, the compiler does not emit `dllimport` for any declarations other than
constants (where it is required), which is again suboptimal for even more
reasons!

* Calling a function imported from another dll without using `dllimport` causes
  the linker/compiler to have extra overhead (one `jmp` instruction on x86) when
  calling the function.
* The same object file may be used in different circumstances, so a function may
  be imported from a dll if the object is linked into a dll, but it may be
  just linked against if linked into an rlib.
* The compiler has no knowledge about whether native functions should be tagged
  dllimport or not.

For now the compiler takes the perf hit (I do not have any numbers to this
effect) by marking very little as `dllimport` and praying the linker will take
care of everything. Fixing this problem will likely require adding a few
attributes to Rust itself (feature gated at the start) and then strongly
recommending static linkage on Windows! This may also involve shipping a
statically linked compiler on Windows instead of a dynamically linked compiler,
but these sorts of changes are pretty invasive and aren't part of this PR.

## CI integration

Thankfully we don't need to set up a new snapshot bot for the changes made here as our snapshots are freestanding already, we should be able to use the same snapshot to bootstrap both MinGW and MSVC compilers (once a new snapshot is made from these changes).

I plan on setting up a new suite of auto bots which are testing MSVC configurations for now as well, for now they'll just be bootstrapping and not running tests, but once unwinding is implemented they'll start running all tests as well and we'll eventually start gating on them as well.

---

I'd love as many eyes on this as we've got as this was one of my first interactions with MSVC and Visual Studio, so there may be glaring holes that I'm missing here and there!

cc @retep998, @ricky26, @vadimcn, @klutzy 

r? @brson
2015-05-20 00:31:55 +00:00
Alex Crichton
847c8520b1 rustc_llvm: Don't export constants across dlls
For imports of constants across DLLs to work on Windows it *requires* that the
import be marked with `dllimport` (unlike functions where the marker is
optional, but strongly recommended). This currently isn't working for importing
FFI constants across boundaries, however, so the one constant exported from
`rustc_llvm.dll` is now a function to be called instead.
2015-05-19 10:53:07 -07:00