| 74 | /// sysconfig.get_config_vars. |
| 75 | #[cfg(not(target_os = "windows"))] |
| 76 | fn get_config_vars(python_path: &str) -> Result<HashMap<String, String>, String> { |
| 77 | let mut script = "import sysconfig; \ |
| 78 | config = sysconfig.get_config_vars();" |
| 79 | .to_owned(); |
| 80 | |
| 81 | for k in SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()) { |
| 82 | script.push_str(&format!( |
| 83 | "print(config.get('{}', {}))", |
| 84 | k, |
| 85 | if is_value(k) { "None" } else { "0" } |
| 86 | )); |
| 87 | script.push(';'); |
| 88 | } |
| 89 | |
| 90 | let mut cmd = Command::new(python_path); |
| 91 | cmd.arg("-c").arg(script); |
| 92 | |
| 93 | let out = cmd |
| 94 | .output() |
| 95 | .map_err(|e| format!("failed to run python interpreter `{:?}`: {}", cmd, e))?; |
| 96 | |
| 97 | if !out.status.success() { |
| 98 | let stderr = String::from_utf8(out.stderr).unwrap(); |
| 99 | let mut msg = "python script failed with stderr:\n\n".to_string(); |
| 100 | msg.push_str(&stderr); |
| 101 | return Err(msg); |
| 102 | } |
| 103 | |
| 104 | let stdout = String::from_utf8(out.stdout).unwrap(); |
| 105 | let split_stdout: Vec<&str> = stdout.trim_end().split(NEWLINE_SEQUENCE).collect(); |
| 106 | if split_stdout.len() != SYSCONFIG_VALUES.len() + SYSCONFIG_FLAGS.len() { |
| 107 | return Err(format!( |
| 108 | "python stdout len didn't return expected number of lines: |
| 109 | {}", |
| 110 | split_stdout.len() |
| 111 | )); |
| 112 | } |
| 113 | let all_vars = SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()); |
| 114 | // let var_map: HashMap<String, String> = HashMap::new(); |
| 115 | Ok(all_vars.zip(split_stdout.iter()).fold( |
| 116 | HashMap::new(), |
| 117 | |mut memo: HashMap<String, String>, (&k, &v)| { |
| 118 | if !(v == "None" && is_value(k)) { |
| 119 | memo.insert(k.to_owned(), v.to_owned()); |
| 120 | } |
| 121 | memo |
| 122 | }, |
| 123 | )) |
| 124 | } |
| 125 | |
| 126 | #[cfg(target_os = "windows")] |
| 127 | fn get_config_vars(_: &str) -> Result<HashMap<String, String>, String> { |