最近学习rust,看到宏展开命令
rustc -Z unstable-options --pretty=expanded main.rs
cargo rustc -- -Z unstable-options --pretty=expanded
于是在我的hello项目中测试了一下,这个演示项目使用cargo创建,里面既有lib又有bin。
% cargo rustc -- -Z unstable-options --pretty=expanded
但是出现了报错,可能是由于软件版本的变更,导致书中的命令不能直接运行,也可能是书中写的是简化示意。
error: extra arguments to `rustc` can only be passed to one target, consider filtering
the package by passing, e.g., `--lib` or `--bin NAME` to specify a single target
根据提示修改
% cargo rustc -- --bin hello -Z unstable-options --pretty=expanded
依然报相同的错误,经过测试发现用下面的方法可以通过。
% cargo rustc --bin hello -- -Z unstable-options --pretty=expanded
这两种写法有什么区别呢,一条命令后面加另一条命令的时候,如果都带有参数,当把前面的命令的参数放到后面的命令的后面的时候就会产生歧义,这个参数到底是谁的,--
是一个通常的约定,--
之后的参数不再解析,也就是说
cmd1 -a -b hello -- cmd2 -c -d -f
-c -d -f 都不会被认为是cmd1的参数,查看c标准库中的参数解析函数的帮助
man getopt
可以看到下面这一行
The special argument "--" forces an end of option-scanning regardless of the scanning mode.
也就是说–被约定成了参数解析的分隔符,为了方便解析程序, 因为解析程序不知道后面有没有加第二个命令,参数的顺序是可以乱序的,如果不加 --
, 解析程序便会认为-c -d -f
也是cmd1的参数,当然理论上可以处理,但是会复杂一些,也会对程序的使用者提出一些要求,而采用了--
分隔约定就简单多了。
再看cargo的帮助
% cargo rustc --help
cargo-rustc
Compile a package, and pass extra options to the compiler
USAGE:
cargo rustc [OPTIONS] [--] [args]...
OPTIONS:
-q, --quiet No output printed to stdout
-p, --package <SPEC> Package to build
-j, --jobs <N> Number of parallel jobs, defaults to
--lib Build only this package's library
--bin <NAME>... Build only the specified binary
--bins Build all binaries
--example <NAME>... Build only the specified example
--examples Build all examples
--test <NAME>... Build only the specified test target
--tests Build all tests
--bench <NAME>... Build only the specified bench target
--benches Build all benches
--all-targets Build all targets
--release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
--features <FEATURES>... Space or comma separated list of features to activate
--all-features Activate all available features
--no-default-features Do not activate the `default` feature
--target <TRIPLE>... Target triple which compiles will be for
--print <INFO> Output compiler information without compiling
--target-dir <DIRECTORY> Directory for all generated artifacts
--manifest-path <PATH> Path to Cargo.toml
--message-format <FMT>... Error format
--unit-graph Output build graph in JSON (unstable)
--ignore-rust-version Ignore `rust-version` specification in packages (unstable)
--future-incompat-report Ouputs a future incompatibility report at the end of the build (unstable)
-v, --verbose Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
--config <KEY=VALUE>... Override a configuration value (unstable)
-Z <FLAG>... Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Prints help information
ARGS:
<args>... Rustc flags
Run `cargo help rustc` for more detailed information.
从帮助中可以看到 --bin
是OPTIONS中的一个,是cargo rustc
的option,而不是rustc的,而usage 明确生命OPTIONS在–的前面,所以正确的用法应该是
% cargo rustc --bin hello -- -Z unstable-options --pretty=expanded
从输出的结果,可以看到
macro_rules! unless {
($arg:expr, $branch:expr) => (
if !$arg { {$branch} ;};
)
}
unless!(1 > 2, 1+2);
已经展开成了
if !(
1 > 2) {
{ 1 + 2 };
};
;
但是只有第一次执行有输出,重复执行却没有输出,除非修改代码或编译参数。群里询问,张汉东老师回答可能是没编译的原因,建议关闭增量编译试试。果然关闭增量编译之后好了。
CARGO_INCREMENTAL=0 cargo rustc --bin hello -- -Z unstable-options --pretty=expanded
本文使用的环境
% uname -a
Linux yiifburj-Aspire-V3-371 5.8.0-55-generic
% cat /etc/issue
Ubuntu 20.04.2 LTS \n \l
% cargo --version
cargo 1.54.0-nightly (e931e4796 2021-05-24)
% rustc --version
rustc 1.54.0-nightly (625d5a693 2021-06-01)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)