rust/hgcli/build.rs
author Gregory Szorc <gregory.szorc@gmail.com>
Mon, 27 Aug 2018 09:13:58 -0700
changeset 39405 0f549da54379
parent 35607 24b5106e3e1e
child 43836 ce088b38f92b
permissions -rw-r--r--
stringutil: teach pprint() to indent This will make data structure dumping in various places a bit easier to read and diff. Since I wanted this for `hg debugwireproto` output, I added indentation to it. A more advanced pretty printer implementation would conditionally add newlines if output is too long. But it is vastly simpler to be consistent and always add newlines when indenting. Again, I'm not crazy about the verbosity of the code and there is room to consolidate logic for "print a collection." But this isn't the most complicated code in the world and I'm not convinced it is worth doing. Differential Revision: https://phab.mercurial-scm.org/D4399
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
35569
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
// build.rs -- Configure build environment for `hgcli` Rust package.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
//
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
// Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
//
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
use std::collections::HashMap;
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
use std::env;
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
use std::path::Path;
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
use std::process::Command;
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
struct PythonConfig {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
    python: String,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
    config: HashMap<String, String>,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
}
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
fn get_python_config() -> PythonConfig {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
    // The python27-sys crate exports a Cargo variable defining the full
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
    // path to the interpreter being used.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    21
    let python = env::var("DEP_PYTHON27_PYTHON_INTERPRETER").expect(
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    22
        "Missing DEP_PYTHON27_PYTHON_INTERPRETER; bad python27-sys crate?",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    23
    );
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    24
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    25
    if !Path::new(&python).exists() {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    26
        panic!(
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    27
            "Python interpreter {} does not exist; this should never happen",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    28
            python
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
        );
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
    // This is a bit hacky but it gets the job done.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    33
    let separator = "SEPARATOR STRING";
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    34
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    35
    let script = "import sysconfig; \
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
c = sysconfig.get_config_vars(); \
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    37
print('SEPARATOR STRING'.join('%s=%s' % i for i in c.items()))";
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    39
    let mut command = Command::new(&python);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
    command.arg("-c").arg(script);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
    let out = command.output().unwrap();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
    if !out.status.success() {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
        panic!(
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
            "python script failed: {}",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    47
            String::from_utf8_lossy(&out.stderr)
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    48
        );
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    49
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
    let stdout = String::from_utf8_lossy(&out.stdout);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
    let mut m = HashMap::new();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    53
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
    for entry in stdout.split(separator) {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
        let mut parts = entry.splitn(2, "=");
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
        let key = parts.next().unwrap();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    57
        let value = parts.next().unwrap();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
        m.insert(String::from(key), String::from(value));
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
    PythonConfig {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
        python: python,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
        config: m,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
}
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
#[cfg(not(target_os = "windows"))]
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
fn have_shared(config: &PythonConfig) -> bool {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    69
    match config.config.get("Py_ENABLE_SHARED") {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
        Some(value) => value == "1",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    71
        None => false,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    72
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    73
}
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    74
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    75
#[cfg(target_os = "windows")]
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    76
fn have_shared(config: &PythonConfig) -> bool {
35603
11c86ab69e67 rust: move import of PathBuf
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35569
diff changeset
    77
    use std::path::PathBuf;
11c86ab69e67 rust: move import of PathBuf
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35569
diff changeset
    78
35569
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    79
    // python27.dll should exist next to python2.7.exe.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    80
    let mut dll = PathBuf::from(&config.python);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    81
    dll.pop();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    82
    dll.push("python27.dll");
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    83
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    84
    return dll.exists();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    85
}
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    86
35607
24b5106e3e1e rust: avoid redundant 'static lifetime
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35603
diff changeset
    87
const REQUIRED_CONFIG_FLAGS: [&str; 2] = ["Py_USING_UNICODE", "WITH_THREAD"];
35569
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    88
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    89
fn main() {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    90
    let config = get_python_config();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    91
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    92
    println!("Using Python: {}", config.python);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    93
    println!("cargo:rustc-env=PYTHON_INTERPRETER={}", config.python);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    94
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
    let prefix = config.config.get("prefix").unwrap();
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
    println!("Prefix: {}", prefix);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    98
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    99
    // TODO Windows builds don't expose these config flags. Figure out another
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
    // way.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   101
    #[cfg(not(target_os = "windows"))]
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
    for key in REQUIRED_CONFIG_FLAGS.iter() {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   103
        let result = match config.config.get(*key) {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   104
            Some(value) => value == "1",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
            None => false,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   106
        };
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
        if !result {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   109
            panic!("Detected Python requires feature {}", key);
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   110
        }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   111
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   112
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   113
    // We need a Python shared library.
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   114
    if !have_shared(&config) {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   115
        panic!("Detected Python lacks a shared library, which is required");
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   116
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   117
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
    let ucs4 = match config.config.get("Py_UNICODE_SIZE") {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   119
        Some(value) => value == "4",
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   120
        None => false,
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   121
    };
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   122
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   123
    if !ucs4 {
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   124
        #[cfg(not(target_os = "windows"))]
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
        panic!("Detected Python doesn't support UCS-4 code points");
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   126
    }
964212780daf rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   127
}