This commit removes the ndebug support from Cargo and also adds a new
configuration option for profiles, `debug-assertions`, which controls whether
debug assertions in the compiler are turned on or not.
Closes#1398
This commit is a complete overhaul of how Cargo handles compilation profiles
internally. The external interface of Cargo is not affected by this change.
Previously each Target had a Profile embedded within it. Conceptually a Target
is an entry in the manifest (a binary, benchmark, etc) and a Profile controlled
various flags (e.g. --test, -C opt-level, etc). Each Package then contained many
profiles for each possible compilation mode. For example a Package would have
one target for testing a library, benchmarking a library, documenting a library,
etc. When it came to building these targets, Cargo would filter out the targets
listed to determine what needed to be built.
This filtering was largely done based off an "environment" represented as a
string. Each mode of compilation got a separate environment string like `"test"`
or `"bench"`. Altogether, however, this approach had a number of drawbacks:
* Examples in release mode do not currently work. This is due to how examples
are classified and how release mode is handled (e.g. the "release" environment
where examples are meant to be built in the "test" environment).
* It is not trivial to implement `cargo test --release` today.
* It is not trivial to implement `cargo build --bin foo` where *only* the binary
`foo` is built. The same is true for examples.
* It is not trivial to add selective building of a number of
binaries/examples/etc.
* Filtering the list of targets to build has some pretty hokey logic that
involves pseudo-environments like "doc-all" vs "doc". This logic is duplicated
in a few places and in general is quite brittle.
* The TOML parser greatly affects compilation due to the time at which profiles
are generated, which seems somewhat backwards.
* Profiles must be overridden, but only partially, at compile time becuase only
the top-level package's profile is applied.
In general, this system just needed an overhaul. This commit made a single
change of separating `Profile` from `Target` and then basically hit `make` until
all the tests passed again. The other large architectural changes are:
* Environment strings are now entirely gone.
* Filters are implemented in a much more robust fashion.
* Release mode is now handled much more gracefully.
* The unit of compilation in the backend is no longer (package, target) but
rather (package, target, profile). This change had to be propagated many
location in the `cargo_rustc` module.
* The backend does not filter targets to build *at all*. All filtering now
happens entirely in the frontend.
I'll test issues after this change lands, but the motivation behind this is to
open the door to quickly fixing a number of outstanding issues against Cargo.
This change itself is not intended to close many bugs.
This adds a new `--bin` flag to `cargo test` to specifically say that a binary
should be tested. Additionally the dependencies are tweaked such that binaries
to not depend on themselves being available.
This commit is a complete overhaul of how Cargo handles compilation profiles
internally. The external interface of Cargo is not affected by this change.
Previously each Target had a Profile embedded within it. Conceptually a Target
is an entry in the manifest (a binary, benchmark, etc) and a Profile controlled
various flags (e.g. --test, -C opt-level, etc). Each Package then contained many
profiles for each possible compilation mode. For example a Package would have
one target for testing a library, benchmarking a library, documenting a library,
etc. When it came to building these targets, Cargo would filter out the targets
listed to determine what needed to be built.
This filtering was largely done based off an "environment" represented as a
string. Each mode of compilation got a separate environment string like `"test"`
or `"bench"`. Altogether, however, this approach had a number of drawbacks:
* Examples in release mode do not currently work. This is due to how examples
are classified and how release mode is handled (e.g. the "release" environment
where examples are meant to be built in the "test" environment).
* It is not trivial to implement `cargo test --release` today.
* It is not trivial to implement `cargo build --bin foo` where *only* the binary
`foo` is built. The same is true for examples.
* It is not trivial to add selective building of a number of
binaries/examples/etc.
* Filtering the list of targets to build has some pretty hokey logic that
involves pseudo-environments like "doc-all" vs "doc". This logic is duplicated
in a few places and in general is quite brittle.
* The TOML parser greatly affects compilation due to the time at which profiles
are generated, which seems somewhat backwards.
* Profiles must be overridden, but only partially, at compile time becuase only
the top-level package's profile is applied.
In general, this system just needed an overhaul. This commit made a single
change of separating `Profile` from `Target` and then basically hit `make` until
all the tests passed again. The other large architectural changes are:
* Environment strings are now entirely gone.
* Filters are implemented in a much more robust fashion.
* Release mode is now handled much more gracefully.
* The unit of compilation in the backend is no longer (package, target) but
rather (package, target, profile). This change had to be propagated many
location in the `cargo_rustc` module.
* The backend does not filter targets to build *at all*. All filtering now
happens entirely in the frontend.
I'll test issues after this change lands, but the motivation behind this is to
open the door to quickly fixing a number of outstanding issues against Cargo.
This change itself is not intended to close many bugs.
This commit now funnels all output of Cargo by default to be in `target/debug`
instead of the bare `target` directory. This change is targeted at raising
awareness of whether a debug build is being used (as opposed to a release
build). It is also aimed at remedying a common scenario where `cargo build` is
followed by `cargo build --release` and then the debug binaries are run by
accident.
This does not yet explore the option of providing symlinks to the most recent
build, hence this commit is a breaking change due to the restructuring of the
layout of the output.
Note that this commit does **not** change the output location for documentation.
All output of `cargo doc` continues to be funneled into the `target/doc`
directory.
Closes#785
Over time this functionality has become obsolete through other means. Due to the
usage of `-L dependency=foo` it's not possible to pick up stale dependencies by
accident, and due to `--extern` you can only pick up a dependency. All of the
cases that auto-cleaning was fixing are now fixed through other methods, so
there's not much use ensuring a "clean build directory" any more.
This has the benefit of fixing issues like #961 where the downside of long
compiles outweighs the benefits of a "let's pretend we started from scratch"
build.
Closes#961
Originally discovered through #1236, this commit fixes a bug in Cargo where
crates may not be recompiled when they need to (leading to obscure errors from
the compiler). The scenario in question looks like:
* Assume a dependency graph of `A -> B -> C` and `A -> C`
* Build all packages
* Modify C
* Rebuild, but hit Ctrl+C while B is building
* Modify A
* Rebuild again
Previously, Cargo only considered the freshness of a package to be the freshness
of the package itself (checking source files, for example). To handle transitive
recompilations, Cargo propagates a dirty bit throughout the dependency graph
automatically (instead if calculating it as such).
In the above example, however, we have a problem where as part of the last
rebuild Cargo thinks `B` and `C` are fresh! The artifact for `C` was just
recompiled, but `B`'s source code is untainted, so Cargo does not think that it
needs to recompile `B`. This is wrong, however, because one of `B`'s
dependencies was rebuilt, so it needs to be rebuilt.
To fix this problem, the fingerprint (a short hash) for all packages is now
transitively propagated (the fingerprint changes when an upstream package
changes). This should ensure that even when Ctrl+C is hit (or the situation
explained in #1236) that Cargo will still consider packages whose source code is
untainted as candidates for recompilation.
The implementation is somewhat tricky due to the actual fingerprint for a path
dependency not being known until *after* the crate is compiled (the fingerprint
is the mtime of the dep-info file).
Closes#1236
This commit cleans up cargo's error module to reduce the duplication of
`CargoError` and the standard library's `Error` trait. The `CargoError` trait
remains, but only has one methods, `is_human`.
A number of other modifications were made:
* ChainError was altered to work over unboxed closures
* Wrap and Require were removed as they're duplicates of the ChainError
functionality.
* Many public error types are now private from util::errors as they're only
returned as boxed trait objects.
* The `concrete` was removed, all calls to `make_human` are now done through a
newtype `Human` wrapper.
* Cargo's custom `try!` macro was removed.
Two tests (test_with_deep_lib_dep and lib_with_standard_name) fail due
to a bug in rustdoc (see rust-lang/rust#20183) so temporarily changing
these so they pass. Be sure to change it back when the fix lands in the
current rust nightly
I'm a bit shaky on the profile.rs changes (`thread_local!` and `RefCell`
relplacing `local_data_key!`), do make sure I haven't royally screwed
something up there.
Note that I haven't sucessfully run the various test_cargo_cross_compile
tests as I don't have an i686-unknown-linux-gnu rustc sitting around.
With #843 and #839 coming around the bend soon, the original decision for
`--name` everywhere isn't making as much sense, for consistence this is renaming
these flags back to `--<target-name>` for the respective targets.
This ends up killing two birds with one stone! The rationale behind this is that
the example and bin namespaces are not the same, and we don't mix metadata into
either filename, so the outputs need to be in different locations.
Closes#193Closes#751
Examples are classified as binaries, but do not have the `test` flag set on
their Profile. They do, however, have their environment set to `test`. Be sure
to place them into the `tests` bucket so they have development dependencies
available for their compilation.
Now that we have selective testing, this no longer makes any sense and all
queries to the path layout need to be based on the package being queried for.
This removes the primary flag from the Context, and requires that the `layout`
method have a local Package available
cc servo/servo#3580
This functionality allows running tests and benchmarks on any upstream
dependencies in the dependency graph. This is most useful for path sources all
developed in tandem (see Servo for instance).
In terms of built artifacts, this will actually preserve as many artifacts as
possible. That means that if you test a low-level dependency with the high-level
artifacts already built, the high-level artifacts will not get removed. This
means that it's possible to accidentally have a low-level dependency to depend
on a higher level one just because it's lib is picked up via -L, but this is
generally a necessary evil to get testing to not rebuild packages too often.
Closes#483
This option is used to disable the --test flag to rustc for a test or benchmark
target in order to signal that the binary already knows how to run the testing
infrastructure.
The test/benchmark is still compiled and run as usual, and the exit code is
expected to reflect the result of the test/benchmark.
Closes#431