Simplify command-line-option declarations in the compiler
This commit is contained in:
parent
584c8200de
commit
001013c63c
@ -12,7 +12,7 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::{fmt, fs, iter};
|
use std::{cmp, fmt, fs, iter};
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||||
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
|
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
|
||||||
@ -1367,11 +1367,36 @@ pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
enum OptionStability {
|
pub enum OptionStability {
|
||||||
Stable,
|
Stable,
|
||||||
Unstable,
|
Unstable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub enum OptionKind {
|
||||||
|
/// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
|
||||||
|
///
|
||||||
|
/// Corresponds to [`getopts::Options::optopt`].
|
||||||
|
Opt,
|
||||||
|
|
||||||
|
/// An option that takes a value, and can appear multiple times (e.g. `--emit`).
|
||||||
|
///
|
||||||
|
/// Corresponds to [`getopts::Options::optmulti`].
|
||||||
|
Multi,
|
||||||
|
|
||||||
|
/// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
|
||||||
|
///
|
||||||
|
/// Corresponds to [`getopts::Options::optflag`].
|
||||||
|
/// The `hint` string must be empty.
|
||||||
|
Flag,
|
||||||
|
|
||||||
|
/// An option that does not take a value, and can appear multiple times (e.g. `-O`).
|
||||||
|
///
|
||||||
|
/// Corresponds to [`getopts::Options::optflagmulti`].
|
||||||
|
/// The `hint` string must be empty.
|
||||||
|
FlagMulti,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct RustcOptGroup {
|
pub struct RustcOptGroup {
|
||||||
apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
|
apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
@ -1402,58 +1427,37 @@ pub fn unstable<F>(name: &'static str, f: F) -> RustcOptGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `opt` local module holds wrappers around the `getopts` API that
|
pub fn make_opt(
|
||||||
// adds extra rustc-specific metadata to each option; such metadata
|
stability: OptionStability,
|
||||||
// is exposed by . The public
|
kind: OptionKind,
|
||||||
// functions below ending with `_u` are the functions that return
|
short_name: &'static str,
|
||||||
// *unstable* options, i.e., options that are only enabled when the
|
long_name: &'static str,
|
||||||
// user also passes the `-Z unstable-options` debugging flag.
|
desc: &'static str,
|
||||||
mod opt {
|
hint: &'static str,
|
||||||
// The `fn flag*` etc below are written so that we can use them
|
) -> RustcOptGroup {
|
||||||
// in the future; do not warn about them not being used right now.
|
RustcOptGroup {
|
||||||
#![allow(dead_code)]
|
name: cmp::max_by_key(short_name, long_name, |s| s.len()),
|
||||||
|
stability,
|
||||||
use super::RustcOptGroup;
|
apply: match kind {
|
||||||
|
OptionKind::Opt => Box::new(move |opts: &mut getopts::Options| {
|
||||||
type R = RustcOptGroup;
|
opts.optopt(short_name, long_name, desc, hint)
|
||||||
type S = &'static str;
|
}),
|
||||||
|
OptionKind::Multi => Box::new(move |opts: &mut getopts::Options| {
|
||||||
fn stable<F>(name: S, f: F) -> R
|
opts.optmulti(short_name, long_name, desc, hint)
|
||||||
where
|
}),
|
||||||
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
|
OptionKind::Flag => {
|
||||||
{
|
assert_eq!(hint, "");
|
||||||
RustcOptGroup::stable(name, f)
|
Box::new(move |opts: &mut getopts::Options| {
|
||||||
}
|
opts.optflag(short_name, long_name, desc)
|
||||||
|
})
|
||||||
fn unstable<F>(name: S, f: F) -> R
|
}
|
||||||
where
|
OptionKind::FlagMulti => {
|
||||||
F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
|
assert_eq!(hint, "");
|
||||||
{
|
Box::new(move |opts: &mut getopts::Options| {
|
||||||
RustcOptGroup::unstable(name, f)
|
opts.optflagmulti(short_name, long_name, desc)
|
||||||
}
|
})
|
||||||
|
}
|
||||||
fn longer(a: S, b: S) -> S {
|
},
|
||||||
if a.len() > b.len() { a } else { b }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn opt_s(a: S, b: S, c: S, d: S) -> R {
|
|
||||||
stable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
|
|
||||||
}
|
|
||||||
pub(crate) fn multi_s(a: S, b: S, c: S, d: S) -> R {
|
|
||||||
stable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
|
|
||||||
}
|
|
||||||
pub(crate) fn flag_s(a: S, b: S, c: S) -> R {
|
|
||||||
stable(longer(a, b), move |opts| opts.optflag(a, b, c))
|
|
||||||
}
|
|
||||||
pub(crate) fn flagmulti_s(a: S, b: S, c: S) -> R {
|
|
||||||
stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opt(a: S, b: S, c: S, d: S) -> R {
|
|
||||||
unstable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
|
|
||||||
}
|
|
||||||
pub(crate) fn multi(a: S, b: S, c: S, d: S) -> R {
|
|
||||||
unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1468,46 +1472,60 @@ pub(crate) fn multi(a: S, b: S, c: S, d: S) -> R {
|
|||||||
/// including metadata for each option, such as whether the option is
|
/// including metadata for each option, such as whether the option is
|
||||||
/// part of the stable long-term interface for rustc.
|
/// part of the stable long-term interface for rustc.
|
||||||
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
||||||
|
use OptionKind::{Flag, FlagMulti, Multi, Opt};
|
||||||
|
use OptionStability::Stable;
|
||||||
|
|
||||||
|
use self::make_opt as opt;
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
opt::flag_s("h", "help", "Display this message"),
|
opt(Stable, Flag, "h", "help", "Display this message", ""),
|
||||||
opt::multi_s("", "cfg", "Configure the compilation environment.
|
opt(
|
||||||
SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"),
|
Stable,
|
||||||
opt::multi_s("", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
|
Multi,
|
||||||
opt::multi_s(
|
"",
|
||||||
|
"cfg",
|
||||||
|
"Configure the compilation environment.\n\
|
||||||
|
SPEC supports the syntax `NAME[=\"VALUE\"]`.",
|
||||||
|
"SPEC",
|
||||||
|
),
|
||||||
|
opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
|
||||||
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"L",
|
"L",
|
||||||
"",
|
"",
|
||||||
"Add a directory to the library search path. The
|
"Add a directory to the library search path. \
|
||||||
optional KIND can be one of dependency, crate, native,
|
The optional KIND can be one of dependency, crate, native, framework, or all (the default).",
|
||||||
framework, or all (the default).",
|
|
||||||
"[KIND=]PATH",
|
"[KIND=]PATH",
|
||||||
),
|
),
|
||||||
opt::multi_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"l",
|
"l",
|
||||||
"",
|
"",
|
||||||
"Link the generated crate(s) to the specified native
|
"Link the generated crate(s) to the specified native\n\
|
||||||
library NAME. The optional KIND can be one of
|
library NAME. The optional KIND can be one of\n\
|
||||||
static, framework, or dylib (the default).
|
static, framework, or dylib (the default).\n\
|
||||||
Optional comma separated MODIFIERS (bundle|verbatim|whole-archive|as-needed)
|
Optional comma separated MODIFIERS\n\
|
||||||
may be specified each with a prefix of either '+' to
|
(bundle|verbatim|whole-archive|as-needed)\n\
|
||||||
enable or '-' to disable.",
|
may be specified each with a prefix of either '+' to\n\
|
||||||
|
enable or '-' to disable.",
|
||||||
"[KIND[:MODIFIERS]=]NAME[:RENAME]",
|
"[KIND[:MODIFIERS]=]NAME[:RENAME]",
|
||||||
),
|
),
|
||||||
make_crate_type_option(),
|
make_crate_type_option(),
|
||||||
opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"),
|
opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "NAME"),
|
||||||
opt::opt_s(
|
opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
|
||||||
"",
|
opt(
|
||||||
"edition",
|
Stable,
|
||||||
&EDITION_STRING,
|
Multi,
|
||||||
EDITION_NAME_LIST,
|
|
||||||
),
|
|
||||||
opt::multi_s(
|
|
||||||
"",
|
"",
|
||||||
"emit",
|
"emit",
|
||||||
"Comma separated list of types of output for \
|
"Comma separated list of types of output for the compiler to emit",
|
||||||
the compiler to emit",
|
|
||||||
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
|
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
|
||||||
),
|
),
|
||||||
opt::multi_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"",
|
"",
|
||||||
"print",
|
"print",
|
||||||
"Compiler information to print on stdout",
|
"Compiler information to print on stdout",
|
||||||
@ -1516,41 +1534,36 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
|||||||
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
|
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
|
||||||
stack-protector-strategies|link-args|deployment-target]",
|
stack-protector-strategies|link-args|deployment-target]",
|
||||||
),
|
),
|
||||||
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
|
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
|
||||||
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
|
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=2", ""),
|
||||||
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
|
opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
|
||||||
opt::opt_s(
|
opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
|
||||||
"",
|
opt(
|
||||||
"out-dir",
|
Stable,
|
||||||
"Write output to compiler-chosen filename \
|
Opt,
|
||||||
in <dir>",
|
|
||||||
"DIR",
|
|
||||||
),
|
|
||||||
opt::opt_s(
|
|
||||||
"",
|
"",
|
||||||
"explain",
|
"explain",
|
||||||
"Provide a detailed explanation of an error \
|
"Provide a detailed explanation of an error message",
|
||||||
message",
|
|
||||||
"OPT",
|
"OPT",
|
||||||
),
|
),
|
||||||
opt::flag_s("", "test", "Build a test harness"),
|
opt(Stable, Flag, "", "test", "Build a test harness", ""),
|
||||||
opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
|
opt(Stable, Opt, "", "target", "Target triple for which the code is compiled", "TARGET"),
|
||||||
opt::multi_s("A", "allow", "Set lint allowed", "LINT"),
|
opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
|
||||||
opt::multi_s("W", "warn", "Set lint warnings", "LINT"),
|
opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
|
||||||
opt::multi_s("", "force-warn", "Set lint force-warn", "LINT"),
|
opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
|
||||||
opt::multi_s("D", "deny", "Set lint denied", "LINT"),
|
opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
|
||||||
opt::multi_s("F", "forbid", "Set lint forbidden", "LINT"),
|
opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
|
||||||
opt::multi_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"",
|
"",
|
||||||
"cap-lints",
|
"cap-lints",
|
||||||
"Set the most restrictive lint level. \
|
"Set the most restrictive lint level. More restrictive lints are capped at this level",
|
||||||
More restrictive lints are capped at this \
|
|
||||||
level",
|
|
||||||
"LEVEL",
|
"LEVEL",
|
||||||
),
|
),
|
||||||
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
|
opt(Stable, Multi, "C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
|
||||||
opt::flag_s("V", "version", "Print version info and exit"),
|
opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
|
||||||
opt::flag_s("v", "verbose", "Use verbose output"),
|
opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,25 +1571,36 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
|||||||
/// each option, such as whether the option is part of the stable
|
/// each option, such as whether the option is part of the stable
|
||||||
/// long-term interface for rustc.
|
/// long-term interface for rustc.
|
||||||
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
||||||
|
use OptionKind::{Multi, Opt};
|
||||||
|
use OptionStability::{Stable, Unstable};
|
||||||
|
|
||||||
|
use self::make_opt as opt;
|
||||||
|
|
||||||
let mut opts = rustc_short_optgroups();
|
let mut opts = rustc_short_optgroups();
|
||||||
// FIXME: none of these descriptions are actually used
|
// FIXME: none of these descriptions are actually used
|
||||||
opts.extend(vec![
|
opts.extend(vec![
|
||||||
opt::multi_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"",
|
"",
|
||||||
"extern",
|
"extern",
|
||||||
"Specify where an external rust library is located",
|
"Specify where an external rust library is located",
|
||||||
"NAME[=PATH]",
|
"NAME[=PATH]",
|
||||||
),
|
),
|
||||||
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
|
opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
|
||||||
opt::multi("Z", "", "Set unstable / perma-unstable options", "FLAG"),
|
opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "FLAG"),
|
||||||
opt::opt_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Opt,
|
||||||
"",
|
"",
|
||||||
"error-format",
|
"error-format",
|
||||||
"How errors and other messages are produced",
|
"How errors and other messages are produced",
|
||||||
"human|json|short",
|
"human|json|short",
|
||||||
),
|
),
|
||||||
opt::multi_s("", "json", "Configure the JSON output of the compiler", "CONFIG"),
|
opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "CONFIG"),
|
||||||
opt::opt_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Opt,
|
||||||
"",
|
"",
|
||||||
"color",
|
"color",
|
||||||
"Configure coloring of output:
|
"Configure coloring of output:
|
||||||
@ -1585,19 +1609,23 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
|||||||
never = never colorize output",
|
never = never colorize output",
|
||||||
"auto|always|never",
|
"auto|always|never",
|
||||||
),
|
),
|
||||||
opt::opt_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Opt,
|
||||||
"",
|
"",
|
||||||
"diagnostic-width",
|
"diagnostic-width",
|
||||||
"Inform rustc of the width of the output so that diagnostics can be truncated to fit",
|
"Inform rustc of the width of the output so that diagnostics can be truncated to fit",
|
||||||
"WIDTH",
|
"WIDTH",
|
||||||
),
|
),
|
||||||
opt::multi_s(
|
opt(
|
||||||
|
Stable,
|
||||||
|
Multi,
|
||||||
"",
|
"",
|
||||||
"remap-path-prefix",
|
"remap-path-prefix",
|
||||||
"Remap source names in all output (compiler messages and output files)",
|
"Remap source names in all output (compiler messages and output files)",
|
||||||
"FROM=TO",
|
"FROM=TO",
|
||||||
),
|
),
|
||||||
opt::multi("", "env-set", "Inject an environment variable", "VAR=VALUE"),
|
opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "VAR=VALUE"),
|
||||||
]);
|
]);
|
||||||
opts
|
opts
|
||||||
}
|
}
|
||||||
@ -2760,7 +2788,9 @@ fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> O
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_crate_type_option() -> RustcOptGroup {
|
pub fn make_crate_type_option() -> RustcOptGroup {
|
||||||
opt::multi_s(
|
make_opt(
|
||||||
|
OptionStability::Stable,
|
||||||
|
OptionKind::Multi,
|
||||||
"",
|
"",
|
||||||
"crate-type",
|
"crate-type",
|
||||||
"Comma separated list of types of crates
|
"Comma separated list of types of crates
|
||||||
|
Loading…
Reference in New Issue
Block a user