rustcコマンドについてざっくり調べる
cargo
ではなくrustc
コマンドについて調べる。
背景としては、Rust-for-Linuxのビルドコードを読んでいて、cargoではなくrustcを使っているようなので。cargoはrustcのまあフロントエンドみたいなアレだと理解しているが (例えばcargo build --verbose
すると、実際に実行されている長大なオプション群付きのrustcコマンドが表示される。)、rustc自体を直接知りたくなった。またそういった背景なのでRust-for-Linuxのビルドに使われているオプションが多いかも。
調べる方法は主に2つ。
-
rustc --help -v
を読む。 - The rustc bookを参照する。
$ rustc -vV
rustc 1.68.0-nightly (1e4f90061 2023-01-11)
binary: rustc
commit-hash: 1e4f90061cc4bc566f99ab21b1f101182b10cf0c
commit-date: 2023-01-11
host: x86_64-unknown-linux-gnu
release: 1.68.0-nightly
LLVM version: 15.0.6
基本
rustcコマンドはinputとしてrustファイルを受け取り、それをコンパイルする。
$ rustc ./hello.rs
$ ./hello
Hello!
rustcコマンドにはcrate rootのファイルを渡すだけで良い。moduleの関係も解決してくれる。例えば
mod foo;
fn main() {
foo::hello();
}
というファイルもコンパイルできる。(foo
module = foo.rs
が正しく存在すれば。)
オプション
オプションを調べていく。
--cfg SPEC
#[cfg(...)]
やcfg!(...)
に使うcompilation environmentを設定する。
例えば、
// main.rs
#[cfg(not(hi))]
fn hello() {
println!("hello");
}
#[cfg(hi)]
fn hello() {
println!("hi");
}
fn main() {
hello();
if cfg!(hi) {
println!("cfg == hi");
} else {
println!("cfg != hi");
}
}
$ rustc ./src/main.rs && ./main
hello
cfg != hi
$ rustc --cfg hi ./src/main.rs && ./main
hi
cfg == hi
ref: https://doc.rust-lang.org/rust-by-example/attribute/cfg.html
-L [KIND=]PATH
library search pathを追加する。
--crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]
crate typeを指定する。(bin、lib、proc-macro以外にもたくさんあるなー。)
--crate-name NAME
crateの名前を指定する。
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
出力するファイルのtypeを指定する。
例えば、
$ rustc --emit asm,llvm-ir ./main.rs
とかやるとassemblyやLLVM IRが見れて面白い。
--extern NAME[=PATH]
外部libraryの場所を指定する。(直接の依存だけ指定できる。依存の依存といった、間接的な依存については-L
オプションを使う。)
具体的には列挙された外部libraryの名前はextern preludeに追加されるみたい。preludeについては以前まとめた記事がある。
なおこのオプションについてはrustc --help -v
の情報が少なかったので次のリンクを参照した。
The rustc book: -extern: specify where an external library is located
--sysroot PATH
sysrootのpathを指定する。
sysrootとは
cargo build
すると通常はtarget/debug/deps
にビルドされたものが格納される。しかしここにはstd libなどは含まれない。それではstd
やproc_macro
がどこからくるかというとsysrootである。
実行時にロードする必要があるあらゆるものがsysrootに含まれる。例えば:
libstd
libtest
libproc_macro
libLLVM.so
次のコマンドでsysrootディレクトリのpathが表示される。
$ rustc --print sysroot
/home/ohno/.rustup/toolchains/1.62.0-x86_64-unknown-linux-gnu
sysrootについては次が詳しいのではないかと思う。
rustc-dev-guide: What is a sysroot?
Discussion