Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Sketch out rustpkg manual #6008

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions doc/rustpkg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
% 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.

# 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 package `bar`,
then `foo/src/bar/main.rs` could be the `main` entry point for
building a `bar` 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 package `bar`,
rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`.
The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`,
where [hash] is a hash of the package ID.
* 'bin/': `rustpkg install` installs executable binaries 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 package `bar`,
rustpkg will install executables for `bar` to
`foo/bin/x86_64-apple-darwin/`.
The executables will have names of the form `foo/bin/x86_64-apple-darwin/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 package `bar` and `foo/src/bar/main.rs` exists,
then `rustpkg build` will create `foo/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`.

## 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.

# 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.

# 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.

## 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`,
and then installs them either into `foo`'s `lib` and `bin` directories,
or into the `lib` and `bin` subdirectories of the first entry in `RUST_PATH`.

## test

`rustpkg test foo` builds `foo`'s `test.rs` file if necessary,
then runs the resulting test executable.
14 changes: 14 additions & 0 deletions mk/docs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ doc/rust.pdf: doc/rust.tex
endif
endif

DOCS += doc/rustpkg.html
doc/rustpkg.html: rustpkg.md doc/version_info.html doc/rust.css doc/manual.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
"$(CFG_PANDOC)" \
--standalone --toc \
--section-divs \
--number-sections \
--from=markdown --to=html \
--css=rust.css \
--css=manual.css \
--include-before-body=doc/version_info.html \
--output=$@

######################################################################
# Node (tutorial related)
######################################################################
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn test_with_ref() {
#[test]
fn test_with_mut_ref() {
let good = ~[1, 2, 3];
let mut v = ~[1, 2];
let v = ~[1, 2];
let c = Cell(v);
do c.with_mut_ref() |v| { v.push(3); }
let v = c.take();
Expand Down
18 changes: 16 additions & 2 deletions src/libcore/char.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand Down Expand Up @@ -234,6 +234,21 @@ pub fn escape_default(c: char) -> ~str {
}
}

/// Returns the amount of bytes this character would need if encoded in utf8
pub fn len_utf8_bytes(c: char) -> uint {
static max_one_b: uint = 128u;
static max_two_b: uint = 2048u;
static max_three_b: uint = 65536u;
static max_four_b: uint = 2097152u;

let code = c as uint;
if code < max_one_b { 1u }
else if code < max_two_b { 2u }
else if code < max_three_b { 3u }
else if code < max_four_b { 4u }
else { fail!(~"invalid character!") }
}

/**
* Compare two chars
*
Expand Down Expand Up @@ -334,7 +349,6 @@ fn test_escape_default() {
assert_eq!(escape_default('\U0001d4b6'), ~"\\U0001d4b6");
}


#[test]
fn test_escape_unicode() {
assert_eq!(escape_unicode('\x00'), ~"\\x00");
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/core.rc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ pub mod vec;
pub mod at_vec;
pub mod str;

#[path = "str/ascii.rs"]
pub mod ascii;

pub mod ptr;
pub mod owned;
pub mod managed;
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/flate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
let outsz : size_t = 0;
let res =
rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
len as size_t,
Expand Down
18 changes: 14 additions & 4 deletions src/libcore/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ pub trait GenericPath {
fn is_restricted(&self) -> bool;

fn normalize(&self) -> Self;

fn is_absolute(&self) -> bool;
}

#[cfg(windows)]
Expand Down Expand Up @@ -379,10 +381,11 @@ impl ToStr for PosixPath {
// FIXME (#3227): when default methods in traits are working, de-duplicate
// PosixPath and WindowsPath, most of their methods are common.
impl GenericPath for PosixPath {

fn from_str(s: &str) -> PosixPath {
let mut components = ~[];
for str::each_split_nonempty(s, |c| c == '/') |s| { components.push(s.to_owned()) }
for str::each_split_nonempty(s, |c| c == '/') |s| {
components.push(s.to_owned())
}
let is_absolute = (s.len() != 0 && s[0] == '/' as u8);
return PosixPath { is_absolute: is_absolute,
components: components }
Expand Down Expand Up @@ -540,6 +543,10 @@ impl GenericPath for PosixPath {
// ..self
}
}

fn is_absolute(&self) -> bool {
self.is_absolute
}
}


Expand All @@ -563,7 +570,6 @@ impl ToStr for WindowsPath {


impl GenericPath for WindowsPath {

fn from_str(s: &str) -> WindowsPath {
let host;
let device;
Expand Down Expand Up @@ -809,6 +815,10 @@ impl GenericPath for WindowsPath {
components: normalize(self.components)
}
}

fn is_absolute(&self) -> bool {
self.is_absolute
}
}


Expand Down Expand Up @@ -844,7 +854,7 @@ pub mod windows {
while i < s.len() {
if is_sep(s[i]) {
let pre = s.slice(2, i).to_owned();
let mut rest = s.slice(i, s.len()).to_owned();
let rest = s.slice(i, s.len()).to_owned();
return Some((pre, rest));
}
i += 1;
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ pub use path::Path;
pub use path::PosixPath;
pub use path::WindowsPath;
pub use ptr::Ptr;
pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
pub use str::{StrSlice, OwnedStr};
pub use to_bytes::IterBytes;
pub use to_str::ToStr;
pub use to_str::{ToStr, ToStrConsume};
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use vec::{CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ struct XorShiftState {
impl Rng for XorShiftState {
fn next(&self) -> u32 {
let x = self.x;
let mut t = x ^ (x << 11);
let t = x ^ (x << 11);
self.x = self.y;
self.y = self.z;
self.z = self.w;
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub impl ReprVisitor {
#[inline(always)]
fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
unsafe {
let mut u = ReprVisitor(ptr, self.writer);
let u = ReprVisitor(ptr, self.writer);
let v = reflect::MovePtrAdaptor(u);
visit_tydesc(inner, @v as @TyVisitor);
true
Expand Down Expand Up @@ -667,7 +667,7 @@ pub fn write_repr<T>(writer: @Writer, object: &T) {
unsafe {
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
let tydesc = intrinsic::get_tydesc::<T>();
let mut u = ReprVisitor(ptr, writer);
let u = ReprVisitor(ptr, writer);
let v = reflect::MovePtrAdaptor(u);
visit_tydesc(tydesc, @v as @TyVisitor)
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ fn loop_smoke_test() {
fn idle_new_then_close() {
do run_in_bare_thread {
let mut loop_ = Loop::new();
let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
let idle_watcher = { IdleWatcher::new(&mut loop_) };
idle_watcher.close();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uv/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ fn connect_read() {
let buf = vec_from_uv_buf(buf);
rtdebug!("read cb!");
if status.is_none() {
let bytes = buf.unwrap();
let _bytes = buf.unwrap();
rtdebug!("%s", bytes.slice(0, nread as uint).to_str());
} else {
rtdebug!("status after read: %s", status.get().to_str());
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uvio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl TcpListener for UvTcpListener {
let mut server_stream_watcher = server_stream_watcher;
let mut loop_ = loop_from_watcher(&server_stream_watcher);
let mut client_tcp_watcher = TcpWatcher::new(&mut loop_);
let mut client_tcp_watcher = client_tcp_watcher.as_stream();
let client_tcp_watcher = client_tcp_watcher.as_stream();
// XXX: Need's to be surfaced in interface
server_stream_watcher.accept(client_tcp_watcher);
Some(~UvStream::new(client_tcp_watcher))
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
fn force_destroy(&mut self) { destroy_repr(&mut self.r, true); }
}

let mut repr = ProgRepr {
let repr = ProgRepr {
pid: pid,
in_fd: pipe_input.out,
out_file: os::fdopen(pipe_output.in),
Expand Down
Loading