From a0b9cc6a8b810b70698b9d5baa4b64de97a80324 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 16 Sep 2013 16:30:49 -0700 Subject: [PATCH] New rustpkg tutorial. --- doc/tutorial-rustpkg.md | 244 ++++++++++++++++++++++++++++++++++++++++ doc/tutorial.md | 2 + 2 files changed, 246 insertions(+) create mode 100644 doc/tutorial-rustpkg.md diff --git a/doc/tutorial-rustpkg.md b/doc/tutorial-rustpkg.md new file mode 100644 index 0000000000000..d419317745be3 --- /dev/null +++ b/doc/tutorial-rustpkg.md @@ -0,0 +1,244 @@ +% Rust Packaging Tutorial + +# Introduction + +Sharing is caring. Rust comes with a tool, `rustpkg`, which allows you to +package up your Rust code and share it with other people. This tutorial will +get you started on all of the concepts and commands you need to give the gift +of Rust code to someone else. + +## Installing External Packages + +First, let's try to use an external package somehow. I've made a sample package +called `hello` to demonstrate how to do so. Here's how `hello` is used: + +~~~~ +extern mod hello; + +fn main() { + hello::world(); +} +~~~~ + +Easy! But if you try to compile this, you'll get an error: + +~~~~ {.notrust} +$ rustc main.rs +main.rs:1:0: 1:17 error: can't find crate for `hello` +main.rs:1 extern mod hello; + ^~~~~~~~~~~~~~~~~ + +~~~~ + +This makes sense, as we haven't gotten it from anywhere yet! Luckily for us, +`rustpkg` has an easy way to fetch others' code: the `install` command. It's +used like this: + +~~~ {.notrust} +$ rustpkg install fragment +~~~ + +This will install a package named 'fragment' into your current Rust +environment. I called it 'fragment' in this example because when using it with +an external package like this, it's often a URI fragment. You see, Rust has no +central authority for packages. You can build your own `hello` library if you +want, and that's fine. We'd both host them in different places and different +projects would rely on whichever version they preferred. + +To install the `hello` library, simply run this in your terminal: + +~~~ {.notrust} +$ rustpkg install github.com/steveklabnik/hello +~~~ + +You should see a message that looks like this: + +~~~ {.notrust} +note: Installed package github.com/steveklabnik/hello-0.1 to /some/path/.rust +~~~ + +Now, compiling our example should work: + +~~~ {.notrust} +$ rustc main.rs +$ ./main +Hello, world. +~~~ + +Simple! That's all it takes. + +## Workspaces + +Before we can talk about how to make packages of your own, you have to +understand the big concept with `rustpkg`: workspaces. A 'workspace' is simply +a directory that has certain folders that `rustpkg` expects. Different Rust +projects will go into different workspaces. + +A workspace consists of any folder that has the following +directories: + +* `src`: The directory where all the source code goes. +* `build`: This directory contains all of the build output. +* `lib`: The directory where any libraries distributed with the package go. +* `bin`: This directory holds any binaries distributed with the package. + +There are also default file names you'll want to follow as well: + +* `main.rs`: A file that's going to become an executable. +* `lib.rs`: A file that's going to become a library. + +## Building your own Package + +Now that you've got workspaces down, let's build your own copy of `hello`. Go +to wherever you keep your personal projects, and let's make all of the +directories we'll need. I'll refer to this personal project directory as +`~/src` for the rest of this tutorial. + +### Creating neccesary files + +~~~ {.notrust} +$ cd ~/src +$ mkdir -p hello/{src/hello,build,lib,bin} +$ cd hello +~~~ + +Easy enough! Let's do one or two more things that are nice to do: + +~~~ {.notrust} +$ git init . +$ cat > README.md +# hello + +A simple package for Rust. + +## Installation + +``` +$ rustpkg install github.com/YOUR_USERNAME/hello +``` +^D +$ cat > .gitignore +.rust +build +^D +$ git commit -am "Initial commit." +~~~ + +If you're not familliar with the `cat >` idiom, it will make files with the +text you type insie. Control-D (`^D`) ends the text for the file. + +Anyway, we've got a README and a `.gitignore`. Let's talk about that +`.gitignore` for a minute: we are ignoring two directories, `build` and +`.rust`. `build`, as we discussed earlier, is for build artifacts, and we don't +want to check those into a repository. `.rust` is a folder that `rustpkg` uses +to keep track of its own settings, as well as the source code of any other +external packages that this workspace uses. This is where that `rustpkg +install` puts all of its files. Those are also not to go into our repository, +so we ignore it all as well. + +Next, let's add a source file: + +~~~ +#[link(name = "hello", + vers = "0.1.0", + uuid = "0028fbe0-1f1f-11e3-8224-0800200c9a66", + url = "https://github.com/YOUR_USERNAME/hello")]; + +#[desc = "A hello world Rust package."]; +#[license = "MIT"]; +#[crate_type = "lib"]; + +pub fn world() { + println("Hello, world."); +} +~~~ + +Put this into `src/hello/lib.rs`. Let's talk about each of these attributes: + +### Crate attributes for packages + +`crate_type` is the simplest: we're building a library here, so we set it to +`"lib"`. If we were making an executable of some kind, we'd set this to `"bin"` +instead. + +`license` is equally simple: the license we want this code to have. I chose MIT +here, but you should pick whatever license makes the most sense for you. + +`desc` is a description of the package and what it does. This should just be a +sentence or two. + +`link` is the big complex attribute here. It's still not too complex: `name` is +the name of the package, and `vers` is the version. If you're building a +library, consider using [Semantic Versioning](http://semver.org/) as your +versioning scheme. Future versions of `rustpkg` will assume SemVer. + +`uuid` is simply a unique identifier. You can generate a UUID by visiting [this +page](http://www.famkruithof.net/uuid/uuidgen). Just copy whatever it puts out +into the value for `uuid`. For more on UUIDs, see +[RFC4122](http://www.ietf.org/rfc/rfc4122.txt). + +Finally, `url` is a URL where this package is located. Easy. + +### Building your package + +Building your package is simple: + +~~~ {.notrust} +$ rustpkg build hello +~~~ + +This will compile `src/hello/lib.rs` into a library. After this process +completes, you'll want to check out `build`: + +~~~ {.notrust} +$ ls build/x86_64-unknown-linux-gnu/hello/ +libhello-ed8619dad9ce7d58-0.1.0.so +~~~ + +This directory naming structure is called a 'build triple,' and is because I'm +on 64 bit Linux. Yours may differ based on platform. + +You'll also notice that `src/hello/lib.rs` turned into +`libhello-ed8619dad9ce7d58-0.1.0.so`. This is a simple combination of the +library name, a hash of its content, and the version. + +Now that your library builds, you'll want to commit: + +~~~ {.notrust} +$ git add src +$ git commit -m "Adding source code." +~~~ + +If you're using GitHub, after creating the project, do this: + +~~~ {.notrust} +$ git remote add origin git@github.com:YOUR_USERNAME/hello.git +$ git push origin -u master +~~~ + +Now you can install and use it! Go anywhere else in your filesystem: + +~~~ {.notrust} +$ cd ~/src/foo +$ rustpkg install github/YOUR_USERNAME/hello +WARNING: The Rust package manager is experimental and may be unstable +note: Installed package github.com/YOUR_USERNAME/hello-0.1 to /home/yourusername/src/hello/.rust +~~~ + +That's it! + +## More resources + +There's a lot more going on with `rustpkg`, this is just to get you started. +Check out [the rustpkg manual](rustpkg.html) for the full details on how to +customize `rustpkg`. + +A tag was created on GitHub specifically for `rustpkg`-related issues. You can +[see all the Issues for rustpkg +here](https://github.com/mozilla/rust/issues?direction=desc&labels=A-pkg&sort=created&state=open), +with bugs as well as new feature plans. `rustpkg` is still under development, +and so may be a bit flaky at the moment. + +You may also want to check out [this blog +post](http://tim.dreamwidth.org/1820526.html), which contains some of the early +design decisions and justifications. diff --git a/doc/tutorial.md b/doc/tutorial.md index 637dbb10c2355..7a9bb4adf65e3 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2979,6 +2979,7 @@ tutorials on individual topics. * [The foreign function interface][ffi] * [Containers and iterators](tutorial-container.html) * [Error-handling and Conditions](tutorial-conditions.html) +* [Packaging up Rust code](rustpkg) There is further documentation on the [wiki], however those tend to be even more out of date as this document. @@ -2986,6 +2987,7 @@ There is further documentation on the [wiki], however those tend to be even more [tasks]: tutorial-tasks.html [macros]: tutorial-macros.html [ffi]: tutorial-ffi.html +[rustpkg]: tutorial-rustpkg.html [wiki]: https://github.com/mozilla/rust/wiki/Docs