Build your project

栏目: IT技术 · 发布时间: 5年前

内容简介:What if you could build a Rust project without Cargo? It's not an actual problem I encountered. It's still a problem I looked into.Cargo is the Rust package manager. Cargo downloads your Rust package’s dependencies, compiles your packages, makes distributa

Tags: rust

What if you could build a Rust project without Cargo? It's not an actual problem I encountered. It's still a problem I looked into.

Cargo is the Rust package manager. Cargo downloads your Rust package’s dependencies, compiles your packages, makes distributable packages, and uploads them to crates.io, the Rust community’s package registry.

(from the Cargo Book )

That's a lot of work this tool does and it's very good at doing it.

I wanted to understand just the bit where it takes your Rust code and builds that into a binary that you can execute and run on your machine. I didn't really want to read all of Cargo, so instead I turned to what Cargo itself tells me. So I took the output of cargo build --verbose and turned that into simple build instructions.

What does it look like?

$ cargo build --verbose
[...]
   Compiling smallvec v1.4.0
   Compiling matches v0.1.8
   Compiling libc v0.2.71
     Running `rustc --crate-name smallvec --edition=2018 /Users/jer/.cargo/registry/src/github.com-1ecc6299db9ec823/smallvec-1.4.0/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 -C metadata=d85954c5ff803feb -C extra-filename=-d85954c5ff803feb --out-dir /Users/jer/projects/rust/bygge/target/debug/deps -L dependency=/Users/jer/projects/rust/bygge/target/debug/deps --cap-lints allow`
     Running `rustc --crate-name libc /Users/jer/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.71/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="std"' -C metadata=bbaef975a82234c8 -C extra-filename=-bbaef975a82234c8 --out-dir /Users/jer/projects/rust/bygge/target/debug/deps -L dependency=/Users/jer/projects/rust/bygge/target/debug/deps --cap-lints allow --cfg freebsd11 --cfg libc_priv_mod_use --cfg libc_union --cfg libc_const_size_of --cfg libc_align --cfg libc_core_cvoid --cfg libc_packedN`
[...]
     Running `rustc --crate-name bygge --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=c1c12e33a54c5b24 -C extra-filename=-c1c12e33a54c5b24 --out-dir /Users/jer/projects/rust/bygge/target/debug/deps -C incremental=/Users/jer/projects/rust/bygge/target/debug/incremental -L dependency=/Users/jer/projects/rust/bygge/target/debug/deps --extern cargo_lock=/Users/jer/projects/rust/bygge/target/debug/deps/libcargo_lock-43ce509885ad1aff.rlib --extern cargo_toml=/Users/jer/projects/rust/bygge/target/debug/deps/libcargo_toml-5b6fff58e6c9a546.rlib --extern dirs=/Users/jer/projects/rust/bygge/target/debug/deps/libdirs-4eb870f2ccf6ed43.rlib --extern petgraph=/Users/jer/projects/rust/bygge/target/debug/deps/libpetgraph-7cb995dcfae4c1f7.rlib --extern pico_args=/Users/jer/projects/rust/bygge/target/debug/deps/libpico_args-03badf8072a773d9.rlib`
    Finished dev [unoptimized + debuginfo] target(s) in 30.82s

I removed a bunch of the output, but it all boils down to the same. You can re-run these commands and you should end up with the same binary as the one Cargo puts into target/debug/ .

You could put them all in a Makefile and use that to re-run them, but you would have gained nothing. Changing your own code or adding, removing or updating dependencies won't be picked up unless you carefully specify all these dependencies in the Makefile and update them when something changes.

We can automate that part.

Lately (again) I've been also reading about other build systems, such as Ninja and was intrigued to rebuild that. I haven't done that yet, but I decided to generate Ninja configuration to see how it behaves.

Let's combine these two things.

The basic manual version

Let's work from a basic binary crate, with no dependencies and a single file.

$ cargo new --bin hello-world
     Created binary (application) `hello-world` package
$ cat
fn main() {
    println!("Hello, world!");
}

Building just that is easy:

$ rustc src/main.rs -o hello-world
$ ./hello-world
Hello, world!

If we rerun rustc it will re-build the code and generate a new file hello-world (that should be the same as the one from the first invocation). That's a bit of extra work; if nothing changed we shouldn't need to rebuild. Let's create a Ninja configuration file build.ninja :

# The build rule to invoke rustc.
# $in and $out are variables provided by ninja.
rule rustc
  command = rustc $in -o $out
  description = RUSTC $out

# Specifying dependencies:
# For `hello-world` to be build we invoke the above `rustc` rule with `src/main.rs` as $in
build hello-world: rustc src/main.rs

With Ninja installed we can build and run this:

$ ninja
[1/1] RUSTC hello-world
$ ./hello-world
Hello, world!

Re-running Ninja won't build it again:

$ ninja
ninja: no work to do.

Ninja knows that nothing changed and thus skips extra work. If we modify the source it rebuilds:

$ echo >> src/main.rs
$ ninja
[1/1] RUSTC hello-world
$ ./hello-world
Hello, world!

We don't gain anything if we keep continuing writing a Ninja build configuration from hand. Especially not once we add more files and some external crates.

Bygge - build your project

Instead of writing out the whole Ninja file, or coming up with some rules for Make that expand to the right files, we can generate the build configuration once and then not touch it again until something changes. That's exactly what Ninja was designed for:

it is designed to have its input files generated by a higher-level build system, [...]

(from the Ninja Website )

After some more exploration with Cargo and the command lines it produces and the files it creates I managed to more-or-less auto-generate a Ninja configuration for a crate.

I've published this experiment as bygge , the crate to build your crates (and itself).

What it does

bygge create generates a Ninja build configuration (in build.ninja by default), listing all the targets a binary crate depends on, including all crate dependencies. ninja can then take this configuration and assemble the final binary. The result should be about the same as an invocation of cargo build .

What it doesn't

bygge is and never will be an alternative to Cargo. Cargo is a full-fledged build system, aware of different build targets, allowing to enable features per dependency, easily cross-compile to different targets and run the built programs as well as tests and generate documentation.

bygge ... builds.

Features

build.rs
cargo fetch

Building bygge

Bygge is able to create a Ninja build configuration to build itself. But first you need a compiled bygge . It comes with a pre-generated configuration for that, that only works on my machine unless you change the paths to the local checkouts of the dependencies.

$ ninja -f manual.ninja
[29/29] RUSTC build/bygge

It builds a build/bygge file that is able to create the build configuration and run Ninja:

$ build/bygge create
==> Creating build file: build.ninja
==> Package: bygge
$ build/bygge build
[29/29] RUSTC build/bygge
$ build/bygge -V
bygge v0.1.0

You can also build it using cargo build and use cargo run create (or target/debug/bygge create ) to create the build.ninja file.

And there you have it: a 300-line Ninja build configuration to build bygge.


以上所述就是小编给大家介绍的《Build your project》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

不是为了快乐

不是为了快乐

宗萨蒋扬钦哲仁波切 / 姚仁喜 / 深圳报业集团出版社 / 2013-1 / 38.00元

前行修持是一套完整的实修系统,它既是一切佛法修持的根基,又囊括了所有修持的精华,以及心灵之道上所需的一切;既适合入门者打造学佛基本功,也是修行人需要终生修持的心法。书中除了实际的方法指导之外,还不断启发佛法的珍贵与修持的必要,并处处可见对学佛者的鼓舞和纠正,其最终的用心,是让我们踏上不间断的修持之路,真正转化我们僵硬、散乱和困惑的心。 在现代人看来,快乐,理应是最值得追求的目标。我们希望生活......一起来看看 《不是为了快乐》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具