Skip to content

Commit f9e7454

Browse files
committed
---
yaml --- r: 80513 b: refs/heads/master c: a0b9cc6 h: refs/heads/master i: 80511: acde26f v: v3
1 parent fe8534b commit f9e7454

File tree

23 files changed

+778
-205
lines changed

23 files changed

+778
-205
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: d0e0c336d081005da157882e95f4bb57f3bd70b8
2+
refs/heads/master: a0b9cc6a8b810b70698b9d5baa4b64de97a80324
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cbd1eefbd350797b783df119fed7956d7e1c74ad
55
refs/heads/try: 71bebebc37fbb229877da88dde13c2f35913bd77

trunk/doc/tutorial-rustpkg.md

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
% Rust Packaging Tutorial
2+
3+
# Introduction
4+
5+
Sharing is caring. Rust comes with a tool, `rustpkg`, which allows you to
6+
package up your Rust code and share it with other people. This tutorial will
7+
get you started on all of the concepts and commands you need to give the gift
8+
of Rust code to someone else.
9+
10+
## Installing External Packages
11+
12+
First, let's try to use an external package somehow. I've made a sample package
13+
called `hello` to demonstrate how to do so. Here's how `hello` is used:
14+
15+
~~~~
16+
extern mod hello;
17+
18+
fn main() {
19+
hello::world();
20+
}
21+
~~~~
22+
23+
Easy! But if you try to compile this, you'll get an error:
24+
25+
~~~~ {.notrust}
26+
$ rustc main.rs
27+
main.rs:1:0: 1:17 error: can't find crate for `hello`
28+
main.rs:1 extern mod hello;
29+
^~~~~~~~~~~~~~~~~
30+
31+
~~~~
32+
33+
This makes sense, as we haven't gotten it from anywhere yet! Luckily for us,
34+
`rustpkg` has an easy way to fetch others' code: the `install` command. It's
35+
used like this:
36+
37+
~~~ {.notrust}
38+
$ rustpkg install fragment
39+
~~~
40+
41+
This will install a package named 'fragment' into your current Rust
42+
environment. I called it 'fragment' in this example because when using it with
43+
an external package like this, it's often a URI fragment. You see, Rust has no
44+
central authority for packages. You can build your own `hello` library if you
45+
want, and that's fine. We'd both host them in different places and different
46+
projects would rely on whichever version they preferred.
47+
48+
To install the `hello` library, simply run this in your terminal:
49+
50+
~~~ {.notrust}
51+
$ rustpkg install github.com/steveklabnik/hello
52+
~~~
53+
54+
You should see a message that looks like this:
55+
56+
~~~ {.notrust}
57+
note: Installed package github.com/steveklabnik/hello-0.1 to /some/path/.rust
58+
~~~
59+
60+
Now, compiling our example should work:
61+
62+
~~~ {.notrust}
63+
$ rustc main.rs
64+
$ ./main
65+
Hello, world.
66+
~~~
67+
68+
Simple! That's all it takes.
69+
70+
## Workspaces
71+
72+
Before we can talk about how to make packages of your own, you have to
73+
understand the big concept with `rustpkg`: workspaces. A 'workspace' is simply
74+
a directory that has certain folders that `rustpkg` expects. Different Rust
75+
projects will go into different workspaces.
76+
77+
A workspace consists of any folder that has the following
78+
directories:
79+
80+
* `src`: The directory where all the source code goes.
81+
* `build`: This directory contains all of the build output.
82+
* `lib`: The directory where any libraries distributed with the package go.
83+
* `bin`: This directory holds any binaries distributed with the package.
84+
85+
There are also default file names you'll want to follow as well:
86+
87+
* `main.rs`: A file that's going to become an executable.
88+
* `lib.rs`: A file that's going to become a library.
89+
90+
## Building your own Package
91+
92+
Now that you've got workspaces down, let's build your own copy of `hello`. Go
93+
to wherever you keep your personal projects, and let's make all of the
94+
directories we'll need. I'll refer to this personal project directory as
95+
`~/src` for the rest of this tutorial.
96+
97+
### Creating neccesary files
98+
99+
~~~ {.notrust}
100+
$ cd ~/src
101+
$ mkdir -p hello/{src/hello,build,lib,bin}
102+
$ cd hello
103+
~~~
104+
105+
Easy enough! Let's do one or two more things that are nice to do:
106+
107+
~~~ {.notrust}
108+
$ git init .
109+
$ cat > README.md
110+
# hello
111+
112+
A simple package for Rust.
113+
114+
## Installation
115+
116+
```
117+
$ rustpkg install github.com/YOUR_USERNAME/hello
118+
```
119+
^D
120+
$ cat > .gitignore
121+
.rust
122+
build
123+
^D
124+
$ git commit -am "Initial commit."
125+
~~~
126+
127+
If you're not familliar with the `cat >` idiom, it will make files with the
128+
text you type insie. Control-D (`^D`) ends the text for the file.
129+
130+
Anyway, we've got a README and a `.gitignore`. Let's talk about that
131+
`.gitignore` for a minute: we are ignoring two directories, `build` and
132+
`.rust`. `build`, as we discussed earlier, is for build artifacts, and we don't
133+
want to check those into a repository. `.rust` is a folder that `rustpkg` uses
134+
to keep track of its own settings, as well as the source code of any other
135+
external packages that this workspace uses. This is where that `rustpkg
136+
install` puts all of its files. Those are also not to go into our repository,
137+
so we ignore it all as well.
138+
139+
Next, let's add a source file:
140+
141+
~~~
142+
#[link(name = "hello",
143+
vers = "0.1.0",
144+
uuid = "0028fbe0-1f1f-11e3-8224-0800200c9a66",
145+
url = "https://github.com/YOUR_USERNAME/hello")];
146+
147+
#[desc = "A hello world Rust package."];
148+
#[license = "MIT"];
149+
#[crate_type = "lib"];
150+
151+
pub fn world() {
152+
println("Hello, world.");
153+
}
154+
~~~
155+
156+
Put this into `src/hello/lib.rs`. Let's talk about each of these attributes:
157+
158+
### Crate attributes for packages
159+
160+
`crate_type` is the simplest: we're building a library here, so we set it to
161+
`"lib"`. If we were making an executable of some kind, we'd set this to `"bin"`
162+
instead.
163+
164+
`license` is equally simple: the license we want this code to have. I chose MIT
165+
here, but you should pick whatever license makes the most sense for you.
166+
167+
`desc` is a description of the package and what it does. This should just be a
168+
sentence or two.
169+
170+
`link` is the big complex attribute here. It's still not too complex: `name` is
171+
the name of the package, and `vers` is the version. If you're building a
172+
library, consider using [Semantic Versioning](http://semver.org/) as your
173+
versioning scheme. Future versions of `rustpkg` will assume SemVer.
174+
175+
`uuid` is simply a unique identifier. You can generate a UUID by visiting [this
176+
page](http://www.famkruithof.net/uuid/uuidgen). Just copy whatever it puts out
177+
into the value for `uuid`. For more on UUIDs, see
178+
[RFC4122](http://www.ietf.org/rfc/rfc4122.txt).
179+
180+
Finally, `url` is a URL where this package is located. Easy.
181+
182+
### Building your package
183+
184+
Building your package is simple:
185+
186+
~~~ {.notrust}
187+
$ rustpkg build hello
188+
~~~
189+
190+
This will compile `src/hello/lib.rs` into a library. After this process
191+
completes, you'll want to check out `build`:
192+
193+
~~~ {.notrust}
194+
$ ls build/x86_64-unknown-linux-gnu/hello/
195+
libhello-ed8619dad9ce7d58-0.1.0.so
196+
~~~
197+
198+
This directory naming structure is called a 'build triple,' and is because I'm
199+
on 64 bit Linux. Yours may differ based on platform.
200+
201+
You'll also notice that `src/hello/lib.rs` turned into
202+
`libhello-ed8619dad9ce7d58-0.1.0.so`. This is a simple combination of the
203+
library name, a hash of its content, and the version.
204+
205+
Now that your library builds, you'll want to commit:
206+
207+
~~~ {.notrust}
208+
$ git add src
209+
$ git commit -m "Adding source code."
210+
~~~
211+
212+
If you're using GitHub, after creating the project, do this:
213+
214+
~~~ {.notrust}
215+
$ git remote add origin [email protected]:YOUR_USERNAME/hello.git
216+
$ git push origin -u master
217+
~~~
218+
219+
Now you can install and use it! Go anywhere else in your filesystem:
220+
221+
~~~ {.notrust}
222+
$ cd ~/src/foo
223+
$ rustpkg install github/YOUR_USERNAME/hello
224+
WARNING: The Rust package manager is experimental and may be unstable
225+
note: Installed package github.com/YOUR_USERNAME/hello-0.1 to /home/yourusername/src/hello/.rust
226+
~~~
227+
228+
That's it!
229+
230+
## More resources
231+
232+
There's a lot more going on with `rustpkg`, this is just to get you started.
233+
Check out [the rustpkg manual](rustpkg.html) for the full details on how to
234+
customize `rustpkg`.
235+
236+
A tag was created on GitHub specifically for `rustpkg`-related issues. You can
237+
[see all the Issues for rustpkg
238+
here](https://github.com/mozilla/rust/issues?direction=desc&labels=A-pkg&sort=created&state=open),
239+
with bugs as well as new feature plans. `rustpkg` is still under development,
240+
and so may be a bit flaky at the moment.
241+
242+
You may also want to check out [this blog
243+
post](http://tim.dreamwidth.org/1820526.html), which contains some of the early
244+
design decisions and justifications.

trunk/doc/tutorial.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,13 +2979,15 @@ tutorials on individual topics.
29792979
* [The foreign function interface][ffi]
29802980
* [Containers and iterators](tutorial-container.html)
29812981
* [Error-handling and Conditions](tutorial-conditions.html)
2982+
* [Packaging up Rust code](rustpkg)
29822983

29832984
There is further documentation on the [wiki], however those tend to be even more out of date as this document.
29842985

29852986
[borrow]: tutorial-borrowed-ptr.html
29862987
[tasks]: tutorial-tasks.html
29872988
[macros]: tutorial-macros.html
29882989
[ffi]: tutorial-ffi.html
2990+
[rustpkg]: tutorial-rustpkg.html
29892991

29902992
[wiki]: https://github.com/mozilla/rust/wiki/Docs
29912993

trunk/src/libextra/fileinput.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ mod test {
433433
}
434434

435435
#[test]
436-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
437436
fn test_make_path_option_vec() {
438437
let strs = [~"some/path",
439438
~"some/other/path"];
@@ -448,7 +447,6 @@ mod test {
448447
}
449448
450449
#[test]
451-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
452450
fn test_fileinput_read_byte() {
453451
let filenames = make_path_option_vec(vec::from_fn(
454452
3,
@@ -479,7 +477,6 @@ mod test {
479477
}
480478
481479
#[test]
482-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
483480
fn test_fileinput_read() {
484481
let filenames = make_path_option_vec(vec::from_fn(
485482
3,
@@ -500,7 +497,6 @@ mod test {
500497
}
501498

502499
#[test]
503-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
504500
fn test_input_vec() {
505501
let mut all_lines = ~[];
506502
let filenames = make_path_option_vec(vec::from_fn(
@@ -524,7 +520,6 @@ mod test {
524520
}
525521

526522
#[test]
527-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
528523
fn test_input_vec_state() {
529524
let filenames = make_path_option_vec(vec::from_fn(
530525
3,
@@ -547,7 +542,6 @@ mod test {
547542
}
548543

549544
#[test]
550-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
551545
fn test_empty_files() {
552546
let filenames = make_path_option_vec(vec::from_fn(
553547
3,
@@ -572,7 +566,6 @@ mod test {
572566
}
573567
574568
#[test]
575-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
576569
fn test_no_trailing_newline() {
577570
let f1 =
578571
Some(Path("tmp/lib-fileinput-test-no-trailing-newline-1.tmp"));
@@ -598,7 +591,6 @@ mod test {
598591
599592
600593
#[test]
601-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
602594
fn test_next_file() {
603595
let filenames = make_path_option_vec(vec::from_fn(
604596
3,
@@ -630,7 +622,6 @@ mod test {
630622
631623
#[test]
632624
#[should_fail]
633-
#[ignore(cfg(windows))] // FIXME(#8810): rt::io::file and windows don't agree
634625
fn test_input_vec_missing_file() {
635626
do input_vec(make_path_option_vec([~"this/file/doesnt/exist"], true)) |line| {
636627
println(line);

0 commit comments

Comments
 (0)