use vcpkg for MSVC builds
MODIFY
.travis.yml
.travis.yml
@@ -32,8 +32,8 @@ env:
global:
- Atlas_ROOT_DIR=/usr/include/ # for cmake to find lapacke.h
matrix:
- - OPENCV_VERSION=3.4.8 WIN_OPENCV_VERSION=3.4.8 OSX_OPENCV_VERSION=@3 OPENCV_PKGCONFIG=opencv CARGO_FEATURES=opencv-34
- - OPENCV_VERSION=4.1.2 WIN_OPENCV_VERSION=4.1.2 OSX_OPENCV_VERSION= OPENCV_PKGCONFIG=opencv4 CARGO_FEATURES=opencv-41
+ - OPENCV_VERSION=3.4.8 CHOCO_OPENCV_VERSION=3.4.8 OSX_OPENCV_VERSION=@3 OPENCV_PKGCONFIG=opencv CARGO_FEATURES=opencv-34
+ - OPENCV_VERSION=4.1.2 CHOCO_OPENCV_VERSION=4.1.2 OSX_OPENCV_VERSION= OPENCV_PKGCONFIG=opencv4 CARGO_FEATURES=opencv-41
addons:
apt:

MODIFY
Cargo.toml
Cargo.toml
@@ -29,12 +29,17 @@ cc = {version = "1.0", features = ["parallel"]}
cpp_build = "0.5.3"
glob_crate = {package = "glob", version = "0.3"}
once_cell = "1.0"
-pkg-config = "0.3"
rayon = "1.0"
regex = "1.0"
semver = "0.9"
which_crate = {package = "which", version = "3.0", default-features = false}
+[target.'cfg(not(target_env = "msvc"))'.build-dependencies]
+pkg-config = "0.3"
+
+[target.'cfg(target_env = "msvc")'.build-dependencies]
+vcpkg = "0.2"
+
[dev-dependencies]
matches = "0.1"

MODIFY
build.rs
build.rs
@@ -66,14 +66,11 @@ impl Library {
let libs: Vec<_> = link_libs.split(',')
.map(|x| {
let mut path = PathBuf::from(x.trim());
- if path.extension().map(|e| e == "lib" || e == "so" || e == "dylib").unwrap_or(false) {
path.set_extension("");
- }
- let out = path.file_name().and_then(|f| f.to_str()).expect("Invalid library name").to_owned();
- if cfg!(target_env = "msvc") {
- println!("cargo:rustc-link-lib=static={}", out);
- } else {
+ let mut out = path.file_name().and_then(|f| f.to_str()).expect("Invalid library name").to_owned();
println!("cargo:rustc-link-lib={}", out);
+ if cfg!(target_env = "msvc") {
+ out += ".lib";
}
out
})
@@ -101,6 +98,7 @@ impl Library {
let version = include_paths.iter()
.filter_map(get_version_from_headers)
.next();
+
let out = Self {
pkg_name: pkg_name.to_owned(),
libs,
@@ -114,7 +112,8 @@ impl Library {
Ok(out)
}
- fn probe_pkg_config(pkg_name: &str) -> Result<Self> {
+ #[cfg(not(target_env = "msvc"))]
+ fn probe_system(pkg_name: &str) -> Result<Self> {
let opencv = pkg_config::probe_library(pkg_name)?;
Ok(Self {
pkg_name: pkg_name.to_owned(),
@@ -128,12 +127,40 @@ impl Library {
})
}
+ #[cfg(target_env = "msvc")]
+ fn probe_system(pkg_name: &str) -> Result<Self> {
+ let opencv = vcpkg::find_package(pkg_name)?;
+ let libs = opencv.found_libs.into_iter()
+ .filter_map(|lib| lib.file_name()
+ .and_then(|l| l.to_str())
+ .map(|l| l.to_string())
+ )
+ .collect();
+ let version = opencv.include_paths.iter()
+ .filter_map(get_version_from_headers)
+ .next();
+ let libdir = opencv.link_paths.first()
+ .map(|x| x.clone())
+ .unwrap_or_else(|| PathBuf::from(""));
+
+ Ok(Self {
+ pkg_name: pkg_name.to_owned(),
+ libs,
+ link_paths: opencv.link_paths,
+ framework_paths: vec![],
+ include_paths: opencv.include_paths,
+ version: version.unwrap_or("0.0.0".to_owned()),
+ prefix: PathBuf::from(""),
+ libdir,
+ })
+ }
pub fn probe(pkg_name: &str) -> Result<Self> {
- if let (Ok(link_libs), Ok(link_paths), Ok(include_paths)) = (env::var("OPENCV_LINK_LIBS"), env::var("OPENCV_LINK_PATHS"), env::var("OPENCV_INCLUDE_PATHS")) {
+ let env_vars = (env::var("OPENCV_LINK_LIBS"), env::var("OPENCV_LINK_PATHS"), env::var("OPENCV_INCLUDE_PATHS"));
+ if let (Ok(link_libs), Ok(link_paths), Ok(include_paths)) = env_vars {
Self::probe_from_paths(pkg_name, &link_libs, &link_paths, &include_paths)
} else {
- Self::probe_pkg_config(pkg_name)
+ Self::probe_system(pkg_name)
}
}
@@ -151,7 +178,7 @@ impl Library {
let link_paths = self.link_paths.iter().chain(third_party_dirs.iter());
if cfg!(target_env = "msvc") {
for l in &self.libs {
- extra_args.push(format!("{}.lib", l).into());
+ extra_args.push(l.into());
}
extra_args.push("-link".into());
for p in link_paths {
@@ -389,7 +416,7 @@ fn build_compiler(opencv_header_dir: &PathBuf) -> cc::Build {
out
}
-fn link_wrapper() -> Result<Library> {
+fn probe_opencv() -> Result<Library> {
let pkg_name = if cfg!(feature = "opencv-32") || cfg!(feature = "opencv-34") {
env::var("OPENCV_PKGCONFIG_NAME").map(|x| Cow::Owned(x)).unwrap_or_else(|_| Cow::Borrowed("opencv"))
} else if cfg!(feature = "opencv-41") {
@@ -397,7 +424,10 @@ fn link_wrapper() -> Result<Library> {
} else {
unreachable!("Feature flags should have been checked in main()");
};
- let opencv = Library::probe(&pkg_name).expect(&format!("Package {} is not found", pkg_name));
+ Ok(Library::probe(&pkg_name).expect(&format!("Package {} is not found", pkg_name)))
+}
+
+fn link_wrapper(opencv: &Library) -> Result<()> {
check_matching_version(&opencv.version).map_err(|e| format!("{}, (version coming from pkg_config for package: {})", e, opencv.pkg_name))?;
eprintln!("=== Using OpenCV library version: {} from: {}", opencv.version, opencv.libdir.display());
@@ -454,7 +484,7 @@ fn link_wrapper() -> Result<Library> {
third_party_deps.iter().for_each(|&x| lookup_lib(&third_party_dirs, x));
}
- Ok(opencv)
+ Ok(())
}
fn build_wrapper(opencv_header_dir: &PathBuf) -> Result<()> {
@@ -762,7 +792,13 @@ fn main() -> Result<()> {
if features != 1 {
panic!("Please select exactly one of the features: opencv-32, opencv-34, opencv-41");
}
+ let opencv = probe_opencv()?;
let opencv_header_dir = env::var_os("OPENCV_HEADER_DIR").map(PathBuf::from).unwrap_or_else(|| {
+ if cfg!(feature = "buildtime-bindgen") {
+ opencv.include_paths.iter()
+ .find(|p| p.join("opencv2").exists())
+ .expect("Using buildtime-bindgen, but discovered OpenCV include paths is empty or contains non-existent paths").clone()
+ } else {
let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").expect("Can't read CARGO_MANIFEST_DIR env var"));
if cfg!(feature = "opencv-32") {
manifest_dir.join("headers/3.2")
@@ -773,6 +809,7 @@ fn main() -> Result<()> {
} else {
panic!("Please select one OpenCV major version using one of the opencv-* features or specify OpenCV header path manually via OPENCV_HEADER_DIR environment var");
}
+ }
});
if let Some(version) = get_version_from_headers(&opencv_header_dir) {
check_matching_version(&version).map_err(|e| format!("{}, (version coming from headers at: {})", e, opencv_header_dir.display()))?;
@@ -782,7 +819,7 @@ fn main() -> Result<()> {
build_wrapper(&opencv_header_dir)?;
if !cfg!(feature = "docs-only") {
- let opencv = link_wrapper()?;
+ link_wrapper(&opencv)?;
if cfg!(feature = "buildtime-bindgen") {
gen_wrapper(&opencv, &opencv_header_dir)?;
}

RENAME
ci/install-windows.sh
ci/install-windows-chocolatey.sh
set -vex
choco install -y python3 --version "3.7.4"
-choco install -y opencv --version "$WIN_OPENCV_VERSION"
+choco install -y opencv --version "$CHOCO_OPENCV_VERSION"

ADD
ci/install-windows-vcpkg.sh
+#!/bin/bash
+
+# WIP, doesn't work yet
+
+set -vex
+
+choco install -y ninja
+export PATH="$PATH:C:\\ProgramData\\chocolatey\\lib\\ninja\\tools"
+git clone https://github.com/Microsoft/vcpkg.git --depth=1
+pushd vcpkg
+./scripts/bootstrap.sh --disableMetrics --useSystemBinaries
+./vcpkg integrate install
+echo "set(VCPKG_BUILD_TYPE release)" >> triplets/x64-windows.cmake
+echo "set(VCPKG_BUILD_TYPE release)" >> triplets/x86-windows.cmake
+./vcpkg install "opencv${VCPKG_OPENCV_VERSION}[contrib,nonfree]"
+popd

MODIFY
ci/install.sh
ci/install.sh
@@ -9,5 +9,9 @@ if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
"$ci_dir/install-osx.sh"
elif [[ "$TRAVIS_OS_NAME" == "windows" ]]; then
- "$ci_dir/install-windows.sh"
+ if [[ "$CHOCO_OPENCV_VERSION" != "" ]]; then # chocolatey build
+ "$ci_dir/install-windows-chocolatey.sh"
+ else # vcpkg build
+ "$ci_dir/install-windows-vcpkg.sh"
+ fi
fi

MODIFY
ci/script.sh
ci/script.sh
set -vex
if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then
+ if [[ "$CHOCO_OPENCV_VERSION" != "" ]]; then # chocolatey build
export PATH="C:\\Python37\\:$PATH:C:\\tools\\opencv\\build\\x64\\vc14\\bin"
export OPENCV_LINK_PATHS="C:\\tools\\opencv\\build\\x64\\vc14\\lib"
- export OPENCV_LINK_LIBS="opencv_world${WIN_OPENCV_VERSION//./}"
+ export OPENCV_LINK_LIBS="opencv_world${CHOCO_OPENCV_VERSION//./}"
export OPENCV_INCLUDE_PATHS="C:\\tools\\opencv\\build\\include"
export OPENCV_HEADER_DIR="C:\\tools\\opencv\\build\\include"
+ else # vcpkg build
+ export VCPKG_ROOT="$TRAVIS_BUILD_DIR\\vcpkg"
+ fi
CARGO_FEATURES="$CARGO_FEATURES,buildtime-bindgen"
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
if [[ "$OSX_OPENCV_VERSION" == "@3" ]]; then

MODIFY
gen_rust.py
gen_rust.py
@@ -996,6 +996,7 @@ reserved_rename = {
"ref": "_ref",
"type": "_type", # fixme: "typ" is better rename
"use": "_use",
+ "loop": "_loop",
}
# list of modules that are imported into every other module so there is no need to reference them using full path, elements are module names

use vcpkg for MSVC builds