1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
use std::path::PathBuf;

use cargo::util::command_prelude::AppExt;
use cargo::util::command_prelude::{multi_opt, opt};

use structopt::clap::*;
use structopt::StructOpt;

// TODO: convert to a function using cargo opt()
#[derive(Clone, Debug, StructOpt)]
struct Common {
    /// Path to directory where target should be copied to
    #[structopt(long = "destdir", parse(from_os_str))]
    destdir: Option<PathBuf>,
    /// Directory path used to construct default values of
    /// includedir, libdir, bindir, pkgconfigdir
    #[structopt(long = "prefix", parse(from_os_str))]
    prefix: Option<PathBuf>,
    /// Path to directory for installing generated library files
    #[structopt(long = "libdir", parse(from_os_str))]
    libdir: Option<PathBuf>,
    /// Path to directory for installing generated headers files
    #[structopt(long = "includedir", parse(from_os_str))]
    includedir: Option<PathBuf>,
    /// Path to directory for installing generated executable files
    #[structopt(long = "bindir", parse(from_os_str))]
    bindir: Option<PathBuf>,
    /// Path to directory for installing generated pkg-config .pc files
    #[structopt(long = "pkgconfigdir", parse(from_os_str))]
    pkgconfigdir: Option<PathBuf>,
    #[structopt(long = "dlltool", parse(from_os_str))]
    /// Use the provided dlltool when building for the windows-gnu targets.
    dlltool: Option<PathBuf>,
}

fn base_cli() -> App<'static, 'static> {
    Common::clap()
        .arg(opt("version", "Print version info and exit").short("V"))
        .arg(
            opt(
                "verbose",
                "Use verbose output (-vv very verbose/build.rs output)",
            )
            .short("v")
            .multiple(true)
            .global(true),
        )
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(
            opt("color", "Coloring: auto, always, never")
                .value_name("WHEN")
                .global(true),
        )
        .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
        .arg(opt("locked", "Require Cargo.lock is up to date").global(true))
        .arg(opt("offline", "Run without accessing the network").global(true))
        .arg(
            multi_opt("config", "KEY=VALUE", "Override a configuration value")
                .global(true)
                .hidden(true),
        )
        .arg_jobs()
        .arg_release("Build artifacts in release mode, with optimizations")
        .arg_profile("Build artifacts with the specified profile")
        .arg_features()
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg_manifest_path()
        .arg_message_format()
        .arg_build_plan()
}

pub fn subcommand_cli(name: &str, about: &'static str) -> App<'static, 'static> {
    base_cli()
        .name(name)
        .about(about)
        .arg(
            multi_opt(
                "library-type",
                "LIBRARY-TYPE",
                "Build only a type of library",
            )
            .global(true)
            .case_insensitive(true)
            .possible_values(&["cdylib", "staticlib"]),
        )
        .after_help(
            "
Compilation can be configured via the use of profiles which are configured in
the manifest. The default profile for this command is `dev`, but passing
the --release flag will use the `release` profile instead.
",
        )
}

pub fn subcommand_test(name: &str) -> App<'static, 'static> {
    base_cli()
        .settings(&[AppSettings::TrailingVarArg])
        .name(name)
        .about("Test the crate C-API")
        .arg(
            Arg::with_name("args")
                .help("Arguments for the test binary")
                .multiple(true)
                .last(true),
        )
        .arg(opt("no-run", "Compile, but don't run tests"))
        .arg(opt("no-fail-fast", "Run all tests regardless of failure"))
}