diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3869255e..1f1e6659 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,7 @@ jobs: - proj-sys-ubuntu - proj-macos - proj-sys-macos + - proj-sys-windows steps: - name: Mark the job as a success if: success() @@ -119,3 +120,87 @@ jobs: uses: actions/checkout@v2 - run: brew install proj - run: cargo test ${{ matrix.features }} + + proj-sys-windows: + name: proj-sys windows + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: windows-latest + env: + _PROJ_SYS_TEST_EXPECT_BUILD_FROM_SRC: 0 + strategy: + fail-fast: false + matrix: + config: + - { + target: "x86_64-pc-windows-msvc", + VCPKG_DEFAULT_TRIPLET: "x64-windows-static", + RUSTFLAGS: "-Ctarget-feature=+crt-static", + features: "", + } + - { + target: "x86_64-pc-windows-msvc", + VCPKG_DEFAULT_TRIPLET: "x64-windows-static-md", + features: "", + } + - { + target: "x86_64-pc-windows-msvc", + VCPKG_DEFAULT_TRIPLET: "x64-windows", + VCPKGRS_DYNAMIC: 1, + # "cargo test --doc" broken with dynamic lib on CI machine (missing dll) + features: "--all-targets", + } + # - { + # target: "i686-pc-windows-msvc", + # VCPKG_DEFAULT_TRIPLET: "x86-windows-static", + # RUSTFLAGS: "-Ctarget-feature=+crt-static", + # features: "", + # } + # - { + # target: "i686-pc-windows-msvc", + # VCPKG_DEFAULT_TRIPLET: "x86-windows-static-md", + # features: "", + # } + # - { + # target: "i686-pc-windows-msvc", + # VCPKG_DEFAULT_TRIPLET: "x86-windows", + # VCPKGRS_DYNAMIC: 1, + # features: "--all-targets", + # } + steps: + - uses: actions/checkout@v2 + - name: Install vcpkg + run: | + git clone https://github.com/Microsoft/vcpkg.git vcp + vcp\bootstrap-vcpkg.bat -disableMetrics + - name: Set env + shell: bash + run: echo "VCPKG_ROOT=${{ github.workspace }}\vcp" >> $GITHUB_ENV + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v1 + with: + version: "10.0" + directory: ${{ runner.temp }}/llvm + - name: Set LIBCLANG_PATH + run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV + - name: install proj lib + env: + VCPKG_DEFAULT_TRIPLET: "${{ matrix.config.VCPKG_DEFAULT_TRIPLET }}" + shell: bash + run: | + set -ex + echo VCPKG_ROOT=${VCPKG_ROOT} + ${VCPKG_ROOT}/vcpkg install proj + - name: Run integration tests + env: + VCPKG_DEFAULT_TRIPLET: "${{ matrix.config.VCPKG_DEFAULT_TRIPLET }}" + RUSTFLAGS: ${{ matrix.config.RUSTFLAGS }} + shell: bash + run: | + set -ex + rustup target add ${{ matrix.config.target }} + rustc --version + cargo --version + echo dyn=${{ matrix.config.VCPKGRS_DYNAMIC }} + if [ '${{ matrix.config.VCPKGRS_DYNAMIC }}' != '' ] ; then export VCPKGRS_DYNAMIC=1 ; fi + cargo build --target ${{ matrix.config.target }} ${{ matrix.config.features }} + cargo test --target ${{ matrix.config.target }} ${{ matrix.config.features }} diff --git a/proj-sys/Cargo.toml b/proj-sys/Cargo.toml index 2a1a0c48..e0996ed8 100644 --- a/proj-sys/Cargo.toml +++ b/proj-sys/Cargo.toml @@ -19,6 +19,10 @@ cmake = "0.1" flate2 = "1.0.14" tar = "0.4.26" +[target.'cfg(target_env = "msvc")'.build-dependencies] +vcpkg = "0.2.11" +winapi-build = "0.1.1" + [features] nobuild = [] bundled_proj = [] diff --git a/proj-sys/build.rs b/proj-sys/build.rs index fa321b51..9bb4fcdc 100644 --- a/proj-sys/build.rs +++ b/proj-sys/build.rs @@ -19,28 +19,7 @@ fn main() -> Result<(), Box> { eprintln!("feature flags specified source build"); build_from_source()? } else { - pkg_config::Config::new() - .atleast_version(MINIMUM_PROJ_VERSION) - .probe("proj") - .and_then(|pk| { - eprintln!("found acceptable libproj already installed at: {:?}", pk.link_paths[0]); - if let Ok(val) = &env::var("_PROJ_SYS_TEST_EXPECT_BUILD_FROM_SRC") { - if val != "0" { - panic!("for testing purposes: existing package was found, but should not have been"); - } - } - - // Tell cargo to tell rustc to link the system proj - // shared library. - println!("cargo:rustc-link-search=native={:?}", pk.link_paths[0]); - println!("cargo:rustc-link-lib=proj"); - - Ok(pk.include_paths[0].clone()) - }) - .or_else(|err| { - eprintln!("pkg-config unable to find existing libproj installation: {}", err); - build_from_source() - })? + configure_pkg()? }; // The bindgen::Builder is the main entry point @@ -66,6 +45,61 @@ fn main() -> Result<(), Box> { Ok(()) } +#[cfg(target_env = "msvc")] +fn configure_pkg() -> Result> { + try_vcpkg() +} + +#[cfg(not(target_env = "msvc"))] +fn configure_pkg() -> Result> { + try_pkg_config() +} + +#[cfg(target_env = "msvc")] +fn try_vcpkg() -> Result> { + use vcpkg; + use build; + + build::link("shell32", true); + build::link("ole32", true); + let lib = vcpkg::Config::new() + .emit_includes(true) + .find_package("proj"); + + match lib { + Ok(include_path) => Ok(include_path.include_paths[0].clone()), + Err(e) => { + eprintln!("vcpkg error: {}, trying pkg_config", e); + try_pkg_config() + } + } +} + +fn try_pkg_config() -> Result> { + pkg_config::Config::new() + .atleast_version(MINIMUM_PROJ_VERSION) + .probe("proj") + .and_then(|pk| { + eprintln!("found acceptable libproj already installed at: {:?}", pk.link_paths[0]); + if let Ok(val) = &env::var("_PROJ_SYS_TEST_EXPECT_BUILD_FROM_SRC") { + if val != "0" { + panic!("for testing purposes: existing package was found, but should not have been"); + } + } + + // Tell cargo to tell rustc to link the system proj + // shared library. + println!("cargo:rustc-link-search=native={:?}", pk.link_paths[0]); + println!("cargo:rustc-link-lib=proj"); + + Ok(pk.include_paths[0].clone()) + }) + .or_else(|err| { + eprintln!("pkg-config unable to find existing libproj installation: {}", err); + build_from_source() + }) +} + // returns the path of "inlude" for the built proj fn build_from_source() -> Result> { eprintln!("building libproj from source"); diff --git a/src/proj.rs b/src/proj.rs index 14095111..a63dd408 100644 --- a/src/proj.rs +++ b/src/proj.rs @@ -1036,8 +1036,8 @@ mod test { let t = proj .convert(MyPoint::new(4760096.421921, 3744293.729449)) .unwrap(); - assert_relative_eq!(t.x(), 1450880.2910605003); - assert_relative_eq!(t.y(), 1141263.0111604529); + assert_relative_eq!(t.x(), 1450880.2910605003, epsilon = 1e-8); + assert_relative_eq!(t.y(), 1141263.0111604529, epsilon = 1e-8); } #[test] // Carry out a projection from geodetic coordinates @@ -1066,8 +1066,8 @@ mod test { let t = stereo70 .project(MyPoint::new(500119.70352012233, 500027.77896348457), true) .unwrap(); - assert_relative_eq!(t.x(), 0.43633200013698786); - assert_relative_eq!(t.y(), 0.8028510000110507); + assert_relative_eq!(t.x(), 0.43633200013698786, epsilon = 1e-14); + assert_relative_eq!(t.y(), 0.8028510000110507, epsilon = 1e-14); } #[test] // Carry out an inverse projection to geodetic coordinates @@ -1159,8 +1159,8 @@ mod test { MyPoint::new(4760197.421921, 3744394.729449), ]; ft_to_m.convert_array(&mut v).unwrap(); - assert_relative_eq!(v[0].x(), 1450880.2910605003f64); - assert_relative_eq!(v[1].y(), 1141293.7960220198); + assert_relative_eq!(v[0].x(), 1450880.2910605003f64, epsilon = 1e-8); + assert_relative_eq!(v[1].y(), 1141293.7960220198, epsilon = 1e-8); } #[test] @@ -1173,8 +1173,8 @@ mod test { // 👽 let usa_m = MyPoint::new(-115.797615, 37.2647978); let usa_ft = to_feet.convert(usa_m).unwrap(); - assert_eq!(6693625.67217475, usa_ft.x()); - assert_eq!(3497301.5918027186, usa_ft.y()); + assert_relative_eq!(6693625.67217475, usa_ft.x(),epsilon = 1e-8); + assert_relative_eq!(3497301.5918027186, usa_ft.y(), epsilon = 1e-8); } #[test]