diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/vcpkg | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/vcpkg')
-rw-r--r-- | third_party/rust/vcpkg/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/vcpkg/Cargo.toml | 28 | ||||
-rw-r--r-- | third_party/rust/vcpkg/src/lib.rs | 532 |
3 files changed, 561 insertions, 0 deletions
diff --git a/third_party/rust/vcpkg/.cargo-checksum.json b/third_party/rust/vcpkg/.cargo-checksum.json new file mode 100644 index 0000000000..3808b3d6b3 --- /dev/null +++ b/third_party/rust/vcpkg/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"0f9d4ef92f867d99dad3a22eca52bb523487dbbf6704b9cc67eca44a9f01b90b","src/lib.rs":"a995e3a7431029dff10764f9e7037670771dbfe8eddc5715fed51fa09d641eb9"},"package":"9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"}
\ No newline at end of file diff --git a/third_party/rust/vcpkg/Cargo.toml b/third_party/rust/vcpkg/Cargo.toml new file mode 100644 index 0000000000..4cc2f41457 --- /dev/null +++ b/third_party/rust/vcpkg/Cargo.toml @@ -0,0 +1,28 @@ +# 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 believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "vcpkg" +version = "0.2.2" +authors = ["Jim McGrath <jimmc2@gmail.com>"] +description = "A library to find native dependencies in a vcpkg tree at build\ntime in order to be used in Cargo build scripts.\n" +documentation = "https://docs.rs/vcpkg" +keywords = ["build-dependencies"] +license = "MIT/Apache-2.0" +repository = "https://github.com/mcgoo/vcpkg-rs" + +[dependencies] +[badges.travis-ci] +repository = "mcgoo/vcpkg-rs" + +[badges.appveyor] +repository = "mcgoo/vcpkg-rs" diff --git a/third_party/rust/vcpkg/src/lib.rs b/third_party/rust/vcpkg/src/lib.rs new file mode 100644 index 0000000000..dbc51f4683 --- /dev/null +++ b/third_party/rust/vcpkg/src/lib.rs @@ -0,0 +1,532 @@ +//! A build dependency for Cargo libraries to find libraries in a
+//! [Vcpkg](https://github.com/Microsoft/vcpkg) tree.
+//!
+//! Note: You must set one of `RUSTFLAGS=-Ctarget-feature=+crt-static` or
+//! `VCPKGRS_DYNAMIC=1` in your environment or the vcpkg-rs helper
+//! will not find any libraries. If `VCPKGRS_DYNAMIC` is set, `cargo install` will
+//! generate dynamically linked binaries, in which case you will have to arrange for
+//! dlls from your Vcpkg installation to be available in your path.
+//!
+//! The simplest possible usage for a library whose Vcpkg port name matches the
+//! name of the lib and DLL that are being looked for looks like this :-
+//!
+//! ```rust,no_run
+//! vcpkg::probe_package("libssh2").unwrap();
+//! ```
+//!
+//! In practice the .lib and .dll often differ in name from the package itself,
+//! in which case the library names must be specified, like this :-
+//!
+//! ```rust,no_run
+//! vcpkg::Config::new()
+//! .lib_names("zlib","zlib1")
+//! .probe("zlib").unwrap();
+//! ```
+//!
+//! If the search was successful all appropriate Cargo metadata will be printed
+//! on stdout.
+//!
+//! The decision to choose static variants of libraries is driven by adding
+//! `RUSTFLAGS=-Ctarget-feature=+crt-static` to the environment. This requires
+//! a nightly compiler but is scheduled to be stable in rustc 1.19.
+//!
+//! A number of environment variables are available to globally configure which
+//! libraries are selected.
+//!
+//! * `VCPKG_ROOT` - Set the directory to look in for a vcpkg installation. If
+//! it is not set, vcpkg will use the user-wide installation if one has been
+//! set up with `vcpkg integrate install`
+//!
+//! * `VCPKGRS_NO_FOO` - if set, vcpkg-rs will not attempt to find the
+//! library named `foo`.
+//!
+//! * `VCPKGRS_DISABLE` - if set, vcpkg-rs will not attempt to find any libraries.
+//!
+//! * `VCPKGRS_DYNAMIC` - if set, vcpkg-rs will link to DLL builds of ports.
+//!
+//! There is a companion crate `vcpkg_cli` that allows testing of environment
+//! and flag combinations.
+//!
+//! ```Batchfile
+//! C:\src> vcpkg_cli probe -l static mysqlclient
+//! Found library mysqlclient
+//! Include paths:
+//! C:\src\diesel_build\vcpkg-dll\installed\x64-windows-static\include
+//! Library paths:
+//! C:\src\diesel_build\vcpkg-dll\installed\x64-windows-static\lib
+//! Cargo metadata:
+//! cargo:rustc-link-search=native=C:\src\diesel_build\vcpkg-dll\installed\x64-windows-static\lib
+//! cargo:rustc-link-lib=static=mysqlclient
+//! ```
+
+use std::ascii::AsciiExt;
+use std::env;
+use std::error;
+use std::fs::{self, File};
+use std::fmt;
+use std::io::{BufRead, BufReader};
+use std::path::{PathBuf, Path};
+
+// #[derive(Clone)]
+pub struct Config {
+ /// should the cargo metadata actually be emitted
+ cargo_metadata: bool,
+
+ /// should cargo:include= metadata be emitted (defaults to false)
+ emit_includes: bool,
+
+ /// libs that must be be found for probing to be considered successful
+ required_libs: Vec<LibNames>,
+
+ /// should DLLs be copies to OUT_DIR?
+ copy_dlls: bool,
+}
+
+#[derive(Debug)]
+pub struct Library {
+ /// Paths for the linker to search for static or import libraries
+ pub link_paths: Vec<PathBuf>,
+
+ /// Paths to search at runtme to find DLLs
+ pub dll_paths: Vec<PathBuf>,
+
+ /// Paths to search for
+ pub include_paths: Vec<PathBuf>,
+
+ /// cargo: metadata lines
+ pub cargo_metadata: Vec<String>,
+
+ /// libraries found are static
+ pub is_static: bool,
+
+ // DLLs found
+ pub found_dlls: Vec<PathBuf>,
+
+ // static libs or import libs found
+ pub found_libs: Vec<PathBuf>,
+}
+
+enum MSVCTarget {
+ X86,
+ X64,
+}
+
+impl fmt::Display for MSVCTarget {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ MSVCTarget::X86 => write!(f, "x86-windows"),
+ MSVCTarget::X64 => write!(f, "x64-windows"),
+ }
+ }
+}
+
+#[derive(Debug)] // need Display?
+pub enum Error {
+ /// Aborted because of a `VCPKGRS_NO_*` environment variable.
+ ///
+ /// Contains the name of the responsible environment variable.
+ DisabledByEnv(String),
+
+ /// Aborted because a required environment variable was not set.
+ RequiredEnvMissing(String),
+
+ /// Only MSVC ABI is supported
+ NotMSVC,
+
+ /// Can't find a vcpkg tree
+ VcpkgNotFound(String),
+
+ /// Library not found in vcpkg tree
+ LibNotFound(String),
+
+ #[doc(hidden)]
+ __Nonexhaustive,
+}
+
+impl error::Error for Error {
+ fn description(&self) -> &str {
+ match *self {
+ Error::DisabledByEnv(_) => "vcpkg-rs requested to be aborted",
+ Error::RequiredEnvMissing(_) => "a required env setting is missing",
+ Error::NotMSVC => "vcpkg-rs only can only find libraries for MSVC ABI 64 bit builds",
+ Error::VcpkgNotFound(_) => "could not find Vcpkg tree",
+ Error::LibNotFound(_) => "could not find library in Vcpkg tree",
+ // Error::LibNotFound(_) => "could not find library in vcpkg tree",
+ Error::__Nonexhaustive => panic!(),
+ }
+ }
+
+ fn cause(&self) -> Option<&error::Error> {
+ match *self {
+ // Error::Command { ref cause, .. } => Some(cause),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ match *self {
+ Error::DisabledByEnv(ref name) => write!(f, "Aborted because {} is set", name),
+ Error::RequiredEnvMissing(ref name) => write!(f, "Aborted because {} is not set", name),
+ Error::NotMSVC => {
+ write!(f,
+ "the vcpkg-rs Vcpkg build helper can only find libraries built for the MSVC ABI.")
+ }
+ Error::VcpkgNotFound(ref detail) => write!(f, "Could not find Vcpkg tree: {}", detail),
+ Error::LibNotFound(ref detail) => {
+ write!(f, "Could not find library in Vcpkg tree {}", detail)
+ }
+ Error::__Nonexhaustive => panic!(),
+ }
+ }
+}
+
+pub fn probe_package(name: &str) -> Result<Library, Error> {
+ Config::new().probe(name)
+}
+
+fn find_vcpkg_root() -> Result<PathBuf, Error> {
+
+ // prefer the setting from the environment is there is one
+ if let Some(path) = env::var_os("VCPKG_ROOT") {
+ return Ok(PathBuf::from(path));
+ }
+
+ // see if there is a per-user vcpkg tree that has been integrated into msbuild
+ // using `vcpkg integrate install`
+ let local_app_data = try!(env::var("LOCALAPPDATA").map_err(|_| {
+ Error::VcpkgNotFound("Failed to read LOCALAPPDATA environment variable".to_string())
+ })); // not present or can't utf8
+ let vcpkg_user_targets_path = Path::new(local_app_data.as_str())
+ .join("vcpkg")
+ .join("vcpkg.user.targets");
+
+ let file = try!(File::open(vcpkg_user_targets_path.clone()).map_err(|_| {
+ Error::VcpkgNotFound("No vcpkg.user.targets found. Set the VCPKG_ROOT environment \
+ variable or run 'vcpkg integrate install'".to_string())
+ }));
+ let file = BufReader::new(&file);
+
+ for line in file.lines() {
+ let line = try!(line.map_err(|_| {
+ Error::VcpkgNotFound(format!("Parsing of {} failed.",
+ vcpkg_user_targets_path
+ .to_string_lossy()
+ .to_owned()))
+ }));
+ let mut split = line.split("Project=\"");
+ split.next(); // eat anything before Project="
+ if let Some(found) = split.next() {
+ // " is illegal in a Windows pathname
+ if let Some(found) = found.split_terminator("\"").next() {
+ let mut vcpkg_root = PathBuf::from(found);
+ if !(vcpkg_root.pop() && vcpkg_root.pop() && vcpkg_root.pop() && vcpkg_root.pop()) {
+ return Err(Error::VcpkgNotFound(format!("Could not find vcpkg root above {}",
+ found)));
+ }
+ return Ok(vcpkg_root);
+ }
+ }
+ }
+
+ Err(Error::VcpkgNotFound(format!("Project location not found parsing {}.",
+ vcpkg_user_targets_path.to_string_lossy().to_owned())))
+}
+
+fn validate_vcpkg_root(path: &PathBuf) -> Result<(), Error> {
+
+ let mut vcpkg_root_path = path.clone();
+ vcpkg_root_path.push(".vcpkg-root");
+
+ if vcpkg_root_path.exists() {
+ Ok(())
+ } else {
+ Err(Error::VcpkgNotFound(format!("Could not find Vcpkg root at {}",
+ vcpkg_root_path.to_string_lossy())))
+ }
+}
+
+/// names of the libraries
+struct LibNames {
+ lib_stem: String,
+ dll_stem: String,
+}
+
+fn find_vcpkg_target(msvc_target: &MSVCTarget) -> Result<VcpkgTarget, Error> {
+
+ let vcpkg_root = try!(find_vcpkg_root());
+ try!(validate_vcpkg_root(&vcpkg_root));
+
+ let static_lib = env::var("CARGO_CFG_TARGET_FEATURE")
+ .unwrap_or(String::new())
+ .contains("crt-static");
+
+ let mut base = vcpkg_root;
+ base.push("installed");
+ let static_appendage = if static_lib { "-static" } else { "" };
+
+ let vcpkg_triple = format!("{}{}", msvc_target.to_string(), static_appendage);
+ base.push(vcpkg_triple);
+
+ let lib_path = base.join("lib");
+ let bin_path = base.join("bin");
+ let include_path = base.join("include");
+
+ Ok(VcpkgTarget {
+ // vcpkg_triple: vcpkg_triple,
+ lib_path: lib_path,
+ bin_path: bin_path,
+ include_path: include_path,
+ is_static: static_lib,
+ })
+}
+
+/// paths and triple for the chosen target
+struct VcpkgTarget {
+ // vcpkg_triple: String,
+ lib_path: PathBuf,
+ bin_path: PathBuf,
+ include_path: PathBuf,
+ is_static: bool,
+}
+
+impl Config {
+ pub fn new() -> Config {
+ Config {
+ cargo_metadata: true,
+ emit_includes: false,
+ required_libs: Vec::new(),
+ copy_dlls: true,
+ }
+ }
+
+ /// Override the name of the library to look for if it differs from the package name.
+ ///
+ /// This may be called more than once if multiple libs are required.
+ /// All libs must be found for the probe to succeed. `.probe()` must
+ /// be run with a different configuration to look for libraries under one of several names.
+ /// `.libname("ssleay32")` will look for ssleay32.lib and also ssleay32.dll if
+ /// dynamic linking is selected.
+ pub fn lib_name(&mut self, lib_stem: &str) -> &mut Config {
+ self.required_libs
+ .push(LibNames {
+ lib_stem: lib_stem.to_owned(),
+ dll_stem: lib_stem.to_owned(),
+ });
+ self
+ }
+
+ /// Override the name of the library to look for if it differs from the package name.
+ ///
+ /// This may be called more than once if multiple libs are required.
+ /// All libs must be found for the probe to succeed. `.probe()` must
+ /// be run with a different configuration to look for libraries under one of several names.
+ /// `.lib_names("libcurl_imp","curl")` will look for libcurl_imp.lib and also curl.dll if
+ /// dynamic linking is selected.
+ pub fn lib_names(&mut self, lib_stem: &str, dll_stem: &str) -> &mut Config {
+ self.required_libs
+ .push(LibNames {
+ lib_stem: lib_stem.to_owned(),
+ dll_stem: dll_stem.to_owned(),
+ });
+ self
+ }
+
+ /// Define whether metadata should be emitted for cargo allowing it to
+ /// automatically link the binary. Defaults to `true`.
+ pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config {
+ self.cargo_metadata = cargo_metadata;
+ self
+ }
+
+ /// Define cargo:include= metadata should be emitted. Defaults to `false`.
+ pub fn emit_includes(&mut self, emit_includes: bool) -> &mut Config {
+ self.emit_includes = emit_includes;
+ self
+ }
+
+ /// Should DLLs be copied to OUT_DIR?
+ /// Defaults to `true`.
+ pub fn copy_dlls(&mut self, copy_dlls: bool) -> &mut Config {
+ self.copy_dlls = copy_dlls;
+ self
+ }
+
+ /// Find the library `port_name` in a Vcpkg tree.
+ ///
+ /// This will use all configuration previously set to select the
+ /// architecture and linkage.
+ pub fn probe(&mut self, port_name: &str) -> Result<Library, Error> {
+
+ // determine the target type, bailing out if it is not some
+ // kind of msvc
+ let msvc_target = try!(msvc_target());
+
+ // bail out if requested to not try at all
+ if env::var_os("VCPKGRS_DISABLE").is_some() {
+ return Err(Error::DisabledByEnv("VCPKGRS_DISABLE".to_owned()));
+ }
+
+ // bail out if requested to not try at all (old)
+ if env::var_os("NO_VCPKG").is_some() {
+ return Err(Error::DisabledByEnv("NO_VCPKG".to_owned()));
+ }
+
+ // bail out if requested to skip this package
+ let abort_var_name = format!("VCPKGRS_NO_{}", envify(port_name));
+ if env::var_os(&abort_var_name).is_some() {
+ return Err(Error::DisabledByEnv(abort_var_name));
+ }
+
+ // bail out if requested to skip this package (old)
+ let abort_var_name = format!("{}_NO_VCPKG", envify(port_name));
+ if env::var_os(&abort_var_name).is_some() {
+ return Err(Error::DisabledByEnv(abort_var_name));
+ }
+
+ // if no overrides have been selected, then the Vcpkg port name
+ // is the the .lib name and the .dll name
+ if self.required_libs.is_empty() {
+ self.required_libs
+ .push(LibNames {
+ lib_stem: port_name.to_owned(),
+ dll_stem: port_name.to_owned(),
+ });
+ }
+
+ let vcpkg_target = try!(find_vcpkg_target(&msvc_target));
+
+ // require explicit opt-in before using dynamically linked
+ // variants, otherwise cargo install of various things will
+ // stop working if Vcpkg is installed.
+ if !vcpkg_target.is_static && !env::var_os("VCPKGRS_DYNAMIC").is_some() {
+ return Err(Error::RequiredEnvMissing("VCPKGRS_DYNAMIC".to_owned()));
+ }
+
+ let mut lib = Library::new(vcpkg_target.is_static);
+
+ if self.emit_includes {
+ lib.cargo_metadata
+ .push(format!("cargo:include={}", vcpkg_target.include_path.display()));
+ }
+ lib.include_paths.push(vcpkg_target.include_path);
+
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-search=native={}",
+ vcpkg_target
+ .lib_path
+ .to_str()
+ .expect("failed to convert string type")));
+ lib.link_paths.push(vcpkg_target.lib_path.clone());
+ if !vcpkg_target.is_static {
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-search=native={}",
+ vcpkg_target
+ .bin_path
+ .to_str()
+ .expect("failed to convert string type")));
+ // this path is dropped by recent version of cargo hence the copies to OUT_DIR below
+ lib.dll_paths.push(vcpkg_target.bin_path.clone());
+ }
+ drop(port_name);
+ for required_lib in &self.required_libs {
+ if vcpkg_target.is_static {
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-lib=static={}", required_lib.lib_stem));
+ } else {
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-lib={}", required_lib.lib_stem));
+ }
+
+ // verify that the library exists
+ let mut lib_location = vcpkg_target.lib_path.clone();
+ lib_location.push(required_lib.lib_stem.clone());
+ lib_location.set_extension("lib");
+
+ if !lib_location.exists() {
+ return Err(Error::LibNotFound(lib_location.display().to_string()));
+ }
+ lib.found_libs.push(lib_location);
+
+ // verify that the DLL exists
+ if !vcpkg_target.is_static {
+ let mut lib_location = vcpkg_target.bin_path.clone();
+ lib_location.push(required_lib.dll_stem.clone());
+ lib_location.set_extension("dll");
+
+ if !lib_location.exists() {
+ return Err(Error::LibNotFound(lib_location.display().to_string()));
+ }
+ lib.found_dlls.push(lib_location);
+ }
+ }
+
+ if self.copy_dlls {
+ if let Some(target_dir) = env::var_os("OUT_DIR") {
+ if !lib.found_dlls.is_empty() {
+ for file in &lib.found_dlls {
+ let mut dest_path = Path::new(target_dir.as_os_str()).to_path_buf();
+ dest_path.push(Path::new(file.file_name().unwrap()));
+ try!(fs::copy(file, &dest_path).map_err(|_| {
+ Error::LibNotFound(format!("Can't copy file {} to {}",
+ file.to_string_lossy(),
+ dest_path.to_string_lossy()))
+ }));
+ println!("vcpkg build helper copied {} to {}",
+ file.to_string_lossy(),
+ dest_path.to_string_lossy());
+ }
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-search=native={}",
+ env::var("OUT_DIR").unwrap()));
+ // work around https://github.com/rust-lang/cargo/issues/3957
+ lib.cargo_metadata
+ .push(format!("cargo:rustc-link-search={}", env::var("OUT_DIR").unwrap()));
+ }
+ } else {
+ return Err(Error::LibNotFound("Unable to get OUT_DIR".to_owned()));
+ }
+ }
+
+ if self.cargo_metadata {
+ for line in &lib.cargo_metadata {
+ println!("{}", line);
+ }
+ }
+ Ok(lib)
+ }
+}
+
+impl Library {
+ pub fn new(is_static: bool) -> Library {
+ Library {
+ link_paths: Vec::new(),
+ dll_paths: Vec::new(),
+ include_paths: Vec::new(),
+ cargo_metadata: Vec::new(),
+ is_static: is_static,
+ found_dlls: Vec::new(),
+ found_libs: Vec::new(),
+ }
+ }
+}
+
+fn envify(name: &str) -> String {
+ name.chars()
+ .map(|c| c.to_ascii_uppercase())
+ .map(|c| if c == '-' { '_' } else { c })
+ .collect()
+}
+
+fn msvc_target() -> Result<MSVCTarget, Error> {
+ let target = env::var("TARGET").unwrap_or(String::new());
+ if !target.contains("-pc-windows-msvc") {
+ Err(Error::NotMSVC)
+ } else if target.starts_with("x86_64-") {
+ Ok(MSVCTarget::X64)
+ } else {
+ // everything else is x86
+ Ok(MSVCTarget::X86)
+ }
+}
|