rustpkg now makes source files that it checks out automatically read-only, and stores them under build/. Also, refactored the `PkgSrc` type to keep track of separate source and destination workspaces, as well as to have a `build_workspace` method that returns the workspace to put temporary files in (usually the source, sometimes the destination -- see comments for more details). Closes #6480
7.4 KiB
% Rustpkg Reference Manual
Introduction
This document is the reference manual for the Rustpkg packaging and build tool for the Rust programming language.
Disclaimer
Rustpkg is a work in progress, as is this reference manual. If the actual behavior of rustpkg differs from the behavior described in this reference, that reflects either an incompleteness or a bug in rustpkg.
Package searching
rustpkg searches for packages using the RUST_PATH
environment variable,
which is a colon-separated list (semicolon-separated on Windows) of directories.
Each directory in this list is a workspace for rustpkg.
RUST_PATH
implicitly contains an entry for ./.rust
(as well as
../.rust
, ../../.rust
,
and so on for every parent of .
up to the filesystem root).
That means that if RUST_PATH
is not set,
then rustpkg will still search for workspaces in ./.rust
and so on.
RUST_PATH
also implicitly contains an entry for the system path:
/usr/local
or the equivalent on Windows.
This entry comes after the implicit entries for ./.rust
and so on.
Finally, the last implicit entry in RUST_PATH
is ~/.rust
or the equivalent on Windows.
Each workspace may contain one or more packages.
When building code that contains one or more directives of the form extern mod P
,
rustpkg automatically searches for packages named P
in the RUST_PATH
(as described above).
It builds those dependencies if necessary.
Thus, when using rustpkg,
there is no need for -L
flags to tell the linker where to find libraries for external crates.
Package structure
A valid workspace must contain each of the following subdirectories:
-
'src/': contains one subdirectory per package. Each subdirectory contains source files for a given package.
For example, if
foo
is a workspace containing the packagebar
, thenfoo/src/bar/main.rs
could be themain
entry point for building abar
executable. -
'lib/':
rustpkg install
installs libraries into a target-specific subdirectory of this directory.For example, on a 64-bit machine running Mac OS X, if
foo
is a workspace containing the packagebar
, rustpkg will install libraries for bar tofoo/lib/x86_64-apple-darwin/
. The libraries will have names of the formfoo/lib/x86_64-apple-darwin/libbar-[hash].dylib
, where [hash] is a hash of the package ID. -
'bin/':
rustpkg install
installs executable binaries into this directory.For example, rustpkg will install executables for
bar
tofoo/bin
. The executables will have names of the formfoo/bin/bar
. -
'build/':
rustpkg build
stores temporary build artifacts in a target-specific subdirectory of this directory.For example, on a 64-bit machine running Mac OS X, if
foo
is a workspace containing the packagebar
andfoo/src/bar/main.rs
exists, thenrustpkg build
will createfoo/build/x86_64-apple-darwin/bar/main.o
.
Package identifiers
A package identifier identifies a package uniquely.
A package can be stored in a workspace on the local file system,
or on a remote Web server, in which case the package ID resembles a URL.
For example, github.com/mozilla/rust
is a package ID
that would refer to the git repository browsable at http://github.com/mozilla/rust
.
A package ID can also specify a version, like:
github.com/mozilla/rust#0.3
.
In this case, rustpkg
will check that the repository github.com/mozilla/rust
has a tag named 0.3
,
and report an error otherwise.
A package ID can also specify a particular revision of a repository, like:
github.com/mozilla/rust#release-0.7
.
When the refspec (portion of the package ID after the #
) can't be parsed as a decimal number,
rustpkg passes the refspec along to the version control system without interpreting it.
rustpkg also interprets any dependencies on such a package ID literally
(as opposed to versions, where a newer version satisfies a dependency on an older version).
Thus, github.com/mozilla/rust#5c4cd30f80
is also a valid package ID,
since git can deduce that 5c4cd30f80
refers to a revision of the desired repository.
A package identifier can name a subdirectory of another package.
For example, if foo
is a workspace, and foo/src/bar/lib.rs
exists,
as well as foo/src/bar/extras/baz/lib.rs
,
then both bar
and bar/extras/baz
are valid package identifiers
in the workspace foo
.
Source files
rustpkg searches for four different fixed filenames in order to determine the crates to build:
main.rs
: Assumed to be a main entry point for building an executable.lib.rs
: Assumed to be a library crate.test.rs
: Assumed to contain tests declared with the#[test]
attribute.bench.rs
: Assumed to contain benchmarks declared with the#[bench]
attribute.
Versions
rustpkg
packages do not need to declare their versions with an attribute inside one of the source files,
because rustpkg
infers it from the version control system.
When building a package that is in a git
repository,
rustpkg
assumes that the most recent tag specifies the current version.
When building a package that is not under version control,
or that has no tags, rustpkg
assumes the intended version is 0.1.
Note: A future version of rustpkg will support semantic versions. Also, a future version will add the option to specify a version with a metadata attribute like
#[link(vers = "3.1415")]
inside the crate module, though this attribute will never be mandatory.
Dependencies
rustpkg infers dependencies from extern mod
directives.
Thus, there should be no need to pass a -L
flag to rustpkg to tell it where to find a library.
(In the future, it will also be possible to write an extern mod
directive referring to a remote package.)
Custom build scripts
A file called pkg.rs
at the root level in a workspace is called a package script.
If a package script exists, rustpkg executes it to build the package
rather than inferring crates as described previously.
Inside pkg.rs
, it's possible to call back into rustpkg to finish up the build.
rustpkg::api
contains functions to build, install, or clean libraries and executables
in the way rustpkg normally would without custom build logic.
Command reference
build
rustpkg build foo
searches for a package with ID foo
and builds it in any workspace(s) where it finds one.
Supposing such packages are found in workspaces X, Y, and Z,
the command leaves behind files in X
's, Y
's, and Z
's build
directories,
but not in their lib
or bin
directories.
(The exception is when rustpkg fetches a package foo
's sources from a remote repository.
In that case, it stores both the sources and the build artifacts for foo
in the workspace that foo
will install to (see ##install below)).
clean
rustpkg clean foo
deletes the contents of foo
's build
directory.
install
rustpkg install foo
builds the libraries and/or executables that are targets for foo
.
If RUST_PATH
is declared as an environment variable, then rustpkg installs the
libraries and executables into the lib
and bin
subdirectories
of the first entry in RUST_PATH
.
Otherwise, if the current working directory CWD is a workspace,
it installs them into CWD's lib
and bin
subdirectories.
Otherwise, if the current working directory is CWD,
it installs them into the .rust/lib and .rust/bin subdirectories of CWD
(creating them if necessary).
test
rustpkg test foo
builds foo
's test.rs
file if necessary,
then runs the resulting test executable.