chore: add vendor dependencies for kauma build
This commit is contained in:
parent
7c94e5d8fb
commit
067ef6141c
1758 changed files with 398473 additions and 0 deletions
1
vendor/cc/.cargo-checksum.json
vendored
Normal file
1
vendor/cc/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"4c2d7e4367b23e9232a1a08f93c6cd739d9c54394d8f6a58b1674101e7fd70ed","Cargo.toml":"8531bf0801327dae7536893352efc21e1864af5cbb854547c3850a4905a88f36","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"f1ddbede208a5b78333a25dac0a7598e678e9b601a7d99a791069bddaf180dfe","clippy.toml":"aa7850db4350883c8f373bd0d6b4d19bf3b75f13c1c238e24368c109cb52fb1d","src/command_helpers.rs":"63742844930bd693e029fa93b734d21c64453c1d9c58f792b3363b28a4c0e86d","src/detect_compiler_family.c":"97ca4b021495611e828becea6187add37414186a16dfedd26c2947cbce6e8b2f","src/lib.rs":"68e35fadafc880de1f59c327f5bc1681837c1009089dcdf6815798e76bbcc39f","src/parallel/async_executor.rs":"4ce24435fff6b6555b43fee042c16bd65d4150d0346567f246b9190d85b45983","src/parallel/job_token.rs":"f4ed0a03d89a42bfd5527133d12b267af519b745f3f2b997ed293df15a2641b8","src/parallel/mod.rs":"55fb4c2d15e66677b2ed5ffa6d65ea161bcf1a1e1dc7910ee3bde06f2f67ab14","src/parallel/once_lock.rs":"d13e4cb82d6bca3297ca8671d83a40dd5affd7ac89191d733dd451867181bb02","src/parallel/stderr.rs":"74384d41198740a6fce0877f144262db09fb091225fa8fbfa771314bb11487c6","src/target_info.rs":"447d3083f24e10fe4c449925b349b3d14ab2ff103c0d9f942ea9b581873442e1","src/tempfile.rs":"ebafb5b0e5d08b0706916ed911d4245240e60c3e2d0c9a1630c520842988a2b3","src/tool.rs":"2e6550062e021f2b394388172bbb01e86fe6a94d2395bcb3c85a9e86690da1a9","src/utilities.rs":"a13bb0a351fcef72823485b1b5dc4f514c533fa4feac95deb66ed9e5fbfe7b53","src/windows/com.rs":"a2800ddb81215fff2bf618336f5c4ff8e8bdb746dd18b795873c7304b3f2a5e3","src/windows/find_tools.rs":"dd6b2450909cd8334a2aa2ce856bcc72a9654d92422267d6345d5fabfcbf57c5","src/windows/mod.rs":"34cfa201cfbcac7ccaa3ea5295d3e4200439af3cc5c6433baf81502596040a89","src/windows/registry.rs":"c521b72c825e8095843e73482ffa810ed066ad8bb9f86e6db0c5c143c171aba1","src/windows/setup_config.rs":"754439cbab492afd44c9755abcbec1a41c9b2c358131cee2df13c0e996dbbec8","src/windows/vs_instances.rs":"946527cf8fd32c3472f6a2884dcdec290763101097334c7478f9c24c3950db6b","src/windows/winapi.rs":"250d51c1826d1a2329e9889dd9f058cfce253dbf2a678b076147c6cdb5db046c","src/windows/windows_sys.rs":"e2714c8307bfa083b9745eb0e46cadd7f98d7b88abf45a7637172019324e34b8","src/windows/windows_targets.rs":"5b4648ebc22b028caca9f4b4bf8881fe2d094b7bec217264ba2e6e2c49d1ccee"},"package":"c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"}
|
||||
244
vendor/cc/CHANGELOG.md
vendored
Normal file
244
vendor/cc/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.1.31](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.30...cc-v1.1.31) - 2024-10-19
|
||||
|
||||
### Other
|
||||
|
||||
- Add comment explaining why cc does not rebuild on env PATH change ([#1247](https://github.com/rust-lang/cc-rs/pull/1247))
|
||||
|
||||
## [1.1.30](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.29...cc-v1.1.30) - 2024-10-11
|
||||
|
||||
### Other
|
||||
|
||||
- Don't pass -fPIC by default on wasm ([#1245](https://github.com/rust-lang/cc-rs/pull/1245))
|
||||
|
||||
## [1.1.29](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.28...cc-v1.1.29) - 2024-10-11
|
||||
|
||||
### Other
|
||||
|
||||
- Regenerate target info ([#1243](https://github.com/rust-lang/cc-rs/pull/1243))
|
||||
|
||||
## [1.1.28](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.27...cc-v1.1.28) - 2024-10-06
|
||||
|
||||
### Other
|
||||
|
||||
- Environment variables: For one accepting boolean, treat "0", "false" and empty env as false ([#1238](https://github.com/rust-lang/cc-rs/pull/1238))
|
||||
|
||||
## [1.1.27](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.26...cc-v1.1.27) - 2024-10-06
|
||||
|
||||
### Other
|
||||
|
||||
- Revert "Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231))" ([#1237](https://github.com/rust-lang/cc-rs/pull/1237))
|
||||
- Disable `CC_ENABLE_DEBUG_OUTPUT` if it is set to "0" ([#1234](https://github.com/rust-lang/cc-rs/pull/1234))
|
||||
|
||||
## [1.1.26](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.25...cc-v1.1.26) - 2024-10-06
|
||||
|
||||
### Other
|
||||
|
||||
- Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231))
|
||||
|
||||
## [1.1.25](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.24...cc-v1.1.25) - 2024-10-05
|
||||
|
||||
### Other
|
||||
|
||||
- Remove incorrect "lib" prefixes in CXXSTDLIB doc comments ([#1228](https://github.com/rust-lang/cc-rs/pull/1228))
|
||||
|
||||
## [1.1.24](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.23...cc-v1.1.24) - 2024-10-01
|
||||
|
||||
### Other
|
||||
|
||||
- Fix wasm32-wasip1-threads: shared-memory disallowed due to not compiled with 'atomics' or 'bulk-memory' features ([#1221](https://github.com/rust-lang/cc-rs/pull/1221))
|
||||
- Reduce the need for the host target triple ([#1224](https://github.com/rust-lang/cc-rs/pull/1224))
|
||||
- Add auto cancellation for CI jobs ([#1222](https://github.com/rust-lang/cc-rs/pull/1222))
|
||||
|
||||
## [1.1.23](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.22...cc-v1.1.23) - 2024-09-30
|
||||
|
||||
### Other
|
||||
|
||||
- Update doc for detecting changes/upgrades of compilers ([#1218](https://github.com/rust-lang/cc-rs/pull/1218))
|
||||
|
||||
## [1.1.22](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.21...cc-v1.1.22) - 2024-09-27
|
||||
|
||||
### Other
|
||||
|
||||
- Don't rerun if PATH changes ([#1215](https://github.com/rust-lang/cc-rs/pull/1215))
|
||||
|
||||
## [1.1.21](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.20...cc-v1.1.21) - 2024-09-18
|
||||
|
||||
### Other
|
||||
|
||||
- disable pic for targets that end in `-none` ([#1212](https://github.com/rust-lang/cc-rs/pull/1212))
|
||||
|
||||
## [1.1.20](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.19...cc-v1.1.20) - 2024-09-17
|
||||
|
||||
### Other
|
||||
|
||||
- Add buildcache as known Rust and C/C++ compiler wrapper ([#1209](https://github.com/rust-lang/cc-rs/pull/1209))
|
||||
|
||||
## [1.1.19](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.18...cc-v1.1.19) - 2024-09-15
|
||||
|
||||
### Other
|
||||
|
||||
- Add support arm64e-apple-darwin ([#1207](https://github.com/rust-lang/cc-rs/pull/1207))
|
||||
|
||||
## [1.1.18](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.17...cc-v1.1.18) - 2024-09-07
|
||||
|
||||
### Other
|
||||
- Fixed unsoundness in `StderrForwarder::forward_available` ([#1203](https://github.com/rust-lang/cc-rs/pull/1203))
|
||||
|
||||
## [1.1.17](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.16...cc-v1.1.17) - 2024-09-06
|
||||
|
||||
### Fixed
|
||||
- fix finding toolchains when invoked by msbuild ([#1201](https://github.com/rust-lang/cc-rs/pull/1201))
|
||||
|
||||
## [1.1.16](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.15...cc-v1.1.16) - 2024-09-04
|
||||
|
||||
### Other
|
||||
- Treat VxWorks wr-cc as a Gnu compiler ([#1198](https://github.com/rust-lang/cc-rs/pull/1198))
|
||||
|
||||
## [1.1.15](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.14...cc-v1.1.15) - 2024-08-26
|
||||
|
||||
### Other
|
||||
- Add -mfloat-abi=hard as a default argument when using any arm/thumb-none-eabihf target ([#1194](https://github.com/rust-lang/cc-rs/pull/1194))
|
||||
|
||||
## [1.1.14](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.13...cc-v1.1.14) - 2024-08-23
|
||||
|
||||
### Other
|
||||
- allow finding tools from path if VisualStudioDir is set
|
||||
|
||||
## [1.1.13](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.12...cc-v1.1.13) - 2024-08-16
|
||||
|
||||
### Other
|
||||
- Fix detect family: should detect emscripten as clang, closes [#1185](https://github.com/rust-lang/cc-rs/pull/1185) ([#1186](https://github.com/rust-lang/cc-rs/pull/1186))
|
||||
|
||||
## [1.1.12](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.11...cc-v1.1.12) - 2024-08-15
|
||||
|
||||
### Other
|
||||
- improve docs ([#1183](https://github.com/rust-lang/cc-rs/pull/1183))
|
||||
|
||||
## [1.1.11](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.10...cc-v1.1.11) - 2024-08-14
|
||||
|
||||
### Other
|
||||
- Add support for parsing shell encoded `*FLAGS` ([#1181](https://github.com/rust-lang/cc-rs/pull/1181))
|
||||
- Replace vector of tuples with BTreeMap which already is sorted and free of duplicates ([#1177](https://github.com/rust-lang/cc-rs/pull/1177))
|
||||
|
||||
## [1.1.10](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.9...cc-v1.1.10) - 2024-08-11
|
||||
|
||||
### Other
|
||||
- Remap Windows targets triples to their LLVM counterparts ([#1176](https://github.com/rust-lang/cc-rs/pull/1176))
|
||||
|
||||
## [1.1.9](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.8...cc-v1.1.9) - 2024-08-11
|
||||
|
||||
### Other
|
||||
- Add custom CC wrapper to the wrapper whitelist ([#1175](https://github.com/rust-lang/cc-rs/pull/1175))
|
||||
|
||||
## [1.1.8](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.7...cc-v1.1.8) - 2024-08-06
|
||||
|
||||
### Other
|
||||
- Fix broken link in docs.rs ([#1173](https://github.com/rust-lang/cc-rs/pull/1173))
|
||||
|
||||
## [1.1.7](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.6...cc-v1.1.7) - 2024-07-29
|
||||
|
||||
### Other
|
||||
- add `.objects` ([#1166](https://github.com/rust-lang/cc-rs/pull/1166))
|
||||
|
||||
## [1.1.6](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.5...cc-v1.1.6) - 2024-07-19
|
||||
|
||||
### Other
|
||||
- Clippy fixes ([#1163](https://github.com/rust-lang/cc-rs/pull/1163))
|
||||
|
||||
## [1.1.5](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.4...cc-v1.1.5) - 2024-07-15
|
||||
|
||||
### Other
|
||||
- Fix cyclic compilation: Use vendored once_cell ([#1154](https://github.com/rust-lang/cc-rs/pull/1154))
|
||||
|
||||
## [1.1.4](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.3...cc-v1.1.4) - 2024-07-14
|
||||
|
||||
### Other
|
||||
- Support compiling on wasm targets (Supersede [#1068](https://github.com/rust-lang/cc-rs/pull/1068)) ([#1160](https://github.com/rust-lang/cc-rs/pull/1160))
|
||||
|
||||
## [1.1.3](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.2...cc-v1.1.3) - 2024-07-14
|
||||
|
||||
### Other
|
||||
- Reduce msrv to 1.63 ([#1158](https://github.com/rust-lang/cc-rs/pull/1158))
|
||||
- Revert "Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137))" ([#1157](https://github.com/rust-lang/cc-rs/pull/1157))
|
||||
- Fix typos ([#1152](https://github.com/rust-lang/cc-rs/pull/1152))
|
||||
- Fix `doc_lazy_continuation` lints ([#1153](https://github.com/rust-lang/cc-rs/pull/1153))
|
||||
|
||||
## [1.1.2](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.1...cc-v1.1.2) - 2024-07-12
|
||||
|
||||
### Other
|
||||
- Add empty `jobserver` feature. ([#1150](https://github.com/rust-lang/cc-rs/pull/1150))
|
||||
|
||||
## [1.1.1](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.0...cc-v1.1.1) - 2024-07-12
|
||||
|
||||
### Other
|
||||
- Fix is_flag_supported not respecting emit_rerun_if_env_changed ([#1147](https://github.com/rust-lang/cc-rs/pull/1147)) ([#1148](https://github.com/rust-lang/cc-rs/pull/1148))
|
||||
|
||||
## [1.1.0](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.106...cc-v1.1.0) - 2024-07-08
|
||||
|
||||
### Added
|
||||
- add cargo_output to eliminate last vestiges of stdout pollution ([#1141](https://github.com/rust-lang/cc-rs/pull/1141))
|
||||
|
||||
## [1.0.106](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.105...cc-v1.0.106) - 2024-07-08
|
||||
|
||||
### Other
|
||||
- Drop support for Visual Studio 12 (2013) ([#1046](https://github.com/rust-lang/cc-rs/pull/1046))
|
||||
- Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137))
|
||||
- Bump msrv to 1.67 ([#1143](https://github.com/rust-lang/cc-rs/pull/1143))
|
||||
- Bump msrv to 1.65 ([#1140](https://github.com/rust-lang/cc-rs/pull/1140))
|
||||
- Fix clippy warnings ([#1138](https://github.com/rust-lang/cc-rs/pull/1138))
|
||||
|
||||
## [1.0.105](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.104...cc-v1.0.105) - 2024-07-07
|
||||
|
||||
### Other
|
||||
- Regenerate windows sys bindings ([#1132](https://github.com/rust-lang/cc-rs/pull/1132))
|
||||
- Fix generate-windows-sys-bindings ([#1133](https://github.com/rust-lang/cc-rs/pull/1133))
|
||||
- Fix gen-windows-sys-binding ([#1130](https://github.com/rust-lang/cc-rs/pull/1130))
|
||||
- Fix gen-windows-sys-binding ([#1127](https://github.com/rust-lang/cc-rs/pull/1127))
|
||||
- Update windows-bindgen requirement from 0.57 to 0.58 ([#1123](https://github.com/rust-lang/cc-rs/pull/1123))
|
||||
|
||||
## [1.0.104](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.103...cc-v1.0.104) - 2024-07-01
|
||||
|
||||
### Other
|
||||
- Fixed link break about compile-time-requirements ([#1118](https://github.com/rust-lang/cc-rs/pull/1118))
|
||||
|
||||
## [1.0.103](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.102...cc-v1.0.103) - 2024-06-30
|
||||
|
||||
### Other
|
||||
- Fix compilation for wasm: env WASI_SYSROOT should be optional ([#1114](https://github.com/rust-lang/cc-rs/pull/1114))
|
||||
|
||||
## [1.0.102](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.101...cc-v1.0.102) - 2024-06-29
|
||||
|
||||
### Other
|
||||
- Fix invalid wasi targets compatibility ([#1105](https://github.com/rust-lang/cc-rs/pull/1105))
|
||||
- Speedup regenerate-target-info and regenerate-windows-sys ([#1110](https://github.com/rust-lang/cc-rs/pull/1110))
|
||||
|
||||
## [1.0.101](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.100...cc-v1.0.101) - 2024-06-25
|
||||
|
||||
### Other
|
||||
- Use `Build::getenv` instead of `env::var*` in anywhere that makes sense ([#1103](https://github.com/rust-lang/cc-rs/pull/1103))
|
||||
|
||||
## [1.0.100](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.99...cc-v1.0.100) - 2024-06-23
|
||||
|
||||
### Other
|
||||
- Update publish.yml to use release-plz ([#1101](https://github.com/rust-lang/cc-rs/pull/1101))
|
||||
- Accept `OsStr` instead of `str` for flags ([#1100](https://github.com/rust-lang/cc-rs/pull/1100))
|
||||
- Use `dep:` syntax to avoid implicit features. ([#1099](https://github.com/rust-lang/cc-rs/pull/1099))
|
||||
- Minor clippy fixes. ([#1098](https://github.com/rust-lang/cc-rs/pull/1098))
|
||||
- Fix WASI compilation for C++ ([#1083](https://github.com/rust-lang/cc-rs/pull/1083))
|
||||
- Regenerate windows sys bindings ([#1096](https://github.com/rust-lang/cc-rs/pull/1096))
|
||||
- Rename regenerate-windows-sys to regenerate-windows-sys.yml ([#1095](https://github.com/rust-lang/cc-rs/pull/1095))
|
||||
- Create regenerate-windows-sys.yml ([#1094](https://github.com/rust-lang/cc-rs/pull/1094))
|
||||
- Update windows-bindgen requirement from 0.56 to 0.57 ([#1091](https://github.com/rust-lang/cc-rs/pull/1091))
|
||||
- Eagerly close tempfile to fix [#1082](https://github.com/rust-lang/cc-rs/pull/1082) ([#1087](https://github.com/rust-lang/cc-rs/pull/1087))
|
||||
- Output msvc.exe in the output directory ([#1090](https://github.com/rust-lang/cc-rs/pull/1090))
|
||||
- Fix clippy warnings on Windows ([#1088](https://github.com/rust-lang/cc-rs/pull/1088))
|
||||
- Don't try to free DLL on drop ([#1089](https://github.com/rust-lang/cc-rs/pull/1089))
|
||||
- Fix panic safety issue in StderrForwarder ([#1079](https://github.com/rust-lang/cc-rs/pull/1079))
|
||||
66
vendor/cc/Cargo.toml
vendored
Normal file
66
vendor/cc/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.63"
|
||||
name = "cc"
|
||||
version = "1.1.31"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
build = false
|
||||
exclude = [
|
||||
"/.github",
|
||||
"tests",
|
||||
"src/bin",
|
||||
]
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = """
|
||||
A build-time dependency for Cargo build scripts to assist in invoking the native
|
||||
C compiler to compile native C code into a static archive to be linked into Rust
|
||||
code.
|
||||
"""
|
||||
homepage = "https://github.com/rust-lang/cc-rs"
|
||||
documentation = "https://docs.rs/cc"
|
||||
readme = "README.md"
|
||||
keywords = ["build-dependencies"]
|
||||
categories = ["development-tools::build-utils"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/rust-lang/cc-rs"
|
||||
|
||||
[lib]
|
||||
name = "cc"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.jobserver]
|
||||
version = "0.1.30"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.shlex]
|
||||
version = "1.3.0"
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
version = "3"
|
||||
|
||||
[features]
|
||||
jobserver = []
|
||||
parallel = [
|
||||
"dep:libc",
|
||||
"dep:jobserver",
|
||||
]
|
||||
|
||||
[target."cfg(unix)".dependencies.libc]
|
||||
version = "0.2.62"
|
||||
optional = true
|
||||
default-features = false
|
||||
201
vendor/cc/LICENSE-APACHE
vendored
Normal file
201
vendor/cc/LICENSE-APACHE
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
25
vendor/cc/LICENSE-MIT
vendored
Normal file
25
vendor/cc/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2014 Alex Crichton
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
27
vendor/cc/README.md
vendored
Normal file
27
vendor/cc/README.md
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# cc-rs
|
||||
|
||||
A library for [Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html)
|
||||
to compile a set of C/C++/assembly/CUDA files into a static archive for Cargo
|
||||
to link into the crate being built. This crate does not compile code itself;
|
||||
it calls out to the default compiler for the platform. This crate will
|
||||
automatically detect situations such as cross compilation and
|
||||
various environment variables and will build code appropriately.
|
||||
|
||||
Refer to the [documentation](https://docs.rs/cc) for detailed usage instructions.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
https://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
https://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in cc-rs by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
5
vendor/cc/clippy.toml
vendored
Normal file
5
vendor/cc/clippy.toml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
disallowed-methods = [
|
||||
{ path = "std::env::var_os", reason = "Please use Build::getenv" },
|
||||
{ path = "std::env::var", reason = "Please use Build::getenv" },
|
||||
]
|
||||
doc-valid-idents = ["AppleClang", "OpenBSD", ".."]
|
||||
491
vendor/cc/src/command_helpers.rs
vendored
Normal file
491
vendor/cc/src/command_helpers.rs
vendored
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
//! Miscellaneous helpers for running commands
|
||||
|
||||
use std::{
|
||||
collections::hash_map,
|
||||
ffi::OsString,
|
||||
fmt::Display,
|
||||
fs,
|
||||
hash::Hasher,
|
||||
io::{self, Read, Write},
|
||||
path::Path,
|
||||
process::{Child, ChildStderr, Command, Stdio},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{Error, ErrorKind, Object};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct CargoOutput {
|
||||
pub(crate) metadata: bool,
|
||||
pub(crate) warnings: bool,
|
||||
pub(crate) debug: bool,
|
||||
pub(crate) output: OutputKind,
|
||||
checked_dbg_var: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
/// Different strategies for handling compiler output (to stdout)
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum OutputKind {
|
||||
/// Forward the output to this process' stdout ([`Stdio::inherit()`])
|
||||
Forward,
|
||||
/// Discard the output ([`Stdio::null()`])
|
||||
Discard,
|
||||
/// Capture the result (`[Stdio::piped()`])
|
||||
Capture,
|
||||
}
|
||||
|
||||
impl CargoOutput {
|
||||
pub(crate) fn new() -> Self {
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
Self {
|
||||
metadata: true,
|
||||
warnings: true,
|
||||
output: OutputKind::Forward,
|
||||
debug: match std::env::var_os("CC_ENABLE_DEBUG_OUTPUT") {
|
||||
Some(v) => v != "0" && v != "false" && v != "",
|
||||
None => false,
|
||||
},
|
||||
checked_dbg_var: Arc::new(AtomicBool::new(false)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn print_metadata(&self, s: &dyn Display) {
|
||||
if self.metadata {
|
||||
println!("{}", s);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn print_warning(&self, arg: &dyn Display) {
|
||||
if self.warnings {
|
||||
println!("cargo:warning={}", arg);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn print_debug(&self, arg: &dyn Display) {
|
||||
if self.metadata && !self.checked_dbg_var.load(Ordering::Relaxed) {
|
||||
self.checked_dbg_var.store(true, Ordering::Relaxed);
|
||||
println!("cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT");
|
||||
}
|
||||
if self.debug {
|
||||
println!("{}", arg);
|
||||
}
|
||||
}
|
||||
|
||||
fn stdio_for_warnings(&self) -> Stdio {
|
||||
if self.warnings {
|
||||
Stdio::piped()
|
||||
} else {
|
||||
Stdio::null()
|
||||
}
|
||||
}
|
||||
|
||||
fn stdio_for_output(&self) -> Stdio {
|
||||
match self.output {
|
||||
OutputKind::Capture => Stdio::piped(),
|
||||
OutputKind::Forward => Stdio::inherit(),
|
||||
OutputKind::Discard => Stdio::null(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct StderrForwarder {
|
||||
inner: Option<(ChildStderr, Vec<u8>)>,
|
||||
#[cfg(feature = "parallel")]
|
||||
is_non_blocking: bool,
|
||||
#[cfg(feature = "parallel")]
|
||||
bytes_available_failed: bool,
|
||||
/// number of bytes buffered in inner
|
||||
bytes_buffered: usize,
|
||||
}
|
||||
|
||||
const MIN_BUFFER_CAPACITY: usize = 100;
|
||||
|
||||
impl StderrForwarder {
|
||||
pub(crate) fn new(child: &mut Child) -> Self {
|
||||
Self {
|
||||
inner: child
|
||||
.stderr
|
||||
.take()
|
||||
.map(|stderr| (stderr, Vec::with_capacity(MIN_BUFFER_CAPACITY))),
|
||||
bytes_buffered: 0,
|
||||
#[cfg(feature = "parallel")]
|
||||
is_non_blocking: false,
|
||||
#[cfg(feature = "parallel")]
|
||||
bytes_available_failed: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn forward_available(&mut self) -> bool {
|
||||
if let Some((stderr, buffer)) = self.inner.as_mut() {
|
||||
loop {
|
||||
// For non-blocking we check to see if there is data available, so we should try to
|
||||
// read at least that much. For blocking, always read at least the minimum amount.
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
let to_reserve = MIN_BUFFER_CAPACITY;
|
||||
#[cfg(feature = "parallel")]
|
||||
let to_reserve = if self.is_non_blocking && !self.bytes_available_failed {
|
||||
match crate::parallel::stderr::bytes_available(stderr) {
|
||||
#[cfg(windows)]
|
||||
Ok(0) => break false,
|
||||
#[cfg(unix)]
|
||||
Ok(0) => {
|
||||
// On Unix, depending on the implementation, we may sometimes get 0 in a
|
||||
// loop (either there is data available or the pipe is broken), so
|
||||
// continue with the non-blocking read anyway.
|
||||
MIN_BUFFER_CAPACITY
|
||||
}
|
||||
#[cfg(windows)]
|
||||
Err(_) => {
|
||||
// On Windows, if we get an error then the pipe is broken, so flush
|
||||
// the buffer and bail.
|
||||
if !buffer.is_empty() {
|
||||
write_warning(&buffer[..]);
|
||||
}
|
||||
self.inner = None;
|
||||
break true;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
Err(_) => {
|
||||
// On Unix, depending on the implementation, we may get spurious
|
||||
// errors so make a note not to use bytes_available again and try
|
||||
// the non-blocking read anyway.
|
||||
self.bytes_available_failed = true;
|
||||
MIN_BUFFER_CAPACITY
|
||||
}
|
||||
#[cfg(target_family = "wasm")]
|
||||
Err(_) => panic!("bytes_available should always succeed on wasm"),
|
||||
Ok(bytes_available) => MIN_BUFFER_CAPACITY.max(bytes_available),
|
||||
}
|
||||
} else {
|
||||
MIN_BUFFER_CAPACITY
|
||||
};
|
||||
if self.bytes_buffered + to_reserve > buffer.len() {
|
||||
buffer.resize(self.bytes_buffered + to_reserve, 0);
|
||||
}
|
||||
|
||||
match stderr.read(&mut buffer[self.bytes_buffered..]) {
|
||||
Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {
|
||||
// No data currently, yield back.
|
||||
break false;
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::Interrupted => {
|
||||
// Interrupted, try again.
|
||||
continue;
|
||||
}
|
||||
Ok(bytes_read) if bytes_read != 0 => {
|
||||
self.bytes_buffered += bytes_read;
|
||||
let mut consumed = 0;
|
||||
for line in buffer[..self.bytes_buffered].split_inclusive(|&b| b == b'\n') {
|
||||
// Only forward complete lines, leave the rest in the buffer.
|
||||
if let Some((b'\n', line)) = line.split_last() {
|
||||
consumed += line.len() + 1;
|
||||
write_warning(line);
|
||||
}
|
||||
}
|
||||
if consumed > 0 && consumed < self.bytes_buffered {
|
||||
// Remove the consumed bytes from buffer
|
||||
buffer.copy_within(consumed.., 0);
|
||||
}
|
||||
self.bytes_buffered -= consumed;
|
||||
}
|
||||
res => {
|
||||
// End of stream: flush remaining data and bail.
|
||||
if self.bytes_buffered > 0 {
|
||||
write_warning(&buffer[..self.bytes_buffered]);
|
||||
}
|
||||
if let Err(err) = res {
|
||||
write_warning(
|
||||
format!("Failed to read from child stderr: {err}").as_bytes(),
|
||||
);
|
||||
}
|
||||
self.inner.take();
|
||||
break true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) fn set_non_blocking(&mut self) -> Result<(), Error> {
|
||||
assert!(!self.is_non_blocking);
|
||||
|
||||
#[cfg(unix)]
|
||||
if let Some((stderr, _)) = self.inner.as_ref() {
|
||||
crate::parallel::stderr::set_non_blocking(stderr)?;
|
||||
}
|
||||
|
||||
self.is_non_blocking = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
fn forward_all(&mut self) {
|
||||
while !self.forward_available() {}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
fn forward_all(&mut self) {
|
||||
let forward_result = self.forward_available();
|
||||
assert!(forward_result, "Should have consumed all data");
|
||||
}
|
||||
}
|
||||
|
||||
fn write_warning(line: &[u8]) {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
stdout.write_all(b"cargo:warning=").unwrap();
|
||||
stdout.write_all(line).unwrap();
|
||||
stdout.write_all(b"\n").unwrap();
|
||||
}
|
||||
|
||||
fn wait_on_child(
|
||||
cmd: &Command,
|
||||
program: &Path,
|
||||
child: &mut Child,
|
||||
cargo_output: &CargoOutput,
|
||||
) -> Result<(), Error> {
|
||||
StderrForwarder::new(child).forward_all();
|
||||
|
||||
let status = match child.wait() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::ToolExecError,
|
||||
format!(
|
||||
"Failed to wait on spawned child process, command {:?} with args {}: {}.",
|
||||
cmd,
|
||||
program.display(),
|
||||
e
|
||||
),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
cargo_output.print_debug(&status);
|
||||
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(
|
||||
ErrorKind::ToolExecError,
|
||||
format!(
|
||||
"Command {:?} with args {} did not execute successfully (status code {}).",
|
||||
cmd,
|
||||
program.display(),
|
||||
status
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the destination object path for each file in the input source files,
|
||||
/// and store them in the output Object.
|
||||
pub(crate) fn objects_from_files(files: &[Arc<Path>], dst: &Path) -> Result<Vec<Object>, Error> {
|
||||
let mut objects = Vec::with_capacity(files.len());
|
||||
for file in files {
|
||||
let basename = file
|
||||
.file_name()
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
ErrorKind::InvalidArgument,
|
||||
"No file_name for object file path!",
|
||||
)
|
||||
})?
|
||||
.to_string_lossy();
|
||||
let dirname = file
|
||||
.parent()
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
ErrorKind::InvalidArgument,
|
||||
"No parent for object file path!",
|
||||
)
|
||||
})?
|
||||
.to_string_lossy();
|
||||
|
||||
// Hash the dirname. This should prevent conflicts if we have multiple
|
||||
// object files with the same filename in different subfolders.
|
||||
let mut hasher = hash_map::DefaultHasher::new();
|
||||
hasher.write(dirname.to_string().as_bytes());
|
||||
let obj = dst
|
||||
.join(format!("{:016x}-{}", hasher.finish(), basename))
|
||||
.with_extension("o");
|
||||
|
||||
match obj.parent() {
|
||||
Some(s) => fs::create_dir_all(s)?,
|
||||
None => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidArgument,
|
||||
"dst is an invalid path with no parent",
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
objects.push(Object::new(file.to_path_buf(), obj));
|
||||
}
|
||||
|
||||
Ok(objects)
|
||||
}
|
||||
|
||||
pub(crate) fn run(
|
||||
cmd: &mut Command,
|
||||
program: impl AsRef<Path>,
|
||||
cargo_output: &CargoOutput,
|
||||
) -> Result<(), Error> {
|
||||
let program = program.as_ref();
|
||||
|
||||
let mut child = spawn(cmd, program, cargo_output)?;
|
||||
wait_on_child(cmd, program, &mut child, cargo_output)
|
||||
}
|
||||
|
||||
pub(crate) fn run_output(
|
||||
cmd: &mut Command,
|
||||
program: impl AsRef<Path>,
|
||||
cargo_output: &CargoOutput,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let program = program.as_ref();
|
||||
|
||||
// We specifically need the output to be captured, so override default
|
||||
let mut captured_cargo_output = cargo_output.clone();
|
||||
captured_cargo_output.output = OutputKind::Capture;
|
||||
let mut child = spawn(cmd, program, &captured_cargo_output)?;
|
||||
|
||||
let mut stdout = vec![];
|
||||
child
|
||||
.stdout
|
||||
.take()
|
||||
.unwrap()
|
||||
.read_to_end(&mut stdout)
|
||||
.unwrap();
|
||||
|
||||
// Don't care about this output, use the normal settings
|
||||
wait_on_child(cmd, program, &mut child, cargo_output)?;
|
||||
|
||||
Ok(stdout)
|
||||
}
|
||||
|
||||
pub(crate) fn spawn(
|
||||
cmd: &mut Command,
|
||||
program: &Path,
|
||||
cargo_output: &CargoOutput,
|
||||
) -> Result<Child, Error> {
|
||||
struct ResetStderr<'cmd>(&'cmd mut Command);
|
||||
|
||||
impl Drop for ResetStderr<'_> {
|
||||
fn drop(&mut self) {
|
||||
// Reset stderr to default to release pipe_writer so that print thread will
|
||||
// not block forever.
|
||||
self.0.stderr(Stdio::inherit());
|
||||
}
|
||||
}
|
||||
|
||||
cargo_output.print_debug(&format_args!("running: {:?}", cmd));
|
||||
|
||||
let cmd = ResetStderr(cmd);
|
||||
let child = cmd
|
||||
.0
|
||||
.stderr(cargo_output.stdio_for_warnings())
|
||||
.stdout(cargo_output.stdio_for_output())
|
||||
.spawn();
|
||||
match child {
|
||||
Ok(child) => Ok(child),
|
||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
|
||||
let extra = if cfg!(windows) {
|
||||
" (see https://docs.rs/cc/latest/cc/#compile-time-requirements \
|
||||
for help)"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
Err(Error::new(
|
||||
ErrorKind::ToolNotFound,
|
||||
format!(
|
||||
"Failed to find tool. Is `{}` installed?{}",
|
||||
program.display(),
|
||||
extra
|
||||
),
|
||||
))
|
||||
}
|
||||
Err(e) => Err(Error::new(
|
||||
ErrorKind::ToolExecError,
|
||||
format!(
|
||||
"Command {:?} with args {} failed to start: {:?}",
|
||||
cmd.0,
|
||||
program.display(),
|
||||
e
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct CmdAddOutputFileArgs {
|
||||
pub(crate) cuda: bool,
|
||||
pub(crate) is_assembler_msvc: bool,
|
||||
pub(crate) msvc: bool,
|
||||
pub(crate) clang: bool,
|
||||
pub(crate) gnu: bool,
|
||||
pub(crate) is_asm: bool,
|
||||
pub(crate) is_arm: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn command_add_output_file(cmd: &mut Command, dst: &Path, args: CmdAddOutputFileArgs) {
|
||||
if args.is_assembler_msvc
|
||||
|| !(!args.msvc || args.clang || args.gnu || args.cuda || (args.is_asm && args.is_arm))
|
||||
{
|
||||
let mut s = OsString::from("-Fo");
|
||||
s.push(dst);
|
||||
cmd.arg(s);
|
||||
} else {
|
||||
cmd.arg("-o").arg(dst);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) fn try_wait_on_child(
|
||||
cmd: &Command,
|
||||
program: &Path,
|
||||
child: &mut Child,
|
||||
stdout: &mut dyn io::Write,
|
||||
stderr_forwarder: &mut StderrForwarder,
|
||||
) -> Result<Option<()>, Error> {
|
||||
stderr_forwarder.forward_available();
|
||||
|
||||
match child.try_wait() {
|
||||
Ok(Some(status)) => {
|
||||
stderr_forwarder.forward_all();
|
||||
|
||||
let _ = writeln!(stdout, "{}", status);
|
||||
|
||||
if status.success() {
|
||||
Ok(Some(()))
|
||||
} else {
|
||||
Err(Error::new(
|
||||
ErrorKind::ToolExecError,
|
||||
format!(
|
||||
"Command {:?} with args {} did not execute successfully (status code {}).",
|
||||
cmd,
|
||||
program.display(),
|
||||
status
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
Ok(None) => Ok(None),
|
||||
Err(e) => {
|
||||
stderr_forwarder.forward_all();
|
||||
Err(Error::new(
|
||||
ErrorKind::ToolExecError,
|
||||
format!(
|
||||
"Failed to wait on spawned child process, command {:?} with args {}: {}.",
|
||||
cmd,
|
||||
program.display(),
|
||||
e
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
15
vendor/cc/src/detect_compiler_family.c
vendored
Normal file
15
vendor/cc/src/detect_compiler_family.c
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifdef __clang__
|
||||
#pragma message "clang"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma message "gcc"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#pragma message "emscripten"
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
#pragma message "VxWorks"
|
||||
#endif
|
||||
4348
vendor/cc/src/lib.rs
vendored
Normal file
4348
vendor/cc/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
118
vendor/cc/src/parallel/async_executor.rs
vendored
Normal file
118
vendor/cc/src/parallel/async_executor.rs
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use std::{
|
||||
cell::Cell,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
|
||||
// Cloning just returns a new no-op raw waker
|
||||
|_| NOOP_RAW_WAKER,
|
||||
// `wake` does nothing
|
||||
|_| {},
|
||||
// `wake_by_ref` does nothing
|
||||
|_| {},
|
||||
// Dropping does nothing as we don't allocate anything
|
||||
|_| {},
|
||||
);
|
||||
const NOOP_RAW_WAKER: RawWaker = RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE);
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct YieldOnce(bool);
|
||||
|
||||
impl Future for YieldOnce {
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
|
||||
let flag = &mut std::pin::Pin::into_inner(self).0;
|
||||
if !*flag {
|
||||
*flag = true;
|
||||
Poll::Pending
|
||||
} else {
|
||||
Poll::Ready(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute the futures and return when they are all done.
|
||||
///
|
||||
/// Here we use our own homebrew async executor since cc is used in the build
|
||||
/// script of many popular projects, pulling in additional dependencies would
|
||||
/// significantly slow down its compilation.
|
||||
pub(crate) fn block_on<Fut1, Fut2>(
|
||||
mut fut1: Fut1,
|
||||
mut fut2: Fut2,
|
||||
has_made_progress: &Cell<bool>,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Fut1: Future<Output = Result<(), Error>>,
|
||||
Fut2: Future<Output = Result<(), Error>>,
|
||||
{
|
||||
// Shadows the future so that it can never be moved and is guaranteed
|
||||
// to be pinned.
|
||||
//
|
||||
// The same trick used in `pin!` macro.
|
||||
//
|
||||
// TODO: Once MSRV is bumped to 1.68, replace this with `std::pin::pin!`
|
||||
let mut fut1 = Some(unsafe { Pin::new_unchecked(&mut fut1) });
|
||||
let mut fut2 = Some(unsafe { Pin::new_unchecked(&mut fut2) });
|
||||
|
||||
// TODO: Once `Waker::noop` stablised and our MSRV is bumped to the version
|
||||
// which it is stablised, replace this with `Waker::noop`.
|
||||
let waker = unsafe { Waker::from_raw(NOOP_RAW_WAKER) };
|
||||
let mut context = Context::from_waker(&waker);
|
||||
|
||||
let mut backoff_cnt = 0;
|
||||
|
||||
loop {
|
||||
has_made_progress.set(false);
|
||||
|
||||
if let Some(fut) = fut2.as_mut() {
|
||||
if let Poll::Ready(res) = fut.as_mut().poll(&mut context) {
|
||||
fut2 = None;
|
||||
res?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(fut) = fut1.as_mut() {
|
||||
if let Poll::Ready(res) = fut.as_mut().poll(&mut context) {
|
||||
fut1 = None;
|
||||
res?;
|
||||
}
|
||||
}
|
||||
|
||||
if fut1.is_none() && fut2.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if !has_made_progress.get() {
|
||||
if backoff_cnt > 3 {
|
||||
// We have yielded at least three times without making'
|
||||
// any progress, so we will sleep for a while.
|
||||
let duration = Duration::from_millis(100 * (backoff_cnt - 3).min(10));
|
||||
thread::sleep(duration);
|
||||
} else {
|
||||
// Given that we spawned a lot of compilation tasks, it is unlikely
|
||||
// that OS cannot find other ready task to execute.
|
||||
//
|
||||
// If all of them are done, then we will yield them and spawn more,
|
||||
// or simply return.
|
||||
//
|
||||
// Thus this will not be turned into a busy-wait loop and it will not
|
||||
// waste CPU resource.
|
||||
thread::yield_now();
|
||||
}
|
||||
}
|
||||
|
||||
backoff_cnt = if has_made_progress.get() {
|
||||
0
|
||||
} else {
|
||||
backoff_cnt + 1
|
||||
};
|
||||
}
|
||||
}
|
||||
273
vendor/cc/src/parallel/job_token.rs
vendored
Normal file
273
vendor/cc/src/parallel/job_token.rs
vendored
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::Error;
|
||||
|
||||
use super::once_lock::OnceLock;
|
||||
|
||||
pub(crate) struct JobToken(PhantomData<()>);
|
||||
|
||||
impl JobToken {
|
||||
fn new() -> Self {
|
||||
Self(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for JobToken {
|
||||
fn drop(&mut self) {
|
||||
match JobTokenServer::new() {
|
||||
JobTokenServer::Inherited(jobserver) => jobserver.release_token_raw(),
|
||||
JobTokenServer::InProcess(jobserver) => jobserver.release_token_raw(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum JobTokenServer {
|
||||
Inherited(inherited_jobserver::JobServer),
|
||||
InProcess(inprocess_jobserver::JobServer),
|
||||
}
|
||||
|
||||
impl JobTokenServer {
|
||||
/// This function returns a static reference to the jobserver because
|
||||
/// - creating a jobserver from env is a bit fd-unsafe (e.g. the fd might
|
||||
/// be closed by other jobserver users in the process) and better do it
|
||||
/// at the start of the program.
|
||||
/// - in case a jobserver cannot be created from env (e.g. it's not
|
||||
/// present), we will create a global in-process only jobserver
|
||||
/// that has to be static so that it will be shared by all cc
|
||||
/// compilation.
|
||||
fn new() -> &'static Self {
|
||||
// TODO: Replace with a OnceLock once MSRV is 1.70
|
||||
static JOBSERVER: OnceLock<JobTokenServer> = OnceLock::new();
|
||||
|
||||
JOBSERVER.get_or_init(|| {
|
||||
unsafe { inherited_jobserver::JobServer::from_env() }
|
||||
.map(Self::Inherited)
|
||||
.unwrap_or_else(|| Self::InProcess(inprocess_jobserver::JobServer::new()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum ActiveJobTokenServer {
|
||||
Inherited(inherited_jobserver::ActiveJobServer<'static>),
|
||||
InProcess(&'static inprocess_jobserver::JobServer),
|
||||
}
|
||||
|
||||
impl ActiveJobTokenServer {
|
||||
pub(crate) fn new() -> Self {
|
||||
match JobTokenServer::new() {
|
||||
JobTokenServer::Inherited(inherited_jobserver) => {
|
||||
Self::Inherited(inherited_jobserver.enter_active())
|
||||
}
|
||||
JobTokenServer::InProcess(inprocess_jobserver) => Self::InProcess(inprocess_jobserver),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn acquire(&mut self) -> Result<JobToken, Error> {
|
||||
match self {
|
||||
Self::Inherited(jobserver) => jobserver.acquire().await,
|
||||
Self::InProcess(jobserver) => Ok(jobserver.acquire().await),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod inherited_jobserver {
|
||||
use super::JobToken;
|
||||
|
||||
use crate::{parallel::async_executor::YieldOnce, Error, ErrorKind};
|
||||
|
||||
use std::{
|
||||
io, mem,
|
||||
sync::{mpsc, Mutex, MutexGuard, PoisonError},
|
||||
};
|
||||
|
||||
pub(super) struct JobServer {
|
||||
/// Implicit token for this process which is obtained and will be
|
||||
/// released in parent. Since JobTokens only give back what they got,
|
||||
/// there should be at most one global implicit token in the wild.
|
||||
///
|
||||
/// Since Rust does not execute any `Drop` for global variables,
|
||||
/// we can't just put it back to jobserver and then re-acquire it at
|
||||
/// the end of the process.
|
||||
///
|
||||
/// Use `Mutex` to avoid race between acquire and release.
|
||||
/// If an `AtomicBool` is used, then it's possible for:
|
||||
/// - `release_token_raw`: Tries to set `global_implicit_token` to true, but it is already
|
||||
/// set to `true`, continue to release it to jobserver
|
||||
/// - `acquire` takes the global implicit token, set `global_implicit_token` to false
|
||||
/// - `release_token_raw` now writes the token back into the jobserver, while
|
||||
/// `global_implicit_token` is `false`
|
||||
///
|
||||
/// If the program exits here, then cc effectively increases parallelism by one, which is
|
||||
/// incorrect, hence we use a `Mutex` here.
|
||||
global_implicit_token: Mutex<bool>,
|
||||
inner: jobserver::Client,
|
||||
}
|
||||
|
||||
impl JobServer {
|
||||
pub(super) unsafe fn from_env() -> Option<Self> {
|
||||
jobserver::Client::from_env().map(|inner| Self {
|
||||
inner,
|
||||
global_implicit_token: Mutex::new(true),
|
||||
})
|
||||
}
|
||||
|
||||
fn get_global_implicit_token(&self) -> MutexGuard<'_, bool> {
|
||||
self.global_implicit_token
|
||||
.lock()
|
||||
.unwrap_or_else(PoisonError::into_inner)
|
||||
}
|
||||
|
||||
/// All tokens except for the global implicit token will be put back into the jobserver
|
||||
/// immediately and they cannot be cached, since Rust does not call `Drop::drop` on
|
||||
/// global variables.
|
||||
pub(super) fn release_token_raw(&self) {
|
||||
let mut global_implicit_token = self.get_global_implicit_token();
|
||||
|
||||
if *global_implicit_token {
|
||||
// There's already a global implicit token, so this token must
|
||||
// be released back into jobserver.
|
||||
//
|
||||
// `release_raw` should not block
|
||||
let _ = self.inner.release_raw();
|
||||
} else {
|
||||
*global_implicit_token = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn enter_active(&self) -> ActiveJobServer<'_> {
|
||||
ActiveJobServer {
|
||||
jobserver: self,
|
||||
helper_thread: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HelperThread {
|
||||
inner: jobserver::HelperThread,
|
||||
/// When rx is dropped, all the token stored within it will be dropped.
|
||||
rx: mpsc::Receiver<io::Result<jobserver::Acquired>>,
|
||||
}
|
||||
|
||||
impl HelperThread {
|
||||
fn new(jobserver: &JobServer) -> Result<Self, Error> {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
Ok(Self {
|
||||
rx,
|
||||
inner: jobserver.inner.clone().into_helper_thread(move |res| {
|
||||
let _ = tx.send(res);
|
||||
})?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ActiveJobServer<'a> {
|
||||
jobserver: &'a JobServer,
|
||||
helper_thread: Option<HelperThread>,
|
||||
}
|
||||
|
||||
impl<'a> ActiveJobServer<'a> {
|
||||
pub(super) async fn acquire(&mut self) -> Result<JobToken, Error> {
|
||||
let mut has_requested_token = false;
|
||||
|
||||
loop {
|
||||
// Fast path
|
||||
if mem::replace(&mut *self.jobserver.get_global_implicit_token(), false) {
|
||||
break Ok(JobToken::new());
|
||||
}
|
||||
|
||||
match self.jobserver.inner.try_acquire() {
|
||||
Ok(Some(acquired)) => {
|
||||
acquired.drop_without_releasing();
|
||||
break Ok(JobToken::new());
|
||||
}
|
||||
Ok(None) => YieldOnce::default().await,
|
||||
Err(err) if err.kind() == io::ErrorKind::Unsupported => {
|
||||
// Fallback to creating a help thread with blocking acquire
|
||||
let helper_thread = if let Some(thread) = self.helper_thread.as_ref() {
|
||||
thread
|
||||
} else {
|
||||
self.helper_thread
|
||||
.insert(HelperThread::new(self.jobserver)?)
|
||||
};
|
||||
|
||||
match helper_thread.rx.try_recv() {
|
||||
Ok(res) => {
|
||||
let acquired = res?;
|
||||
acquired.drop_without_releasing();
|
||||
break Ok(JobToken::new());
|
||||
}
|
||||
Err(mpsc::TryRecvError::Disconnected) => break Err(Error::new(
|
||||
ErrorKind::JobserverHelpThreadError,
|
||||
"jobserver help thread has returned before ActiveJobServer is dropped",
|
||||
)),
|
||||
Err(mpsc::TryRecvError::Empty) => {
|
||||
if !has_requested_token {
|
||||
helper_thread.inner.request_token();
|
||||
has_requested_token = true;
|
||||
}
|
||||
YieldOnce::default().await
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => break Err(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod inprocess_jobserver {
|
||||
use super::JobToken;
|
||||
|
||||
use crate::parallel::async_executor::YieldOnce;
|
||||
|
||||
use std::{
|
||||
env::var,
|
||||
sync::atomic::{
|
||||
AtomicU32,
|
||||
Ordering::{AcqRel, Acquire},
|
||||
},
|
||||
};
|
||||
|
||||
pub(crate) struct JobServer(AtomicU32);
|
||||
|
||||
impl JobServer {
|
||||
pub(super) fn new() -> Self {
|
||||
// Use `NUM_JOBS` if set (it's configured by Cargo) and otherwise
|
||||
// just fall back to a semi-reasonable number.
|
||||
//
|
||||
// Note that we could use `num_cpus` here but it's an extra
|
||||
// dependency that will almost never be used, so
|
||||
// it's generally not too worth it.
|
||||
let mut parallelism = 4;
|
||||
// TODO: Use std::thread::available_parallelism as an upper bound
|
||||
// when MSRV is bumped.
|
||||
if let Ok(amt) = var("NUM_JOBS") {
|
||||
if let Ok(amt) = amt.parse() {
|
||||
parallelism = amt;
|
||||
}
|
||||
}
|
||||
|
||||
Self(AtomicU32::new(parallelism))
|
||||
}
|
||||
|
||||
pub(super) async fn acquire(&self) -> JobToken {
|
||||
loop {
|
||||
let res = self
|
||||
.0
|
||||
.fetch_update(AcqRel, Acquire, |tokens| tokens.checked_sub(1));
|
||||
|
||||
if res.is_ok() {
|
||||
break JobToken::new();
|
||||
}
|
||||
|
||||
YieldOnce::default().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn release_token_raw(&self) {
|
||||
self.0.fetch_add(1, AcqRel);
|
||||
}
|
||||
}
|
||||
}
|
||||
4
vendor/cc/src/parallel/mod.rs
vendored
Normal file
4
vendor/cc/src/parallel/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub(crate) mod async_executor;
|
||||
pub(crate) mod job_token;
|
||||
pub(crate) mod once_lock;
|
||||
pub(crate) mod stderr;
|
||||
47
vendor/cc/src/parallel/once_lock.rs
vendored
Normal file
47
vendor/cc/src/parallel/once_lock.rs
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use std::{
|
||||
cell::UnsafeCell,
|
||||
marker::PhantomData,
|
||||
mem::MaybeUninit,
|
||||
panic::{RefUnwindSafe, UnwindSafe},
|
||||
sync::Once,
|
||||
};
|
||||
|
||||
pub(crate) struct OnceLock<T> {
|
||||
once: Once,
|
||||
value: UnsafeCell<MaybeUninit<T>>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> OnceLock<T> {
|
||||
pub(crate) const fn new() -> Self {
|
||||
Self {
|
||||
once: Once::new(),
|
||||
value: UnsafeCell::new(MaybeUninit::uninit()),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_or_init(&self, f: impl FnOnce() -> T) -> &T {
|
||||
self.once.call_once(|| {
|
||||
unsafe { &mut *self.value.get() }.write(f());
|
||||
});
|
||||
unsafe { (&*self.value.get()).assume_init_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Sync + Send> Sync for OnceLock<T> {}
|
||||
unsafe impl<T: Send> Send for OnceLock<T> {}
|
||||
|
||||
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {}
|
||||
impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
|
||||
|
||||
impl<T> Drop for OnceLock<T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
if self.once.is_completed() {
|
||||
// SAFETY: The cell is initialized and being dropped, so it can't
|
||||
// be accessed again.
|
||||
unsafe { self.value.get_mut().assume_init_drop() };
|
||||
}
|
||||
}
|
||||
}
|
||||
91
vendor/cc/src/parallel/stderr.rs
vendored
Normal file
91
vendor/cc/src/parallel/stderr.rs
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#![cfg_attr(target_family = "wasm", allow(unused))]
|
||||
/// Helpers functions for [ChildStderr].
|
||||
use std::{convert::TryInto, process::ChildStderr};
|
||||
|
||||
use crate::{Error, ErrorKind};
|
||||
|
||||
#[cfg(all(not(unix), not(windows), not(target_family = "wasm")))]
|
||||
compile_error!("Only unix and windows support non-blocking pipes! For other OSes, disable the parallel feature.");
|
||||
|
||||
#[cfg(unix)]
|
||||
fn get_flags(fd: std::os::unix::io::RawFd) -> Result<i32, Error> {
|
||||
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL, 0) };
|
||||
if flags == -1 {
|
||||
Err(Error::new(
|
||||
ErrorKind::IOError,
|
||||
format!(
|
||||
"Failed to get flags for pipe {}: {}",
|
||||
fd,
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
))
|
||||
} else {
|
||||
Ok(flags)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn set_flags(fd: std::os::unix::io::RawFd, flags: std::os::raw::c_int) -> Result<(), Error> {
|
||||
if unsafe { libc::fcntl(fd, libc::F_SETFL, flags) } == -1 {
|
||||
Err(Error::new(
|
||||
ErrorKind::IOError,
|
||||
format!(
|
||||
"Failed to set flags for pipe {}: {}",
|
||||
fd,
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn set_non_blocking(pipe: &impl std::os::unix::io::AsRawFd) -> Result<(), Error> {
|
||||
// On Unix, switch the pipe to non-blocking mode.
|
||||
// On Windows, we have a different way to be non-blocking.
|
||||
let fd = pipe.as_raw_fd();
|
||||
|
||||
let flags = get_flags(fd)?;
|
||||
set_flags(fd, flags | libc::O_NONBLOCK)
|
||||
}
|
||||
|
||||
pub fn bytes_available(stderr: &mut ChildStderr) -> Result<usize, Error> {
|
||||
let mut bytes_available = 0;
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use crate::windows::windows_sys::PeekNamedPipe;
|
||||
use std::os::windows::io::AsRawHandle;
|
||||
use std::ptr::null_mut;
|
||||
if unsafe {
|
||||
PeekNamedPipe(
|
||||
stderr.as_raw_handle(),
|
||||
null_mut(),
|
||||
0,
|
||||
null_mut(),
|
||||
&mut bytes_available,
|
||||
null_mut(),
|
||||
)
|
||||
} == 0
|
||||
{
|
||||
return Err(Error::new(
|
||||
ErrorKind::IOError,
|
||||
format!(
|
||||
"PeekNamedPipe failed with {}",
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::io::AsRawFd;
|
||||
if unsafe { libc::ioctl(stderr.as_raw_fd(), libc::FIONREAD, &mut bytes_available) } != 0 {
|
||||
return Err(Error::new(
|
||||
ErrorKind::IOError,
|
||||
format!("ioctl failed with {}", std::io::Error::last_os_error()),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(bytes_available.try_into().unwrap())
|
||||
}
|
||||
29
vendor/cc/src/target_info.rs
vendored
Normal file
29
vendor/cc/src/target_info.rs
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! This file is generated code. Please edit the generator
|
||||
//! in dev-tools/gen-target-info if you need to make changes.
|
||||
|
||||
pub const RISCV_ARCH_MAPPING: &[(&str, &str)] = &[
|
||||
("riscv32e", "riscv32"),
|
||||
("riscv32em", "riscv32"),
|
||||
("riscv32emc", "riscv32"),
|
||||
("riscv32gc", "riscv32"),
|
||||
("riscv32i", "riscv32"),
|
||||
("riscv32im", "riscv32"),
|
||||
("riscv32ima", "riscv32"),
|
||||
("riscv32imac", "riscv32"),
|
||||
("riscv32imafc", "riscv32"),
|
||||
("riscv32imc", "riscv32"),
|
||||
("riscv64gc", "riscv64"),
|
||||
("riscv64imac", "riscv64"),
|
||||
];
|
||||
pub const WINDOWS_TRIPLE_MAPPING: &[(&str, &str)] = &[
|
||||
("aarch64-pc-windows-gnullvm", "aarch64-pc-windows-gnu"),
|
||||
("aarch64-uwp-windows-msvc", "aarch64-pc-windows-msvc"),
|
||||
("i686-pc-windows-gnullvm", "i686-pc-windows-gnu"),
|
||||
("i686-uwp-windows-gnu", "i686-pc-windows-gnu"),
|
||||
("i686-uwp-windows-msvc", "i686-pc-windows-msvc"),
|
||||
("i686-win7-windows-msvc", "i686-pc-windows-msvc"),
|
||||
("thumbv7a-uwp-windows-msvc", "thumbv7a-pc-windows-msvc"),
|
||||
("x86_64-pc-windows-gnullvm", "x86_64-pc-windows-gnu"),
|
||||
("x86_64-uwp-windows-gnu", "x86_64-pc-windows-gnu"),
|
||||
("x86_64-uwp-windows-msvc", "x86_64-pc-windows-msvc"),
|
||||
];
|
||||
86
vendor/cc/src/tempfile.rs
vendored
Normal file
86
vendor/cc/src/tempfile.rs
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#![cfg_attr(target_family = "wasm", allow(unused))]
|
||||
|
||||
use std::{
|
||||
collections::hash_map::RandomState,
|
||||
fs::{remove_file, File, OpenOptions},
|
||||
hash::{BuildHasher, Hasher},
|
||||
io, os,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[cfg(not(any(unix, target_family = "wasm", windows)))]
|
||||
compile_error!("Your system is not supported since cc cannot create named tempfile");
|
||||
|
||||
fn rand() -> u64 {
|
||||
RandomState::new().build_hasher().finish()
|
||||
}
|
||||
|
||||
fn tmpname(suffix: &str) -> String {
|
||||
format!("{}{}", rand(), suffix)
|
||||
}
|
||||
|
||||
fn create_named(path: &Path) -> io::Result<File> {
|
||||
let mut open_options = OpenOptions::new();
|
||||
|
||||
open_options.read(true).write(true).create_new(true);
|
||||
|
||||
#[cfg(all(unix, not(target_os = "wasi")))]
|
||||
<OpenOptions as os::unix::fs::OpenOptionsExt>::mode(&mut open_options, 0o600);
|
||||
|
||||
#[cfg(windows)]
|
||||
<OpenOptions as os::windows::fs::OpenOptionsExt>::custom_flags(
|
||||
&mut open_options,
|
||||
crate::windows::windows_sys::FILE_ATTRIBUTE_TEMPORARY,
|
||||
);
|
||||
|
||||
open_options.open(path)
|
||||
}
|
||||
|
||||
pub(super) struct NamedTempfile {
|
||||
path: PathBuf,
|
||||
file: Option<File>,
|
||||
}
|
||||
|
||||
impl NamedTempfile {
|
||||
pub(super) fn new(base: &Path, suffix: &str) -> io::Result<Self> {
|
||||
for _ in 0..10 {
|
||||
let path = base.join(tmpname(suffix));
|
||||
match create_named(&path) {
|
||||
Ok(file) => {
|
||||
return Ok(Self {
|
||||
file: Some(file),
|
||||
path,
|
||||
})
|
||||
}
|
||||
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
}
|
||||
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::AlreadyExists,
|
||||
format!(
|
||||
"too many temporary files exist in base `{}` with suffix `{}`",
|
||||
base.display(),
|
||||
suffix
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub(super) fn path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub(super) fn take_file(&mut self) -> Option<File> {
|
||||
self.file.take()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for NamedTempfile {
|
||||
fn drop(&mut self) {
|
||||
// On Windows you have to close all handle to it before
|
||||
// removing the file.
|
||||
self.file.take();
|
||||
let _ = remove_file(&self.path);
|
||||
}
|
||||
}
|
||||
476
vendor/cc/src/tool.rs
vendored
Normal file
476
vendor/cc/src/tool.rs
vendored
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashMap,
|
||||
env,
|
||||
ffi::{OsStr, OsString},
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
sync::RwLock,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
command_helpers::{run_output, CargoOutput},
|
||||
run,
|
||||
tempfile::NamedTempfile,
|
||||
Error, ErrorKind, OutputKind,
|
||||
};
|
||||
|
||||
/// Configuration used to represent an invocation of a C compiler.
|
||||
///
|
||||
/// This can be used to figure out what compiler is in use, what the arguments
|
||||
/// to it are, and what the environment variables look like for the compiler.
|
||||
/// This can be used to further configure other build systems (e.g. forward
|
||||
/// along CC and/or CFLAGS) or the `to_command` method can be used to run the
|
||||
/// compiler itself.
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Tool {
|
||||
pub(crate) path: PathBuf,
|
||||
pub(crate) cc_wrapper_path: Option<PathBuf>,
|
||||
pub(crate) cc_wrapper_args: Vec<OsString>,
|
||||
pub(crate) args: Vec<OsString>,
|
||||
pub(crate) env: Vec<(OsString, OsString)>,
|
||||
pub(crate) family: ToolFamily,
|
||||
pub(crate) cuda: bool,
|
||||
pub(crate) removed_args: Vec<OsString>,
|
||||
pub(crate) has_internal_target_arg: bool,
|
||||
}
|
||||
|
||||
impl Tool {
|
||||
pub(crate) fn new(
|
||||
path: PathBuf,
|
||||
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
|
||||
cargo_output: &CargoOutput,
|
||||
out_dir: Option<&Path>,
|
||||
) -> Self {
|
||||
Self::with_features(
|
||||
path,
|
||||
None,
|
||||
false,
|
||||
cached_compiler_family,
|
||||
cargo_output,
|
||||
out_dir,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn with_clang_driver(
|
||||
path: PathBuf,
|
||||
clang_driver: Option<&str>,
|
||||
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
|
||||
cargo_output: &CargoOutput,
|
||||
out_dir: Option<&Path>,
|
||||
) -> Self {
|
||||
Self::with_features(
|
||||
path,
|
||||
clang_driver,
|
||||
false,
|
||||
cached_compiler_family,
|
||||
cargo_output,
|
||||
out_dir,
|
||||
)
|
||||
}
|
||||
|
||||
/// Explicitly set the `ToolFamily`, skipping name-based detection.
|
||||
pub(crate) fn with_family(path: PathBuf, family: ToolFamily) -> Self {
|
||||
Self {
|
||||
path,
|
||||
cc_wrapper_path: None,
|
||||
cc_wrapper_args: Vec::new(),
|
||||
args: Vec::new(),
|
||||
env: Vec::new(),
|
||||
family,
|
||||
cuda: false,
|
||||
removed_args: Vec::new(),
|
||||
has_internal_target_arg: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn with_features(
|
||||
path: PathBuf,
|
||||
clang_driver: Option<&str>,
|
||||
cuda: bool,
|
||||
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
|
||||
cargo_output: &CargoOutput,
|
||||
out_dir: Option<&Path>,
|
||||
) -> Self {
|
||||
fn is_zig_cc(path: &Path, cargo_output: &CargoOutput) -> bool {
|
||||
run_output(
|
||||
Command::new(path).arg("--version"),
|
||||
path,
|
||||
// tool detection issues should always be shown as warnings
|
||||
cargo_output,
|
||||
)
|
||||
.map(|o| String::from_utf8_lossy(&o).contains("ziglang"))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn detect_family_inner(
|
||||
path: &Path,
|
||||
cargo_output: &CargoOutput,
|
||||
out_dir: Option<&Path>,
|
||||
) -> Result<ToolFamily, Error> {
|
||||
let out_dir = out_dir
|
||||
.map(Cow::Borrowed)
|
||||
.unwrap_or_else(|| Cow::Owned(env::temp_dir()));
|
||||
|
||||
// Ensure all the parent directories exist otherwise temp file creation
|
||||
// will fail
|
||||
std::fs::create_dir_all(&out_dir).map_err(|err| Error {
|
||||
kind: ErrorKind::IOError,
|
||||
message: format!("failed to create OUT_DIR '{}': {}", out_dir.display(), err)
|
||||
.into(),
|
||||
})?;
|
||||
|
||||
let mut tmp =
|
||||
NamedTempfile::new(&out_dir, "detect_compiler_family.c").map_err(|err| Error {
|
||||
kind: ErrorKind::IOError,
|
||||
message: format!(
|
||||
"failed to create detect_compiler_family.c temp file in '{}': {}",
|
||||
out_dir.display(),
|
||||
err
|
||||
)
|
||||
.into(),
|
||||
})?;
|
||||
let mut tmp_file = tmp.take_file().unwrap();
|
||||
tmp_file.write_all(include_bytes!("detect_compiler_family.c"))?;
|
||||
// Close the file handle *now*, otherwise the compiler may fail to open it on Windows
|
||||
// (#1082). The file stays on disk and its path remains valid until `tmp` is dropped.
|
||||
tmp_file.flush()?;
|
||||
tmp_file.sync_data()?;
|
||||
drop(tmp_file);
|
||||
|
||||
let stdout = run_output(
|
||||
Command::new(path).arg("-E").arg(tmp.path()),
|
||||
path,
|
||||
// When expanding the file, the compiler prints a lot of information to stderr
|
||||
// that it is not an error, but related to expanding itself.
|
||||
//
|
||||
// cc would have to disable warning here to prevent generation of too many warnings.
|
||||
&{
|
||||
let mut cargo_output = cargo_output.clone();
|
||||
cargo_output.warnings = cargo_output.debug;
|
||||
cargo_output
|
||||
},
|
||||
)?;
|
||||
let stdout = String::from_utf8_lossy(&stdout);
|
||||
|
||||
cargo_output.print_debug(&stdout);
|
||||
|
||||
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
|
||||
let accepts_cl_style_flags = run(Command::new(path).arg("-?"), path, &{
|
||||
// the errors are not errors!
|
||||
let mut cargo_output = cargo_output.clone();
|
||||
cargo_output.warnings = cargo_output.debug;
|
||||
cargo_output.output = OutputKind::Discard;
|
||||
cargo_output
|
||||
})
|
||||
.is_ok();
|
||||
|
||||
let clang = stdout.contains(r#""clang""#);
|
||||
let gcc = stdout.contains(r#""gcc""#);
|
||||
let emscripten = stdout.contains(r#""emscripten""#);
|
||||
let vxworks = stdout.contains(r#""VxWorks""#);
|
||||
|
||||
match (clang, accepts_cl_style_flags, gcc, emscripten, vxworks) {
|
||||
(clang_cl, true, _, false, false) => Ok(ToolFamily::Msvc { clang_cl }),
|
||||
(true, _, _, _, false) | (_, _, _, true, false) => Ok(ToolFamily::Clang {
|
||||
zig_cc: is_zig_cc(path, cargo_output),
|
||||
}),
|
||||
(false, false, true, _, false) | (_, _, _, _, true) => Ok(ToolFamily::Gnu),
|
||||
(false, false, false, false, false) => {
|
||||
cargo_output.print_warning(&"Compiler family detection failed since it does not define `__clang__`, `__GNUC__`, `__EMSCRIPTEN__` or `__VXWORKS__`, also does not accept cl style flag `-?`, fallback to treating it as GNU");
|
||||
Err(Error::new(
|
||||
ErrorKind::ToolFamilyMacroNotFound,
|
||||
"Expects macro `__clang__`, `__GNUC__` or `__EMSCRIPTEN__`, `__VXWORKS__` or accepts cl style flag `-?`, but found none",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
let detect_family = |path: &Path| -> Result<ToolFamily, Error> {
|
||||
if let Some(family) = cached_compiler_family.read().unwrap().get(path) {
|
||||
return Ok(*family);
|
||||
}
|
||||
|
||||
let family = detect_family_inner(path, cargo_output, out_dir)?;
|
||||
cached_compiler_family
|
||||
.write()
|
||||
.unwrap()
|
||||
.insert(path.into(), family);
|
||||
Ok(family)
|
||||
};
|
||||
|
||||
let family = detect_family(&path).unwrap_or_else(|e| {
|
||||
cargo_output.print_warning(&format_args!(
|
||||
"Compiler family detection failed due to error: {}",
|
||||
e
|
||||
));
|
||||
match path.file_name().map(OsStr::to_string_lossy) {
|
||||
Some(fname) if fname.contains("clang-cl") => ToolFamily::Msvc { clang_cl: true },
|
||||
Some(fname) if fname.ends_with("cl") || fname == "cl.exe" => {
|
||||
ToolFamily::Msvc { clang_cl: false }
|
||||
}
|
||||
Some(fname) if fname.contains("clang") => match clang_driver {
|
||||
Some("cl") => ToolFamily::Msvc { clang_cl: true },
|
||||
_ => ToolFamily::Clang {
|
||||
zig_cc: is_zig_cc(&path, cargo_output),
|
||||
},
|
||||
},
|
||||
Some(fname) if fname.contains("zig") => ToolFamily::Clang { zig_cc: true },
|
||||
_ => ToolFamily::Gnu,
|
||||
}
|
||||
});
|
||||
|
||||
Tool {
|
||||
path,
|
||||
cc_wrapper_path: None,
|
||||
cc_wrapper_args: Vec::new(),
|
||||
args: Vec::new(),
|
||||
env: Vec::new(),
|
||||
family,
|
||||
cuda,
|
||||
removed_args: Vec::new(),
|
||||
has_internal_target_arg: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add an argument to be stripped from the final command arguments.
|
||||
pub(crate) fn remove_arg(&mut self, flag: OsString) {
|
||||
self.removed_args.push(flag);
|
||||
}
|
||||
|
||||
/// Push an "exotic" flag to the end of the compiler's arguments list.
|
||||
///
|
||||
/// Nvidia compiler accepts only the most common compiler flags like `-D`,
|
||||
/// `-I`, `-c`, etc. Options meant specifically for the underlying
|
||||
/// host C++ compiler have to be prefixed with `-Xcompiler`.
|
||||
/// [Another possible future application for this function is passing
|
||||
/// clang-specific flags to clang-cl, which otherwise accepts only
|
||||
/// MSVC-specific options.]
|
||||
pub(crate) fn push_cc_arg(&mut self, flag: OsString) {
|
||||
if self.cuda {
|
||||
self.args.push("-Xcompiler".into());
|
||||
}
|
||||
self.args.push(flag);
|
||||
}
|
||||
|
||||
/// Checks if an argument or flag has already been specified or conflicts.
|
||||
///
|
||||
/// Currently only checks optimization flags.
|
||||
pub(crate) fn is_duplicate_opt_arg(&self, flag: &OsString) -> bool {
|
||||
let flag = flag.to_str().unwrap();
|
||||
let mut chars = flag.chars();
|
||||
|
||||
// Only duplicate check compiler flags
|
||||
if self.is_like_msvc() {
|
||||
if chars.next() != Some('/') {
|
||||
return false;
|
||||
}
|
||||
} else if (self.is_like_gnu() || self.is_like_clang()) && chars.next() != Some('-') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for existing optimization flags (-O, /O)
|
||||
if chars.next() == Some('O') {
|
||||
return self
|
||||
.args()
|
||||
.iter()
|
||||
.any(|a| a.to_str().unwrap_or("").chars().nth(1) == Some('O'));
|
||||
}
|
||||
|
||||
// TODO Check for existing -m..., -m...=..., /arch:... flags
|
||||
false
|
||||
}
|
||||
|
||||
/// Don't push optimization arg if it conflicts with existing args.
|
||||
pub(crate) fn push_opt_unless_duplicate(&mut self, flag: OsString) {
|
||||
if self.is_duplicate_opt_arg(&flag) {
|
||||
eprintln!("Info: Ignoring duplicate arg {:?}", &flag);
|
||||
} else {
|
||||
self.push_cc_arg(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this compiler into a `Command` that's ready to be run.
|
||||
///
|
||||
/// This is useful for when the compiler needs to be executed and the
|
||||
/// command returned will already have the initial arguments and environment
|
||||
/// variables configured.
|
||||
pub fn to_command(&self) -> Command {
|
||||
let mut cmd = match self.cc_wrapper_path {
|
||||
Some(ref cc_wrapper_path) => {
|
||||
let mut cmd = Command::new(cc_wrapper_path);
|
||||
cmd.arg(&self.path);
|
||||
cmd
|
||||
}
|
||||
None => Command::new(&self.path),
|
||||
};
|
||||
cmd.args(&self.cc_wrapper_args);
|
||||
|
||||
let value = self
|
||||
.args
|
||||
.iter()
|
||||
.filter(|a| !self.removed_args.contains(a))
|
||||
.collect::<Vec<_>>();
|
||||
cmd.args(&value);
|
||||
|
||||
for (k, v) in self.env.iter() {
|
||||
cmd.env(k, v);
|
||||
}
|
||||
cmd
|
||||
}
|
||||
|
||||
/// Returns the path for this compiler.
|
||||
///
|
||||
/// Note that this may not be a path to a file on the filesystem, e.g. "cc",
|
||||
/// but rather something which will be resolved when a process is spawned.
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
/// Returns the default set of arguments to the compiler needed to produce
|
||||
/// executables for the target this compiler generates.
|
||||
pub fn args(&self) -> &[OsString] {
|
||||
&self.args
|
||||
}
|
||||
|
||||
/// Returns the set of environment variables needed for this compiler to
|
||||
/// operate.
|
||||
///
|
||||
/// This is typically only used for MSVC compilers currently.
|
||||
pub fn env(&self) -> &[(OsString, OsString)] {
|
||||
&self.env
|
||||
}
|
||||
|
||||
/// Returns the compiler command in format of CC environment variable.
|
||||
/// Or empty string if CC env was not present
|
||||
///
|
||||
/// This is typically used by configure script
|
||||
pub fn cc_env(&self) -> OsString {
|
||||
match self.cc_wrapper_path {
|
||||
Some(ref cc_wrapper_path) => {
|
||||
let mut cc_env = cc_wrapper_path.as_os_str().to_owned();
|
||||
cc_env.push(" ");
|
||||
cc_env.push(self.path.to_path_buf().into_os_string());
|
||||
for arg in self.cc_wrapper_args.iter() {
|
||||
cc_env.push(" ");
|
||||
cc_env.push(arg);
|
||||
}
|
||||
cc_env
|
||||
}
|
||||
None => OsString::from(""),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the compiler flags in format of CFLAGS environment variable.
|
||||
/// Important here - this will not be CFLAGS from env, its internal gcc's flags to use as CFLAGS
|
||||
/// This is typically used by configure script
|
||||
pub fn cflags_env(&self) -> OsString {
|
||||
let mut flags = OsString::new();
|
||||
for (i, arg) in self.args.iter().enumerate() {
|
||||
if i > 0 {
|
||||
flags.push(" ");
|
||||
}
|
||||
flags.push(arg);
|
||||
}
|
||||
flags
|
||||
}
|
||||
|
||||
/// Whether the tool is GNU Compiler Collection-like.
|
||||
pub fn is_like_gnu(&self) -> bool {
|
||||
self.family == ToolFamily::Gnu
|
||||
}
|
||||
|
||||
/// Whether the tool is Clang-like.
|
||||
pub fn is_like_clang(&self) -> bool {
|
||||
matches!(self.family, ToolFamily::Clang { .. })
|
||||
}
|
||||
|
||||
/// Whether the tool is AppleClang under .xctoolchain
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub(crate) fn is_xctoolchain_clang(&self) -> bool {
|
||||
let path = self.path.to_string_lossy();
|
||||
path.contains(".xctoolchain/")
|
||||
}
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub(crate) fn is_xctoolchain_clang(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether the tool is MSVC-like.
|
||||
pub fn is_like_msvc(&self) -> bool {
|
||||
matches!(self.family, ToolFamily::Msvc { .. })
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the family of tools this tool belongs to.
|
||||
///
|
||||
/// Each family of tools differs in how and what arguments they accept.
|
||||
///
|
||||
/// Detection of a family is done on best-effort basis and may not accurately reflect the tool.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ToolFamily {
|
||||
/// Tool is GNU Compiler Collection-like.
|
||||
Gnu,
|
||||
/// Tool is Clang-like. It differs from the GCC in a sense that it accepts superset of flags
|
||||
/// and its cross-compilation approach is different.
|
||||
Clang { zig_cc: bool },
|
||||
/// Tool is the MSVC cl.exe.
|
||||
Msvc { clang_cl: bool },
|
||||
}
|
||||
|
||||
impl ToolFamily {
|
||||
/// What the flag to request debug info for this family of tools look like
|
||||
pub(crate) fn add_debug_flags(&self, cmd: &mut Tool, dwarf_version: Option<u32>) {
|
||||
match *self {
|
||||
ToolFamily::Msvc { .. } => {
|
||||
cmd.push_cc_arg("-Z7".into());
|
||||
}
|
||||
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
|
||||
cmd.push_cc_arg(
|
||||
dwarf_version
|
||||
.map_or_else(|| "-g".into(), |v| format!("-gdwarf-{}", v))
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// What the flag to force frame pointers.
|
||||
pub(crate) fn add_force_frame_pointer(&self, cmd: &mut Tool) {
|
||||
match *self {
|
||||
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
|
||||
cmd.push_cc_arg("-fno-omit-frame-pointer".into());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// What the flags to enable all warnings
|
||||
pub(crate) fn warnings_flags(&self) -> &'static str {
|
||||
match *self {
|
||||
ToolFamily::Msvc { .. } => "-W4",
|
||||
ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Wall",
|
||||
}
|
||||
}
|
||||
|
||||
/// What the flags to enable extra warnings
|
||||
pub(crate) fn extra_warnings_flags(&self) -> Option<&'static str> {
|
||||
match *self {
|
||||
ToolFamily::Msvc { .. } => None,
|
||||
ToolFamily::Gnu | ToolFamily::Clang { .. } => Some("-Wextra"),
|
||||
}
|
||||
}
|
||||
|
||||
/// What the flag to turn warning into errors
|
||||
pub(crate) fn warnings_to_errors_flag(&self) -> &'static str {
|
||||
match *self {
|
||||
ToolFamily::Msvc { .. } => "-WX",
|
||||
ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Werror",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn verbose_stderr(&self) -> bool {
|
||||
matches!(*self, ToolFamily::Clang { .. })
|
||||
}
|
||||
}
|
||||
45
vendor/cc/src/utilities.rs
vendored
Normal file
45
vendor/cc/src/utilities.rs
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
use std::{
|
||||
ffi::OsStr,
|
||||
fmt::{self, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
pub(super) struct JoinOsStrs<'a, T> {
|
||||
pub(super) slice: &'a [T],
|
||||
pub(super) delimiter: char,
|
||||
}
|
||||
|
||||
impl<T> fmt::Display for JoinOsStrs<'_, T>
|
||||
where
|
||||
T: AsRef<OsStr>,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let len = self.slice.len();
|
||||
for (index, os_str) in self.slice.iter().enumerate() {
|
||||
// TODO: Use OsStr::display once it is stablised,
|
||||
// Path and OsStr has the same `Display` impl
|
||||
write!(f, "{}", Path::new(os_str).display())?;
|
||||
if index + 1 < len {
|
||||
f.write_char(self.delimiter)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct OptionOsStrDisplay<T>(pub(super) Option<T>);
|
||||
|
||||
impl<T> fmt::Display for OptionOsStrDisplay<T>
|
||||
where
|
||||
T: AsRef<OsStr>,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// TODO: Use OsStr::display once it is stablised
|
||||
// Path and OsStr has the same `Display` impl
|
||||
if let Some(os_str) = self.0.as_ref() {
|
||||
write!(f, "Some({})", Path::new(os_str).display())
|
||||
} else {
|
||||
f.write_str("None")
|
||||
}
|
||||
}
|
||||
}
|
||||
110
vendor/cc/src/windows/com.rs
vendored
Normal file
110
vendor/cc/src/windows/com.rs
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright © 2017 winapi-rs developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
||||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::windows::{
|
||||
winapi::{IUnknown, Interface},
|
||||
windows_sys::{
|
||||
CoInitializeEx, SysFreeString, SysStringLen, BSTR, COINIT_MULTITHREADED, HRESULT, S_FALSE,
|
||||
S_OK,
|
||||
},
|
||||
};
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
ffi::OsString,
|
||||
ops::Deref,
|
||||
os::windows::ffi::OsStringExt,
|
||||
ptr::{null, null_mut},
|
||||
slice::from_raw_parts,
|
||||
};
|
||||
|
||||
pub fn initialize() -> Result<(), HRESULT> {
|
||||
let err = unsafe { CoInitializeEx(null(), COINIT_MULTITHREADED.try_into().unwrap()) };
|
||||
if err != S_OK && err != S_FALSE {
|
||||
// S_FALSE just means COM is already initialized
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ComPtr<T>(*mut T)
|
||||
where
|
||||
T: Interface;
|
||||
impl<T> ComPtr<T>
|
||||
where
|
||||
T: Interface,
|
||||
{
|
||||
/// Creates a `ComPtr` to wrap a raw pointer.
|
||||
/// It takes ownership over the pointer which means it does __not__ call `AddRef`.
|
||||
/// `T` __must__ be a COM interface that inherits from `IUnknown`.
|
||||
pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
|
||||
assert!(!ptr.is_null());
|
||||
ComPtr(ptr)
|
||||
}
|
||||
/// For internal use only.
|
||||
fn as_unknown(&self) -> &IUnknown {
|
||||
unsafe { &*(self.0 as *mut IUnknown) }
|
||||
}
|
||||
/// Performs `QueryInterface` fun.
|
||||
pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>
|
||||
where
|
||||
U: Interface,
|
||||
{
|
||||
let mut obj = null_mut();
|
||||
let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(unsafe { ComPtr::from_raw(obj as *mut U) })
|
||||
}
|
||||
}
|
||||
impl<T> Deref for ComPtr<T>
|
||||
where
|
||||
T: Interface,
|
||||
{
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { &*self.0 }
|
||||
}
|
||||
}
|
||||
impl<T> Clone for ComPtr<T>
|
||||
where
|
||||
T: Interface,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
self.as_unknown().AddRef();
|
||||
ComPtr::from_raw(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> Drop for ComPtr<T>
|
||||
where
|
||||
T: Interface,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.as_unknown().Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct BStr(BSTR);
|
||||
impl BStr {
|
||||
pub unsafe fn from_raw(s: BSTR) -> BStr {
|
||||
BStr(s)
|
||||
}
|
||||
pub fn to_osstring(&self) -> OsString {
|
||||
let len = unsafe { SysStringLen(self.0) };
|
||||
let slice = unsafe { from_raw_parts(self.0, len as usize) };
|
||||
OsStringExt::from_wide(slice)
|
||||
}
|
||||
}
|
||||
impl Drop for BStr {
|
||||
fn drop(&mut self) {
|
||||
unsafe { SysFreeString(self.0) };
|
||||
}
|
||||
}
|
||||
1191
vendor/cc/src/windows/find_tools.rs
vendored
Normal file
1191
vendor/cc/src/windows/find_tools.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
22
vendor/cc/src/windows/mod.rs
vendored
Normal file
22
vendor/cc/src/windows/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//! These modules are all glue to support reading the MSVC version from
|
||||
//! the registry and from COM interfaces.
|
||||
|
||||
// This is used in the crate's public API, so don't use #[cfg(windows)]
|
||||
pub mod find_tools;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) mod windows_sys;
|
||||
#[cfg(windows)]
|
||||
mod windows_targets;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod registry;
|
||||
#[cfg(windows)]
|
||||
#[macro_use]
|
||||
mod winapi;
|
||||
#[cfg(windows)]
|
||||
mod com;
|
||||
#[cfg(windows)]
|
||||
mod setup_config;
|
||||
#[cfg(windows)]
|
||||
mod vs_instances;
|
||||
191
vendor/cc/src/windows/registry.rs
vendored
Normal file
191
vendor/cc/src/windows/registry.rs
vendored
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::windows::windows_sys::{
|
||||
RegCloseKey, RegEnumKeyExW, RegOpenKeyExW, RegQueryValueExW, ERROR_NO_MORE_ITEMS,
|
||||
ERROR_SUCCESS, HKEY, HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, REG_SZ,
|
||||
};
|
||||
use std::{
|
||||
ffi::{OsStr, OsString},
|
||||
io,
|
||||
ops::RangeFrom,
|
||||
os::windows::prelude::*,
|
||||
ptr::null_mut,
|
||||
};
|
||||
|
||||
/// Must never be `HKEY_PERFORMANCE_DATA`.
|
||||
pub(crate) struct RegistryKey(Repr);
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
type DWORD = u32;
|
||||
|
||||
struct OwnedKey(HKEY);
|
||||
|
||||
/// Note: must not encode `HKEY_PERFORMANCE_DATA` or one of its subkeys.
|
||||
enum Repr {
|
||||
/// `HKEY_LOCAL_MACHINE`.
|
||||
LocalMachine,
|
||||
/// A subkey of `HKEY_LOCAL_MACHINE`.
|
||||
Owned(OwnedKey),
|
||||
}
|
||||
|
||||
pub struct Iter<'a> {
|
||||
idx: RangeFrom<DWORD>,
|
||||
key: &'a RegistryKey,
|
||||
}
|
||||
|
||||
unsafe impl Sync for Repr {}
|
||||
unsafe impl Send for Repr {}
|
||||
|
||||
pub(crate) const LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::LocalMachine);
|
||||
|
||||
impl RegistryKey {
|
||||
fn raw(&self) -> HKEY {
|
||||
match self.0 {
|
||||
Repr::LocalMachine => HKEY_LOCAL_MACHINE,
|
||||
Repr::Owned(ref val) => val.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Open a sub-key of `self`.
|
||||
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
|
||||
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
||||
let mut ret = null_mut();
|
||||
let err = unsafe {
|
||||
RegOpenKeyExW(
|
||||
self.raw(),
|
||||
key.as_ptr(),
|
||||
0,
|
||||
KEY_READ | KEY_WOW64_32KEY,
|
||||
&mut ret,
|
||||
)
|
||||
};
|
||||
if err == ERROR_SUCCESS {
|
||||
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(err as i32))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter {
|
||||
Iter {
|
||||
idx: 0..,
|
||||
key: self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query_str(&self, name: &str) -> io::Result<OsString> {
|
||||
let name: &OsStr = name.as_ref();
|
||||
let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
||||
let mut len = 0;
|
||||
let mut kind = 0;
|
||||
unsafe {
|
||||
let err = RegQueryValueExW(
|
||||
self.raw(),
|
||||
name.as_ptr(),
|
||||
null_mut(),
|
||||
&mut kind,
|
||||
null_mut(),
|
||||
&mut len,
|
||||
);
|
||||
if err != ERROR_SUCCESS {
|
||||
return Err(io::Error::from_raw_os_error(err as i32));
|
||||
}
|
||||
if kind != REG_SZ {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"registry key wasn't a string",
|
||||
));
|
||||
}
|
||||
|
||||
// The length here is the length in bytes, but we're using wide
|
||||
// characters so we need to be sure to halve it for the length
|
||||
// passed in.
|
||||
assert!(len % 2 == 0, "impossible wide string size: {} bytes", len);
|
||||
let vlen = len as usize / 2;
|
||||
// Defensively initialized, see comment about
|
||||
// `HKEY_PERFORMANCE_DATA` below.
|
||||
let mut v = vec![0u16; vlen];
|
||||
let err = RegQueryValueExW(
|
||||
self.raw(),
|
||||
name.as_ptr(),
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
v.as_mut_ptr() as *mut _,
|
||||
&mut len,
|
||||
);
|
||||
// We don't check for `ERROR_MORE_DATA` (which would if the value
|
||||
// grew between the first and second call to `RegQueryValueExW`),
|
||||
// both because it's extremely unlikely, and this is a bit more
|
||||
// defensive more defensive against weird types of registry keys.
|
||||
if err != ERROR_SUCCESS {
|
||||
return Err(io::Error::from_raw_os_error(err as i32));
|
||||
}
|
||||
// The length is allowed to change, but should still be even, as
|
||||
// well as smaller.
|
||||
assert!(len % 2 == 0, "impossible wide string size: {} bytes", len);
|
||||
// If the length grew but returned a success code, it *probably*
|
||||
// indicates we're `HKEY_PERFORMANCE_DATA` or a subkey(?). We
|
||||
// consider this UB, since those keys write "undefined" or
|
||||
// "unpredictable" values to len, and need to use a completely
|
||||
// different loop structure. This should be impossible (and enforce
|
||||
// it in the API to the best of our ability), but to mitigate the
|
||||
// damage we do some smoke-checks on the len, and ensure `v` has
|
||||
// been fully initialized (rather than trusting the result of
|
||||
// `RegQueryValueExW`).
|
||||
let actual_len = len as usize / 2;
|
||||
assert!(actual_len <= v.len());
|
||||
v.truncate(actual_len);
|
||||
// Some registry keys may have a terminating nul character, but
|
||||
// we're not interested in that, so chop it off if it's there.
|
||||
if !v.is_empty() && v[v.len() - 1] == 0 {
|
||||
v.pop();
|
||||
}
|
||||
Ok(OsString::from_wide(&v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OwnedKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
RegCloseKey(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = io::Result<OsString>;
|
||||
|
||||
fn next(&mut self) -> Option<io::Result<OsString>> {
|
||||
self.idx.next().and_then(|i| unsafe {
|
||||
let mut v = Vec::with_capacity(256);
|
||||
let mut len = v.capacity() as DWORD;
|
||||
let ret = RegEnumKeyExW(
|
||||
self.key.raw(),
|
||||
i,
|
||||
v.as_mut_ptr(),
|
||||
&mut len,
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
);
|
||||
if ret == ERROR_NO_MORE_ITEMS {
|
||||
None
|
||||
} else if ret != ERROR_SUCCESS {
|
||||
Some(Err(io::Error::from_raw_os_error(ret as i32)))
|
||||
} else {
|
||||
v.set_len(len as usize);
|
||||
Some(Ok(OsString::from_wide(&v)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
283
vendor/cc/src/windows/setup_config.rs
vendored
Normal file
283
vendor/cc/src/windows/setup_config.rs
vendored
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
// Copyright © 2017 winapi-rs developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
||||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(bad_style)]
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::windows::{
|
||||
com::{BStr, ComPtr},
|
||||
winapi::{
|
||||
IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY,
|
||||
PULONGLONG, ULONG,
|
||||
},
|
||||
windows_sys::{CoCreateInstance, BSTR, CLSCTX_ALL, HRESULT, S_FALSE},
|
||||
};
|
||||
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
ptr::{null, null_mut},
|
||||
};
|
||||
|
||||
// Bindings to the Setup.Configuration stuff
|
||||
pub type InstanceState = u32;
|
||||
|
||||
pub const eNone: InstanceState = 0;
|
||||
pub const eLocal: InstanceState = 1;
|
||||
pub const eRegistered: InstanceState = 2;
|
||||
pub const eNoRebootRequired: InstanceState = 4;
|
||||
pub const eComplete: InstanceState = -1i32 as u32;
|
||||
|
||||
RIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)]
|
||||
interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) {
|
||||
fn GetInstanceId(
|
||||
pbstrInstanceId: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetInstallDate(
|
||||
pInstallDate: LPFILETIME,
|
||||
) -> HRESULT,
|
||||
fn GetInstallationName(
|
||||
pbstrInstallationName: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetInstallationPath(
|
||||
pbstrInstallationPath: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetInstallationVersion(
|
||||
pbstrInstallationVersion: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetDisplayName(
|
||||
lcid: LCID,
|
||||
pbstrDisplayName: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetDescription(
|
||||
lcid: LCID,
|
||||
pbstrDescription: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn ResolvePath(
|
||||
pwszRelativePath: LPCOLESTR,
|
||||
pbstrAbsolutePath: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)]
|
||||
interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) {
|
||||
fn GetState(
|
||||
pState: *mut InstanceState,
|
||||
) -> HRESULT,
|
||||
fn GetPackages(
|
||||
ppsaPackages: *mut LPSAFEARRAY,
|
||||
) -> HRESULT,
|
||||
fn GetProduct(
|
||||
ppPackage: *mut *mut ISetupPackageReference,
|
||||
) -> HRESULT,
|
||||
fn GetProductPath(
|
||||
pbstrProductPath: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)]
|
||||
interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) {
|
||||
fn Next(
|
||||
celt: ULONG,
|
||||
rgelt: *mut *mut ISetupInstance,
|
||||
pceltFetched: *mut ULONG,
|
||||
) -> HRESULT,
|
||||
fn Skip(
|
||||
celt: ULONG,
|
||||
) -> HRESULT,
|
||||
fn Reset() -> HRESULT,
|
||||
fn Clone(
|
||||
ppenum: *mut *mut IEnumSetupInstances,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)]
|
||||
interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) {
|
||||
fn EnumInstances(
|
||||
ppEnumInstances: *mut *mut IEnumSetupInstances,
|
||||
) -> HRESULT,
|
||||
fn GetInstanceForCurrentProcess(
|
||||
ppInstance: *mut *mut ISetupInstance,
|
||||
) -> HRESULT,
|
||||
fn GetInstanceForPath(
|
||||
wzPath: LPCWSTR,
|
||||
ppInstance: *mut *mut ISetupInstance,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)]
|
||||
interface ISetupConfiguration2(ISetupConfiguration2Vtbl):
|
||||
ISetupConfiguration(ISetupConfigurationVtbl) {
|
||||
fn EnumAllInstances(
|
||||
ppEnumInstances: *mut *mut IEnumSetupInstances,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)]
|
||||
interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) {
|
||||
fn GetId(
|
||||
pbstrId: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetVersion(
|
||||
pbstrVersion: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetChip(
|
||||
pbstrChip: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetLanguage(
|
||||
pbstrLanguage: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetBranch(
|
||||
pbstrBranch: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetType(
|
||||
pbstrType: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
fn GetUniqueId(
|
||||
pbstrUniqueId: *mut BSTR,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
RIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)]
|
||||
interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) {
|
||||
fn ParseVersion(
|
||||
pwszVersion: LPCOLESTR,
|
||||
pullVersion: PULONGLONG,
|
||||
) -> HRESULT,
|
||||
fn ParseVersionRange(
|
||||
pwszVersionRange: LPCOLESTR,
|
||||
pullMinVersion: PULONGLONG,
|
||||
pullMaxVersion: PULONGLONG,
|
||||
) -> HRESULT,
|
||||
}}
|
||||
|
||||
DEFINE_GUID! {CLSID_SetupConfiguration,
|
||||
0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}
|
||||
|
||||
// Safe wrapper around the COM interfaces
|
||||
pub struct SetupConfiguration(ComPtr<ISetupConfiguration>);
|
||||
|
||||
impl SetupConfiguration {
|
||||
pub fn new() -> Result<SetupConfiguration, i32> {
|
||||
let mut obj = null_mut();
|
||||
let err = unsafe {
|
||||
CoCreateInstance(
|
||||
&CLSID_SetupConfiguration,
|
||||
null_mut(),
|
||||
CLSCTX_ALL,
|
||||
&ISetupConfiguration::uuidof(),
|
||||
&mut obj,
|
||||
)
|
||||
};
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) };
|
||||
Ok(SetupConfiguration(obj))
|
||||
}
|
||||
pub fn get_instance_for_current_process(&self) -> Result<SetupInstance, i32> {
|
||||
let mut obj = null_mut();
|
||||
let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(unsafe { SetupInstance::from_raw(obj) })
|
||||
}
|
||||
pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> {
|
||||
let mut obj = null_mut();
|
||||
let err = unsafe { self.0.EnumInstances(&mut obj) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
|
||||
}
|
||||
pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> {
|
||||
let mut obj = null_mut();
|
||||
let this = self.0.cast::<ISetupConfiguration2>()?;
|
||||
let err = unsafe { this.EnumAllInstances(&mut obj) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetupInstance(ComPtr<ISetupInstance>);
|
||||
|
||||
impl SetupInstance {
|
||||
pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance {
|
||||
SetupInstance(ComPtr::from_raw(obj))
|
||||
}
|
||||
pub fn instance_id(&self) -> Result<OsString, i32> {
|
||||
let mut s = null();
|
||||
let err = unsafe { self.0.GetInstanceId(&mut s) };
|
||||
let bstr = unsafe { BStr::from_raw(s) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(bstr.to_osstring())
|
||||
}
|
||||
pub fn installation_name(&self) -> Result<OsString, i32> {
|
||||
let mut s = null();
|
||||
let err = unsafe { self.0.GetInstallationName(&mut s) };
|
||||
let bstr = unsafe { BStr::from_raw(s) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(bstr.to_osstring())
|
||||
}
|
||||
pub fn installation_path(&self) -> Result<OsString, i32> {
|
||||
let mut s = null();
|
||||
let err = unsafe { self.0.GetInstallationPath(&mut s) };
|
||||
let bstr = unsafe { BStr::from_raw(s) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(bstr.to_osstring())
|
||||
}
|
||||
pub fn installation_version(&self) -> Result<OsString, i32> {
|
||||
let mut s = null();
|
||||
let err = unsafe { self.0.GetInstallationVersion(&mut s) };
|
||||
let bstr = unsafe { BStr::from_raw(s) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(bstr.to_osstring())
|
||||
}
|
||||
pub fn product_path(&self) -> Result<OsString, i32> {
|
||||
let mut s = null();
|
||||
let this = self.0.cast::<ISetupInstance2>()?;
|
||||
let err = unsafe { this.GetProductPath(&mut s) };
|
||||
let bstr = unsafe { BStr::from_raw(s) };
|
||||
if err < 0 {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(bstr.to_osstring())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>);
|
||||
|
||||
impl EnumSetupInstances {
|
||||
pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances {
|
||||
EnumSetupInstances(ComPtr::from_raw(obj))
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for EnumSetupInstances {
|
||||
type Item = Result<SetupInstance, i32>;
|
||||
fn next(&mut self) -> Option<Result<SetupInstance, i32>> {
|
||||
let mut obj = null_mut();
|
||||
let err = unsafe { self.0.Next(1, &mut obj, null_mut()) };
|
||||
if err < 0 {
|
||||
return Some(Err(err));
|
||||
}
|
||||
if err == S_FALSE {
|
||||
return None;
|
||||
}
|
||||
Some(Ok(unsafe { SetupInstance::from_raw(obj) }))
|
||||
}
|
||||
}
|
||||
199
vendor/cc/src/windows/vs_instances.rs
vendored
Normal file
199
vendor/cc/src/windows/vs_instances.rs
vendored
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::BufRead;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::windows::setup_config::{EnumSetupInstances, SetupInstance};
|
||||
|
||||
pub enum VsInstance {
|
||||
Com(SetupInstance),
|
||||
Vswhere(VswhereInstance),
|
||||
}
|
||||
|
||||
impl VsInstance {
|
||||
pub fn installation_name(&self) -> Option<Cow<str>> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s
|
||||
.installation_name()
|
||||
.ok()
|
||||
.and_then(|s| s.into_string().ok())
|
||||
.map(Cow::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationName").map(Cow::from),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn installation_path(&self) -> Option<PathBuf> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s.installation_path().ok().map(PathBuf::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationPath").map(PathBuf::from),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn installation_version(&self) -> Option<Cow<str>> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s
|
||||
.installation_version()
|
||||
.ok()
|
||||
.and_then(|s| s.into_string().ok())
|
||||
.map(Cow::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationVersion").map(Cow::from),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum VsInstances {
|
||||
ComBased(EnumSetupInstances),
|
||||
VswhereBased(VswhereInstance),
|
||||
}
|
||||
|
||||
impl IntoIterator for VsInstances {
|
||||
type Item = VsInstance;
|
||||
#[allow(bare_trait_objects)]
|
||||
type IntoIter = Box<Iterator<Item = Self::Item>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
match self {
|
||||
VsInstances::ComBased(e) => {
|
||||
Box::new(e.into_iter().filter_map(Result::ok).map(VsInstance::Com))
|
||||
}
|
||||
VsInstances::VswhereBased(v) => Box::new(std::iter::once(VsInstance::Vswhere(v))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VswhereInstance {
|
||||
map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Vec<u8>> for VswhereInstance {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(output: &Vec<u8>) -> Result<Self, Self::Error> {
|
||||
let map: HashMap<_, _> = output
|
||||
.lines()
|
||||
.map_while(Result::ok)
|
||||
.filter_map(|s| {
|
||||
let mut splitn = s.splitn(2, ": ");
|
||||
Some((splitn.next()?.to_owned(), splitn.next()?.to_owned()))
|
||||
})
|
||||
.collect();
|
||||
|
||||
if !map.contains_key("installationName")
|
||||
|| !map.contains_key("installationPath")
|
||||
|| !map.contains_key("installationVersion")
|
||||
{
|
||||
return Err("required properties not found");
|
||||
}
|
||||
|
||||
Ok(Self { map })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests_ {
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[test]
|
||||
fn it_parses_vswhere_output_correctly() {
|
||||
let output = br"instanceId: 58104422
|
||||
installDate: 21/02/2021 21:50:33
|
||||
installationName: VisualStudio/16.9.2+31112.23
|
||||
installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
|
||||
installationVersion: 16.9.31112.23
|
||||
productId: Microsoft.VisualStudio.Product.BuildTools
|
||||
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
|
||||
state: 4294967295
|
||||
isComplete: 1
|
||||
isLaunchable: 1
|
||||
isPrerelease: 0
|
||||
isRebootRequired: 0
|
||||
displayName: Visual Studio Build Tools 2019
|
||||
description: The Visual Studio Build Tools allows you to build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support.
|
||||
channelId: VisualStudio.16.Release
|
||||
channelUri: https://aka.ms/vs/16/release/channel
|
||||
enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
|
||||
releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.2
|
||||
thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909
|
||||
updateDate: 2021-03-17T21:16:46.5963702Z
|
||||
catalog_buildBranch: d16.9
|
||||
catalog_buildVersion: 16.9.31112.23
|
||||
catalog_id: VisualStudio/16.9.2+31112.23
|
||||
catalog_localBuild: build-lab
|
||||
catalog_manifestName: VisualStudio
|
||||
catalog_manifestType: installer
|
||||
catalog_productDisplayVersion: 16.9.2
|
||||
catalog_productLine: Dev16
|
||||
catalog_productLineVersion: 2019
|
||||
catalog_productMilestone: RTW
|
||||
catalog_productMilestoneIsPreRelease: False
|
||||
catalog_productName: Visual Studio
|
||||
catalog_productPatchVersion: 2
|
||||
catalog_productPreReleaseMilestoneSuffix: 1.0
|
||||
catalog_productSemanticVersion: 16.9.2+31112.23
|
||||
catalog_requiredEngineVersion: 2.9.3365.38425
|
||||
properties_campaignId: 156063665.1613940062
|
||||
properties_channelManifestId: VisualStudio.16.Release/16.9.2+31112.23
|
||||
properties_nickname:
|
||||
properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installershell.exe
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
assert!(vswhere_instance.is_ok());
|
||||
|
||||
let vs_instance = super::VsInstance::Vswhere(vswhere_instance.unwrap());
|
||||
assert_eq!(
|
||||
vs_instance.installation_name(),
|
||||
Some(Cow::from("VisualStudio/16.9.2+31112.23"))
|
||||
);
|
||||
assert_eq!(
|
||||
vs_instance.installation_path(),
|
||||
Some(PathBuf::from(
|
||||
r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
vs_instance.installation_version(),
|
||||
Some(Cow::from("16.9.31112.23"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_empty_output() {
|
||||
let output = b"".to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_output_consisting_of_empty_lines() {
|
||||
let output = br"
|
||||
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_output_without_required_properties() {
|
||||
let output = br"instanceId: 58104422
|
||||
installDate: 21/02/2021 21:50:33
|
||||
productId: Microsoft.VisualStudio.Product.BuildTools
|
||||
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
}
|
||||
146
vendor/cc/src/windows/winapi.rs
vendored
Normal file
146
vendor/cc/src/windows/winapi.rs
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright © 2015-2017 winapi-rs developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
||||
// All files in the project carrying such notice may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(bad_style, clippy::upper_case_acronyms)]
|
||||
|
||||
use std::os::raw;
|
||||
|
||||
pub type wchar_t = u16;
|
||||
|
||||
pub use crate::windows::windows_sys::{FILETIME, GUID, HRESULT, SAFEARRAY};
|
||||
|
||||
pub type REFIID = *const IID;
|
||||
pub type IID = GUID;
|
||||
pub type ULONG = raw::c_ulong;
|
||||
pub type DWORD = u32;
|
||||
pub type LPFILETIME = *mut FILETIME;
|
||||
pub type OLECHAR = WCHAR;
|
||||
pub type WCHAR = wchar_t;
|
||||
pub type LPCOLESTR = *const OLECHAR;
|
||||
pub type LCID = DWORD;
|
||||
pub type LPCWSTR = *const WCHAR;
|
||||
pub type PULONGLONG = *mut ULONGLONG;
|
||||
pub type ULONGLONG = u64;
|
||||
|
||||
pub trait Interface {
|
||||
fn uuidof() -> GUID;
|
||||
}
|
||||
|
||||
pub type LPSAFEARRAY = *mut SAFEARRAY;
|
||||
|
||||
macro_rules! DEFINE_GUID {
|
||||
(
|
||||
$name:ident, $l:expr, $w1:expr, $w2:expr,
|
||||
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
|
||||
) => {
|
||||
pub const $name: $crate::windows::winapi::GUID = $crate::windows::winapi::GUID {
|
||||
data1: $l,
|
||||
data2: $w1,
|
||||
data3: $w2,
|
||||
data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! RIDL {
|
||||
(#[uuid($($uuid:expr),+)]
|
||||
interface $interface:ident ($vtbl:ident) {$(
|
||||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
|
||||
)+}) => (
|
||||
#[repr(C)]
|
||||
pub struct $vtbl {
|
||||
$(pub $method: unsafe extern "system" fn(
|
||||
This: *mut $interface,
|
||||
$($p: $t),*
|
||||
) -> $rtr,)+
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct $interface {
|
||||
pub lpVtbl: *const $vtbl,
|
||||
}
|
||||
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
|
||||
RIDL!{@uuid $interface $($uuid),+}
|
||||
);
|
||||
(#[uuid($($uuid:expr),+)]
|
||||
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {
|
||||
}) => (
|
||||
#[repr(C)]
|
||||
pub struct $vtbl {
|
||||
pub parent: $pvtbl,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct $interface {
|
||||
pub lpVtbl: *const $vtbl,
|
||||
}
|
||||
RIDL!{@deref $interface $pinterface}
|
||||
RIDL!{@uuid $interface $($uuid),+}
|
||||
);
|
||||
(#[uuid($($uuid:expr),+)]
|
||||
interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(
|
||||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
|
||||
)+}) => (
|
||||
#[repr(C)]
|
||||
pub struct $vtbl {
|
||||
pub parent: $pvtbl,
|
||||
$(pub $method: unsafe extern "system" fn(
|
||||
This: *mut $interface,
|
||||
$($p: $t,)*
|
||||
) -> $rtr,)+
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct $interface {
|
||||
pub lpVtbl: *const $vtbl,
|
||||
}
|
||||
RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}
|
||||
RIDL!{@deref $interface $pinterface}
|
||||
RIDL!{@uuid $interface $($uuid),+}
|
||||
);
|
||||
(@deref $interface:ident $pinterface:ident) => (
|
||||
impl ::std::ops::Deref for $interface {
|
||||
type Target = $pinterface;
|
||||
#[inline]
|
||||
fn deref(&self) -> &$pinterface {
|
||||
unsafe { &*(self as *const $interface as *const $pinterface) }
|
||||
}
|
||||
}
|
||||
);
|
||||
(@impl $interface:ident {$(
|
||||
fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,
|
||||
)+}) => (
|
||||
impl $interface {
|
||||
$(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr {
|
||||
((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*)
|
||||
})+
|
||||
}
|
||||
);
|
||||
(@uuid $interface:ident
|
||||
$l:expr, $w1:expr, $w2:expr,
|
||||
$b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr
|
||||
) => (
|
||||
impl $crate::windows::winapi::Interface for $interface {
|
||||
#[inline]
|
||||
fn uuidof() -> $crate::windows::winapi::GUID {
|
||||
$crate::windows::winapi::GUID {
|
||||
data1: $l,
|
||||
data2: $w1,
|
||||
data3: $w2,
|
||||
data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
RIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)]
|
||||
interface IUnknown(IUnknownVtbl) {
|
||||
fn QueryInterface(
|
||||
riid: REFIID,
|
||||
ppvObject: *mut *mut raw::c_void,
|
||||
) -> HRESULT,
|
||||
fn AddRef() -> ULONG,
|
||||
fn Release() -> ULONG,
|
||||
}}
|
||||
121
vendor/cc/src/windows/windows_sys.rs
vendored
Normal file
121
vendor/cc/src/windows/windows_sys.rs
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// This file is autogenerated.
|
||||
//
|
||||
// To add bindings, edit windows_sys.lst then run:
|
||||
//
|
||||
// ```
|
||||
// cd generate-windows-sys/
|
||||
// cargo run
|
||||
// ```
|
||||
// Bindings generated by `windows-bindgen` 0.58.0
|
||||
|
||||
#![allow(
|
||||
non_snake_case,
|
||||
non_upper_case_globals,
|
||||
non_camel_case_types,
|
||||
dead_code,
|
||||
clippy::all
|
||||
)]
|
||||
windows_targets::link!("advapi32.dll" "system" fn RegCloseKey(hkey : HKEY) -> WIN32_ERROR);
|
||||
windows_targets::link!("advapi32.dll" "system" fn RegEnumKeyExW(hkey : HKEY, dwindex : u32, lpname : PWSTR, lpcchname : *mut u32, lpreserved : *const u32, lpclass : PWSTR, lpcchclass : *mut u32, lpftlastwritetime : *mut FILETIME) -> WIN32_ERROR);
|
||||
windows_targets::link!("advapi32.dll" "system" fn RegOpenKeyExW(hkey : HKEY, lpsubkey : PCWSTR, uloptions : u32, samdesired : REG_SAM_FLAGS, phkresult : *mut HKEY) -> WIN32_ERROR);
|
||||
windows_targets::link!("advapi32.dll" "system" fn RegQueryValueExW(hkey : HKEY, lpvaluename : PCWSTR, lpreserved : *const u32, lptype : *mut REG_VALUE_TYPE, lpdata : *mut u8, lpcbdata : *mut u32) -> WIN32_ERROR);
|
||||
windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn GetMachineTypeAttributes(machine : u16, machinetypeattributes : *mut MACHINE_ATTRIBUTES) -> HRESULT);
|
||||
windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC);
|
||||
windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE);
|
||||
windows_targets::link!("kernel32.dll" "system" fn OpenSemaphoreA(dwdesiredaccess : u32, binherithandle : BOOL, lpname : PCSTR) -> HANDLE);
|
||||
windows_targets::link!("kernel32.dll" "system" fn PeekNamedPipe(hnamedpipe : HANDLE, lpbuffer : *mut core::ffi::c_void, nbuffersize : u32, lpbytesread : *mut u32, lptotalbytesavail : *mut u32, lpbytesleftthismessage : *mut u32) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn ReleaseSemaphore(hsemaphore : HANDLE, lreleasecount : i32, lppreviouscount : *mut i32) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
|
||||
windows_targets::link!("ole32.dll" "system" fn CoCreateInstance(rclsid : *const GUID, punkouter : * mut core::ffi::c_void, dwclscontext : CLSCTX, riid : *const GUID, ppv : *mut *mut core::ffi::c_void) -> HRESULT);
|
||||
windows_targets::link!("ole32.dll" "system" fn CoInitializeEx(pvreserved : *const core::ffi::c_void, dwcoinit : u32) -> HRESULT);
|
||||
windows_targets::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR));
|
||||
windows_targets::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32);
|
||||
pub type ADVANCED_FEATURE_FLAGS = u16;
|
||||
pub type BOOL = i32;
|
||||
pub type BSTR = *const u16;
|
||||
pub type CLSCTX = u32;
|
||||
pub const CLSCTX_ALL: CLSCTX = 23u32;
|
||||
pub type COINIT = i32;
|
||||
pub const COINIT_MULTITHREADED: COINIT = 0i32;
|
||||
pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32;
|
||||
pub const ERROR_SUCCESS: WIN32_ERROR = 0u32;
|
||||
pub const FALSE: BOOL = 0i32;
|
||||
pub type FARPROC = Option<unsafe extern "system" fn() -> isize>;
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FILETIME {
|
||||
pub dwLowDateTime: u32,
|
||||
pub dwHighDateTime: u32,
|
||||
}
|
||||
pub const FILE_ATTRIBUTE_TEMPORARY: FILE_FLAGS_AND_ATTRIBUTES = 256u32;
|
||||
pub type FILE_FLAGS_AND_ATTRIBUTES = u32;
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct GUID {
|
||||
pub data1: u32,
|
||||
pub data2: u16,
|
||||
pub data3: u16,
|
||||
pub data4: [u8; 8],
|
||||
}
|
||||
impl GUID {
|
||||
pub const fn from_u128(uuid: u128) -> Self {
|
||||
Self {
|
||||
data1: (uuid >> 96) as u32,
|
||||
data2: (uuid >> 80 & 0xffff) as u16,
|
||||
data3: (uuid >> 64 & 0xffff) as u16,
|
||||
data4: (uuid as u64).to_be_bytes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub type HANDLE = *mut core::ffi::c_void;
|
||||
pub type HKEY = *mut core::ffi::c_void;
|
||||
pub const HKEY_LOCAL_MACHINE: HKEY = -2147483646i32 as _;
|
||||
pub type HMODULE = *mut core::ffi::c_void;
|
||||
pub type HRESULT = i32;
|
||||
pub type IMAGE_FILE_MACHINE = u16;
|
||||
pub const IMAGE_FILE_MACHINE_AMD64: IMAGE_FILE_MACHINE = 34404u16;
|
||||
pub const KEY_READ: REG_SAM_FLAGS = 131097u32;
|
||||
pub const KEY_WOW64_32KEY: REG_SAM_FLAGS = 512u32;
|
||||
pub type MACHINE_ATTRIBUTES = i32;
|
||||
pub type PCSTR = *const u8;
|
||||
pub type PCWSTR = *const u16;
|
||||
pub type PWSTR = *mut u16;
|
||||
pub type REG_SAM_FLAGS = u32;
|
||||
pub const REG_SZ: REG_VALUE_TYPE = 1u32;
|
||||
pub type REG_VALUE_TYPE = u32;
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SAFEARRAY {
|
||||
pub cDims: u16,
|
||||
pub fFeatures: ADVANCED_FEATURE_FLAGS,
|
||||
pub cbElements: u32,
|
||||
pub cLocks: u32,
|
||||
pub pvData: *mut core::ffi::c_void,
|
||||
pub rgsabound: [SAFEARRAYBOUND; 1],
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SAFEARRAYBOUND {
|
||||
pub cElements: u32,
|
||||
pub lLbound: i32,
|
||||
}
|
||||
pub const SEMAPHORE_MODIFY_STATE: SYNCHRONIZATION_ACCESS_RIGHTS = 2u32;
|
||||
pub type SYNCHRONIZATION_ACCESS_RIGHTS = u32;
|
||||
pub const S_FALSE: HRESULT = 0x1_u32 as _;
|
||||
pub const S_OK: HRESULT = 0x0_u32 as _;
|
||||
pub type THREAD_ACCESS_RIGHTS = u32;
|
||||
pub const THREAD_SYNCHRONIZE: THREAD_ACCESS_RIGHTS = 1048576u32;
|
||||
pub const UserEnabled: MACHINE_ATTRIBUTES = 1i32;
|
||||
pub const WAIT_ABANDONED: WAIT_EVENT = 128u32;
|
||||
pub type WAIT_EVENT = u32;
|
||||
pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32;
|
||||
pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32;
|
||||
pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32;
|
||||
pub type WIN32_ERROR = u32;
|
||||
|
||||
#[link(name = "advapi32")]
|
||||
#[link(name = "ole32")]
|
||||
#[link(name = "oleaut32")]
|
||||
extern "C" {}
|
||||
use super::windows_targets;
|
||||
19
vendor/cc/src/windows/windows_targets.rs
vendored
Normal file
19
vendor/cc/src/windows/windows_targets.rs
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//! Provides the `link!` macro used by the generated windows bindings.
|
||||
//!
|
||||
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
|
||||
//! It's very roughly equivalent to the windows-targets crate.
|
||||
|
||||
macro_rules! link_macro {
|
||||
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
|
||||
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
|
||||
// have in this repo. So instead we always link kernel32.lib and add the rest of the import
|
||||
// libraries below by using an empty extern block. This works because extern blocks are not
|
||||
// connected to the library given in the #[link] attribute.
|
||||
#[link(name = "kernel32")]
|
||||
extern $abi {
|
||||
$(#[link_name=$link_name])?
|
||||
pub fn $($function)*;
|
||||
}
|
||||
)
|
||||
}
|
||||
pub(crate) use link_macro as link;
|
||||
Loading…
Add table
Add a link
Reference in a new issue