Skip to content

Commit a0b9cc6

Browse files
committed
New rustpkg tutorial.
1 parent 0ec4d34 commit a0b9cc6

File tree

2 files changed

+246
-0
lines changed

2 files changed

+246
-0
lines changed

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.

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

0 commit comments

Comments
 (0)