diff --git a/.github/workflows/install-ccache.ps1 b/.github/workflows/install-ccache.ps1 new file mode 100644 index 0000000..f56a953 --- /dev/null +++ b/.github/workflows/install-ccache.ps1 @@ -0,0 +1,38 @@ +[CmdletBinding()] +param ( + [Parameter(Mandatory = $true)] + [string] $Destination +) + +$version = "4.8" +$folder = "ccache-$version-windows-x86_64" +$url = "https://github.com/ccache/ccache/releases/download/v$version/$folder.zip" +$expectedSha256 = "A2B3BAB4BB8318FFC5B3E4074DC25636258BC7E4B51261F7D9BEF8127FDA8309" + +$ErrorActionPreference = "Stop" + +try { + New-Item -Path "$Destination" -ItemType Container -ErrorAction SilentlyContinue + + Write-Host "Download CCache" + $zipFilePath = Join-Path "$env:TEMP" "$folder.zip" + Invoke-WebRequest -Uri $url -UseBasicParsing -OutFile "$zipFilePath" -MaximumRetryCount 3 + + $hash = Get-FileHash $zipFilePath -Algorithm "sha256" + if ($hash.Hash -ne $expectedSha256) { + throw "File $Path hash $hash.Hash did not match expected hash $expectedHash" + } + + Write-Host "Unzip CCache" + Expand-Archive -Path "$zipFilePath" -DestinationPath "$env:TEMP" + + Write-Host "Move CCache" + Move-Item -Force "$env:TEMP/$folder/ccache.exe" "$Destination" + Remove-Item "$zipFilePath" + Remove-Item -Recurse "$env:TEMP/$folder" +} +catch { + Write-Host "Installation failed with an error" + $_.Exception | Format-List + exit -1 +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ubuntu.yml similarity index 97% rename from .github/workflows/ci.yml rename to .github/workflows/ubuntu.yml index 888a383..455e8d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ubuntu.yml @@ -162,8 +162,6 @@ jobs: -DCMAKE_BUILD_TYPE=${{ matrix.config.cmakeBuildType }} \ -DCMAKE_INSTALL_PREFIX=./install \ -DCMAKE_CUDA_ARCHITECTURES=50 \ - -DSuiteSparse_CHOLMOD_LIBRARY="/usr/lib/x86_64-linux-gnu/libcholmod.so" \ - -DSuiteSparse_CHOLMOD_INCLUDE_DIR="/usr/include/suitesparse" \ -DTESTS_ENABLED=ON \ -DASAN_ENABLED=${{ matrix.config.asanEnabled }} ninja -k 10000 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..74e1fe5 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,142 @@ +name: Windows + +on: + push: + branches: + - main + pull_request: + types: [ assigned, opened, synchronize, reopened ] + release: + types: [ published, edited ] + +jobs: + build: + name: ${{ matrix.config.os }} ${{ matrix.config.cmakeBuildType }} ${{ matrix.config.cudaEnabled && 'CUDA' || '' }} + runs-on: ${{ matrix.config.os }} + strategy: + matrix: + config: [ + { + os: windows-2019, + cmakeBuildType: Release, + cudaEnabled: false, + testsEnabled: true, + exportPackage: false, + }, + { + os: windows-2022, + cmakeBuildType: Release, + cudaEnabled: false, + testsEnabled: true, + exportPackage: true, + }, + ] + + env: + COMPILER_CACHE_VERSION: 1 + COMPILER_CACHE_DIR: ${{ github.workspace }}/compiler-cache + CCACHE_DIR: ${{ github.workspace }}/compiler-cache/ccache + CCACHE_BASEDIR: ${{ github.workspace }} + VCPKG_COMMIT_ID: e01906b2ba7e645a76ee021a19de616edc98d29f + VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" + + steps: + - uses: actions/checkout@v4 + + - name: Export GitHub Actions cache env + uses: actions/github-script@v7 + with: + script: | + core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); + core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); + + - name: Compiler cache + uses: actions/cache@v4 + id: cache-builds + with: + key: v${{ env.COMPILER_CACHE_VERSION }}-${{ matrix.config.os }}-${{ matrix.config.cmakeBuildType }}-${{ matrix.config.asanEnabled }}--${{ matrix.config.cudaEnabled }}-${{ github.run_id }}-${{ github.run_number }} + restore-keys: v${{ env.COMPILER_CACHE_VERSION }}-${{ matrix.config.os }}-${{ matrix.config.cmakeBuildType }}-${{ matrix.config.asanEnabled }}--${{ matrix.config.cudaEnabled }} + path: ${{ env.COMPILER_CACHE_DIR }} + + - name: Install ccache + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path "${{ env.CCACHE_DIR }}" + echo "${{ env.COMPILER_CACHE_DIR }}/bin" | Out-File -Encoding utf8 -Append -FilePath $env:GITHUB_PATH + + if (Test-Path -PathType Leaf "${{ env.COMPILER_CACHE_DIR }}/bin/ccache.exe") { + exit + } + + .github/workflows/install-ccache.ps1 -Destination "${{ env.COMPILER_CACHE_DIR }}/bin" + + - name: Install CMake and Ninja + uses: lukka/get-cmake@latest + + - name: Setup vcpkg + shell: pwsh + run: | + ./scripts/shell/enter_vs_dev_shell.ps1 + cd ${{ github.workspace }} + git clone https://github.com/microsoft/vcpkg + cd vcpkg + git reset --hard ${{ env.VCPKG_COMMIT_ID }} + ./bootstrap-vcpkg.bat + + - name: Configure and build + shell: pwsh + run: | + ./scripts/shell/enter_vs_dev_shell.ps1 + cd ${{ github.workspace }} + ./vcpkg/vcpkg.exe integrate install + mkdir build + cd build + cmake .. ` + -GNinja ` + -DCMAKE_MAKE_PROGRAM=ninja ` + -DCMAKE_BUILD_TYPE=Release ` + -DTESTS_ENABLED=ON ` + -DCUDA_ENABLED=OFF ` + -DGUI_ENABLED=OFF ` + -DCGAL_ENABLED=OFF ` + -DCMAKE_CUDA_ARCHITECTURES=all-major ` + -DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" ` + -DVCPKG_TARGET_TRIPLET=x64-windows-release ` + -DCMAKE_INSTALL_PREFIX=install + ninja + + - name: Run tests + shell: pwsh + run: | + ./vcpkg/vcpkg.exe integrate install + cd build + ctest -E .+colmap_.* --output-on-failure + + - name: Export package + if: matrix.config.exportPackage + shell: pwsh + run: | + ./vcpkg/vcpkg.exe integrate install + + cd build + ninja install + + ../vcpkg/vcpkg.exe install ` + --triplet=x64-windows-release + ../vcpkg/vcpkg.exe export --raw --output-dir vcpkg_export --output glomap + cp vcpkg_export/glomap/installed/x64-windows/bin/*.dll install/bin + cp vcpkg_export/glomap/installed/x64-windows-release/bin/*.dll install/bin + + - name: Upload package + uses: actions/upload-artifact@v4 + if: ${{ matrix.config.exportPackage }} + with: + name: glomap-x64-windows + path: build/install + + - name: Cleanup compiler cache + shell: pwsh + run: | + ccache --show-stats --verbose + ccache --evict-older-than 1d + ccache --show-stats --verbose diff --git a/CMakeLists.txt b/CMakeLists.txt index 564b027..5a252ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ option(FETCH_POSELIB "Whether to use PoseLib with FetchContent or with self-inst include(cmake/FindDependencies.cmake) +# Propagate options to vcpkg manifest. if (TESTS_ENABLED) enable_testing() endif() diff --git a/cmake/FindDependencies.cmake b/cmake/FindDependencies.cmake index fbd6517..824f8b0 100644 --- a/cmake/FindDependencies.cmake +++ b/cmake/FindDependencies.cmake @@ -1,3 +1,29 @@ +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +find_package(Eigen3 3.4 REQUIRED) +find_package(SuiteSparse COMPONENTS CHOLMOD REQUIRED) +find_package(Ceres REQUIRED COMPONENTS SuiteSparse) +find_package(Boost REQUIRED) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + find_package(Glog REQUIRED) + if(DEFINED glog_VERSION_MAJOR) + # Older versions of glog don't export version variables. + add_definitions("-DGLOG_VERSION_MAJOR=${glog_VERSION_MAJOR}") + add_definitions("-DGLOG_VERSION_MINOR=${glog_VERSION_MINOR}") + endif() +endif() + +if(TESTS_ENABLED) + message(STATUS "Enabling tests") + find_package(GTest REQUIRED) +endif() + +if (OPENMP_ENABLED) + message(STATUS "Enabling OpenMP") + find_package(OpenMP REQUIRED) +endif() + include(FetchContent) FetchContent_Declare(PoseLib GIT_REPOSITORY https://github.com/PoseLib/PoseLib.git @@ -25,25 +51,3 @@ else() find_package(COLMAP REQUIRED) endif() message(STATUS "Configuring COLMAP... done") - -find_package(Eigen3 3.4 REQUIRED) -find_package(Ceres REQUIRED COMPONENTS SuiteSparse) -find_package(Boost REQUIRED) - -if(TESTS_ENABLED) - message(STATUS "Enabling tests") - find_package(GTest REQUIRED) -endif() - -if (OPENMP_ENABLED) - message(STATUS "Enabling OpenMP") - find_package(OpenMP REQUIRED) -endif() - -find_package(SuiteSparse QUIET) -if(SuiteSparse_FOUND) - set(SuiteSparse_CHOLMOD_INCLUDE_DIR "${SUITESPARSE_INCLUDE_DIRS}/suitesparse") - set(SuiteSparse_CHOLMOD_LIBRARY SuiteSparse::cholmod) -else() - message(STATUS "SuiteSparse not found, assuming Ceres provides SuiteSparse") -endif() diff --git a/cmake/FindGlog.cmake b/cmake/FindGlog.cmake new file mode 100644 index 0000000..8bf2ea4 --- /dev/null +++ b/cmake/FindGlog.cmake @@ -0,0 +1,118 @@ +# Copyright (c) 2023, ETH Zurich and UNC Chapel Hill. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +# Find package module for Glog library. +# +# The following variables are set by this module: +# +# GLOG_FOUND: TRUE if Glog is found. +# glog::glog: Imported target to link against. +# +# The following variables control the behavior of this module: +# +# GLOG_INCLUDE_DIR_HINTS: List of additional directories in which to +# search for Glog includes. +# GLOG_LIBRARY_DIR_HINTS: List of additional directories in which to +# search for Glog libraries. + +set(GLOG_INCLUDE_DIR_HINTS "" CACHE PATH "Glog include directory") +set(GLOG_LIBRARY_DIR_HINTS "" CACHE PATH "Glog library directory") + +unset(GLOG_FOUND) + +find_package(glog CONFIG QUIET) +if(TARGET glog::glog) + set(GLOG_FOUND TRUE) + message(STATUS "Found Glog") + message(STATUS " Target : glog::glog") +else() + # Older versions of glog don't come with a find_package config. + # Fall back to custom logic to find the library and remap to imported target. + + include(FindPackageHandleStandardArgs) + + list(APPEND GLOG_CHECK_INCLUDE_DIRS + /usr/local/include + /usr/local/homebrew/include + /opt/local/var/macports/software + /opt/local/include + /usr/include) + list(APPEND GLOG_CHECK_PATH_SUFFIXES + glog/include + glog/Include + Glog/include + Glog/Include + src/windows) + + list(APPEND GLOG_CHECK_LIBRARY_DIRS + /usr/local/lib + /usr/local/homebrew/lib + /opt/local/lib + /usr/lib) + list(APPEND GLOG_CHECK_LIBRARY_SUFFIXES + glog/lib + glog/Lib + Glog/lib + Glog/Lib + x64/Release) + + find_path(GLOG_INCLUDE_DIRS + NAMES + glog/logging.h + PATHS + ${GLOG_INCLUDE_DIR_HINTS} + ${GLOG_CHECK_INCLUDE_DIRS} + PATH_SUFFIXES + ${GLOG_CHECK_PATH_SUFFIXES}) + find_library(GLOG_LIBRARIES + NAMES + glog + libglog + PATHS + ${GLOG_LIBRARY_DIR_HINTS} + ${GLOG_CHECK_LIBRARY_DIRS} + PATH_SUFFIXES + ${GLOG_CHECK_LIBRARY_SUFFIXES}) + + if(GLOG_INCLUDE_DIRS AND GLOG_LIBRARIES) + set(GLOG_FOUND TRUE) + message(STATUS "Found Glog") + message(STATUS " Includes : ${GLOG_INCLUDE_DIRS}") + message(STATUS " Libraries : ${GLOG_LIBRARIES}") + endif() + + add_library(glog::glog INTERFACE IMPORTED) + target_include_directories(glog::glog INTERFACE ${GLOG_INCLUDE_DIRS}) + target_link_libraries(glog::glog INTERFACE ${GLOG_LIBRARIES}) +endif() + +if(NOT GLOG_FOUND AND GLOG_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Glog") +endif() diff --git a/cmake/FindMETIS.cmake b/cmake/FindMETIS.cmake new file mode 100644 index 0000000..5f41792 --- /dev/null +++ b/cmake/FindMETIS.cmake @@ -0,0 +1,110 @@ +# +# Copyright (c) 2022 Sergiu Deitsch +# +# 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 PARTMETISLAR 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. +# +#[=======================================================================[.rst: +Module for locating METIS +========================= + +Read-only variables: + +``METIS_FOUND`` + Indicates whether the library has been found. + +``METIS_VERSION`` + Indicates library version. + +Targets +------- + +``METIS::METIS`` + Specifies targets that should be passed to target_link_libararies. +]=======================================================================] + +include (FindPackageHandleStandardArgs) + +find_path (METIS_INCLUDE_DIR NAMES metis.h + PATH_SUFFIXES include + DOC "METIS include directory") +find_library (METIS_LIBRARY_DEBUG NAMES metis + PATH_SUFFIXES Debug + DOC "METIS debug library") +find_library (METIS_LIBRARY_RELEASE NAMES metis + PATH_SUFFIXES Release + DOC "METIS release library") + +if (METIS_LIBRARY_RELEASE) + if (METIS_LIBRARY_DEBUG) + set (METIS_LIBRARY debug ${METIS_LIBRARY_DEBUG} optimized + ${METIS_LIBRARY_RELEASE} CACHE STRING "METIS library") + else (METIS_LIBRARY_DEBUG) + set (METIS_LIBRARY ${METIS_LIBRARY_RELEASE} CACHE FILEPATH "METIS library") + endif (METIS_LIBRARY_DEBUG) +elseif (METIS_LIBRARY_DEBUG) + set (METIS_LIBRARY ${METIS_LIBRARY_DEBUG} CACHE FILEPATH "METIS library") +endif (METIS_LIBRARY_RELEASE) + +set (_METIS_VERSION_HEADER ${METIS_INCLUDE_DIR}/metis.h) + +if (EXISTS ${_METIS_VERSION_HEADER}) + file (READ ${_METIS_VERSION_HEADER} _METIS_VERSION_CONTENTS) + + string (REGEX REPLACE ".*#define METIS_VER_MAJOR[ \t]+([0-9]+).*" "\\1" + METIS_VERSION_MAJOR "${_METIS_VERSION_CONTENTS}") + string (REGEX REPLACE ".*#define METIS_VER_MINOR[ \t]+([0-9]+).*" "\\1" + METIS_VERSION_MINOR "${_METIS_VERSION_CONTENTS}") + string (REGEX REPLACE ".*#define METIS_VER_SUBMINOR[ \t]+([0-9]+).*" "\\1" + METIS_VERSION_PATCH "${_METIS_VERSION_CONTENTS}") + + set (METIS_VERSION + ${METIS_VERSION_MAJOR}.${METIS_VERSION_MINOR}.${METIS_VERSION_PATCH}) + set (METIS_VERSION_COMPONENTS 3) +endif (EXISTS ${_METIS_VERSION_HEADER}) + +mark_as_advanced (METIS_INCLUDE_DIR METIS_LIBRARY_DEBUG METIS_LIBRARY_RELEASE + METIS_LIBRARY) + +if (NOT TARGET METIS::METIS) + if (METIS_INCLUDE_DIR OR METIS_LIBRARY) + add_library (METIS::METIS IMPORTED UNKNOWN) + endif (METIS_INCLUDE_DIR OR METIS_LIBRARY) +endif (NOT TARGET METIS::METIS) + +if (METIS_INCLUDE_DIR) + set_property (TARGET METIS::METIS PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${METIS_INCLUDE_DIR}) +endif (METIS_INCLUDE_DIR) + +if (METIS_LIBRARY_RELEASE) + set_property (TARGET METIS::METIS PROPERTY IMPORTED_LOCATION_RELEASE + ${METIS_LIBRARY_RELEASE}) + set_property (TARGET METIS::METIS APPEND PROPERTY IMPORTED_CONFIGURATIONS + RELEASE) +endif (METIS_LIBRARY_RELEASE) + +if (METIS_LIBRARY_DEBUG) + set_property (TARGET METIS::METIS PROPERTY IMPORTED_LOCATION_DEBUG + ${METIS_LIBRARY_DEBUG}) + set_property (TARGET METIS::METIS APPEND PROPERTY IMPORTED_CONFIGURATIONS + DEBUG) +endif (METIS_LIBRARY_DEBUG) + +find_package_handle_standard_args (METIS REQUIRED_VARS + METIS_INCLUDE_DIR METIS_LIBRARY VERSION_VAR METIS_VERSION) diff --git a/cmake/FindSuiteSparse.cmake b/cmake/FindSuiteSparse.cmake new file mode 100644 index 0000000..bccd89f --- /dev/null +++ b/cmake/FindSuiteSparse.cmake @@ -0,0 +1,537 @@ +# Ceres Solver - A fast non-linear least squares minimizer +# Copyright 2023 Google Inc. All rights reserved. +# http://ceres-solver.org/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Google Inc. nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Author: alexs.mac@gmail.com (Alex Stewart) +# + +#[=======================================================================[.rst: +FindSuiteSparse +=============== + +Module for locating SuiteSparse libraries and its dependencies. + +This module defines the following variables: + +``SuiteSparse_FOUND`` + ``TRUE`` iff SuiteSparse and all dependencies have been found. + +``SuiteSparse_VERSION`` + Extracted from ``SuiteSparse_config.h`` (>= v4). + +``SuiteSparse_VERSION_MAJOR`` + Equal to 4 if ``SuiteSparse_VERSION`` = 4.2.1 + +``SuiteSparse_VERSION_MINOR`` + Equal to 2 if ``SuiteSparse_VERSION`` = 4.2.1 + +``SuiteSparse_VERSION_PATCH`` + Equal to 1 if ``SuiteSparse_VERSION`` = 4.2.1 + +The following variables control the behaviour of this module: + +``SuiteSparse_NO_CMAKE`` + Do not attempt to use the native SuiteSparse CMake package configuration. + + +Targets +------- + +The following targets define the SuiteSparse components searched for. + +``SuiteSparse::AMD`` + Symmetric Approximate Minimum Degree (AMD) + +``SuiteSparse::CAMD`` + Constrained Approximate Minimum Degree (CAMD) + +``SuiteSparse::COLAMD`` + Column Approximate Minimum Degree (COLAMD) + +``SuiteSparse::CCOLAMD`` + Constrained Column Approximate Minimum Degree (CCOLAMD) + +``SuiteSparse::CHOLMOD`` + Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD) + +``SuiteSparse::Partition`` + CHOLMOD with METIS support + +``SuiteSparse::SPQR`` + Multifrontal Sparse QR (SuiteSparseQR) + +``SuiteSparse::Config`` + Common configuration for all but CSparse (SuiteSparse version >= 4). + +Optional SuiteSparse dependencies: + +``METIS::METIS`` + Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS) +]=======================================================================] + +if (NOT SuiteSparse_NO_CMAKE) + find_package (SuiteSparse NO_MODULE QUIET) +endif (NOT SuiteSparse_NO_CMAKE) + +if (SuiteSparse_FOUND) + return () +endif (SuiteSparse_FOUND) + +# Push CMP0057 to enable support for IN_LIST, when cmake_minimum_required is +# set to <3.3. +cmake_policy (PUSH) +cmake_policy (SET CMP0057 NEW) + +if (NOT SuiteSparse_FIND_COMPONENTS) + set (SuiteSparse_FIND_COMPONENTS + AMD + CAMD + CCOLAMD + CHOLMOD + COLAMD + SPQR + ) + + foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS) + set (SuiteSparse_FIND_REQUIRED_${component} TRUE) + endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS) +endif (NOT SuiteSparse_FIND_COMPONENTS) + +# Assume SuiteSparse was found and set it to false only if third-party +# dependencies could not be located. SuiteSparse components are handled by +# FindPackageHandleStandardArgs HANDLE_COMPONENTS option. +set (SuiteSparse_FOUND TRUE) + +include (CheckLibraryExists) +include (CheckSymbolExists) +include (CMakePushCheckState) + +# Config is a base component and thus always required +set (SuiteSparse_IMPLICIT_COMPONENTS Config) + +# CHOLMOD depends on AMD, CAMD, CCOLAMD, and COLAMD. +if (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS) + list (APPEND SuiteSparse_IMPLICIT_COMPONENTS AMD CAMD CCOLAMD COLAMD) +endif (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS) + +# SPQR depends on CHOLMOD. +if (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS) + list (APPEND SuiteSparse_IMPLICIT_COMPONENTS CHOLMOD) +endif (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS) + +# Implicit components are always required +foreach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS) + set (SuiteSparse_FIND_REQUIRED_${component} TRUE) +endforeach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS) + +list (APPEND SuiteSparse_FIND_COMPONENTS ${SuiteSparse_IMPLICIT_COMPONENTS}) + +# Do not list components multiple times. +list (REMOVE_DUPLICATES SuiteSparse_FIND_COMPONENTS) + +# Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when +# FindSuiteSparse was invoked. +macro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX) + if (MSVC) + set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}") + endif (MSVC) +endmacro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX) + +# Called if we failed to find SuiteSparse or any of it's required dependencies, +# unsets all public (designed to be used externally) variables and reports +# error message at priority depending upon [REQUIRED/QUIET/] argument. +macro(SuiteSparse_REPORT_NOT_FOUND REASON_MSG) + # Will be set to FALSE by find_package_handle_standard_args + unset (SuiteSparse_FOUND) + + # Do NOT unset SuiteSparse_REQUIRED_VARS here, as it is used by + # FindPackageHandleStandardArgs() to generate the automatic error message on + # failure which highlights which components are missing. + + suitesparse_reset_find_library_prefix() + + # Note _FIND_[REQUIRED/QUIETLY] variables defined by FindPackage() + # use the camelcase library name, not uppercase. + if (SuiteSparse_FIND_QUIETLY) + message(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) + elseif (SuiteSparse_FIND_REQUIRED) + message(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) + else() + # Neither QUIETLY nor REQUIRED, use no priority which emits a message + # but continues configuration and allows generation. + message("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) + endif (SuiteSparse_FIND_QUIETLY) + + # Do not call return(), s/t we keep processing if not called with REQUIRED + # and report all missing components, rather than bailing after failing to find + # the first. +endmacro(SuiteSparse_REPORT_NOT_FOUND) + +# Handle possible presence of lib prefix for libraries on MSVC, see +# also SuiteSparse_RESET_FIND_LIBRARY_PREFIX(). +if (MSVC) + # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES + # s/t we can set it back before returning. + set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}") + # The empty string in this list is important, it represents the case when + # the libraries have no prefix (shared libraries / DLLs). + set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}") +endif (MSVC) + +# Additional suffixes to try appending to each search path. +list(APPEND SuiteSparse_CHECK_PATH_SUFFIXES + suitesparse) # Windows/Ubuntu + +# Wrappers to find_path/library that pass the SuiteSparse search hints/paths. +# +# suitesparse_find_component( [FILES name1 [name2 ...]] +# [LIBRARIES name1 [name2 ...]]) +macro(suitesparse_find_component COMPONENT) + include(CMakeParseArguments) + set(MULTI_VALUE_ARGS FILES LIBRARIES) + cmake_parse_arguments(SuiteSparse_FIND_COMPONENT_${COMPONENT} + "" "" "${MULTI_VALUE_ARGS}" ${ARGN}) + + set(SuiteSparse_${COMPONENT}_FOUND TRUE) + if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES) + find_path(SuiteSparse_${COMPONENT}_INCLUDE_DIR + NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES} + PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES}) + if (SuiteSparse_${COMPONENT}_INCLUDE_DIR) + message(STATUS "Found ${COMPONENT} headers in: " + "${SuiteSparse_${COMPONENT}_INCLUDE_DIR}") + mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR) + else() + # Specified headers not found. + set(SuiteSparse_${COMPONENT}_FOUND FALSE) + if (SuiteSparse_FIND_REQUIRED_${COMPONENT}) + suitesparse_report_not_found( + "Did not find ${COMPONENT} header (required SuiteSparse component).") + else() + message(STATUS "Did not find ${COMPONENT} header (optional " + "SuiteSparse component).") + # Hide optional vars from CMake GUI even if not found. + mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR) + endif() + endif() + endif() + + if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES) + find_library(SuiteSparse_${COMPONENT}_LIBRARY + NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES} + PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES}) + if (SuiteSparse_${COMPONENT}_LIBRARY) + message(STATUS "Found ${COMPONENT} library: ${SuiteSparse_${COMPONENT}_LIBRARY}") + mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY) + else () + # Specified libraries not found. + set(SuiteSparse_${COMPONENT}_FOUND FALSE) + if (SuiteSparse_FIND_REQUIRED_${COMPONENT}) + suitesparse_report_not_found( + "Did not find ${COMPONENT} library (required SuiteSparse component).") + else() + message(STATUS "Did not find ${COMPONENT} library (optional SuiteSparse " + "dependency)") + # Hide optional vars from CMake GUI even if not found. + mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY) + endif() + endif() + endif() + + # A component can be optional (given to OPTIONAL_COMPONENTS). However, if the + # component is implicit (must be always present, such as the Config component) + # assume it be required as well. + if (SuiteSparse_FIND_REQUIRED_${COMPONENT}) + list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_INCLUDE_DIR) + list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_LIBRARY) + endif (SuiteSparse_FIND_REQUIRED_${COMPONENT}) + + # Define the target only if the include directory and the library were found + if (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY) + if (NOT TARGET SuiteSparse::${COMPONENT}) + add_library(SuiteSparse::${COMPONENT} IMPORTED UNKNOWN) + endif (NOT TARGET SuiteSparse::${COMPONENT}) + + set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${SuiteSparse_${COMPONENT}_INCLUDE_DIR}) + set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY + IMPORTED_LOCATION ${SuiteSparse_${COMPONENT}_LIBRARY}) + endif (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY) +endmacro() + +# Given the number of components of SuiteSparse, and to ensure that the +# automatic failure message generated by FindPackageHandleStandardArgs() +# when not all required components are found is helpful, we maintain a list +# of all variables that must be defined for SuiteSparse to be considered found. +unset(SuiteSparse_REQUIRED_VARS) + +# BLAS. +find_package(BLAS QUIET) +if (NOT BLAS_FOUND) + suitesparse_report_not_found( + "Did not find BLAS library (required for SuiteSparse).") +endif (NOT BLAS_FOUND) + +# LAPACK. +find_package(LAPACK QUIET) +if (NOT LAPACK_FOUND) + suitesparse_report_not_found( + "Did not find LAPACK library (required for SuiteSparse).") +endif (NOT LAPACK_FOUND) + +foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS) + if (component STREQUAL Partition) + # Partition is a meta component that neither provides additional headers nor + # a separate library. It is strictly part of CHOLMOD. + continue () + endif (component STREQUAL Partition) + string (TOLOWER ${component} component_library) + + if (component STREQUAL "Config") + set (component_header SuiteSparse_config.h) + set (component_library suitesparseconfig) + elseif (component STREQUAL "SPQR") + set (component_header SuiteSparseQR.hpp) + else (component STREQUAL "SPQR") + set (component_header ${component_library}.h) + endif (component STREQUAL "Config") + + suitesparse_find_component(${component} + FILES ${component_header} + LIBRARIES ${component_library}) +endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS) + +if (TARGET SuiteSparse::SPQR) + # SuiteSparseQR may be compiled with Intel Threading Building Blocks, + # we assume that if TBB is installed, SuiteSparseQR was compiled with + # support for it, this will do no harm if it wasn't. + find_package(TBB QUIET) + if (TBB_FOUND) + message(STATUS "Found Intel Thread Building Blocks (TBB) library " + "(${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} / ${TBB_INTERFACE_VERSION}) " + "include location: ${TBB_INCLUDE_DIRS}. Assuming SuiteSparseQR was " + "compiled with TBB.") + # Add the TBB libraries to the SuiteSparseQR libraries (the only + # libraries to optionally depend on TBB). + if (TARGET TBB::tbb) + # Native TBB package configuration provides an imported target. Use it if + # available. + set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY + INTERFACE_LINK_LIBRARIES TBB::tbb) + else (TARGET TBB::tbb) + set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS}) + set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${TBB_LIBRARIES}) + endif (TARGET TBB::tbb) + else (TBB_FOUND) + message(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was " + "not compiled with TBB.") + endif (TBB_FOUND) +endif (TARGET SuiteSparse::SPQR) + +check_library_exists(rt shm_open "" HAVE_LIBRT) + +if (TARGET SuiteSparse::Config) + # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for + # timing by default when compiled on Linux or Unix, but not on OSX (which + # does not have librt). + if (HAVE_LIBRT) + message(STATUS "Adding librt to " + "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if " + "SuiteSparse is compiled with timing).") + set_property (TARGET SuiteSparse::Config APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $) + else (HAVE_LIBRT) + message(STATUS "Could not find librt, but found SuiteSparse_config, " + "assuming that SuiteSparse was compiled without timing.") + endif (HAVE_LIBRT) + + # Add BLAS and LAPACK as dependencies of SuiteSparse::Config for convenience + # given that all components depend on it. + if (BLAS_FOUND) + if (TARGET BLAS::BLAS) + set_property (TARGET SuiteSparse::Config APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $) + else (TARGET BLAS::BLAS) + set_property (TARGET SuiteSparse::Config APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${BLAS_LIBRARIES}) + endif (TARGET BLAS::BLAS) + endif (BLAS_FOUND) + + if (LAPACK_FOUND) + if (TARGET LAPACK::LAPACK) + set_property (TARGET SuiteSparse::Config APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $) + else (TARGET LAPACK::LAPACK) + set_property (TARGET SuiteSparse::Config APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${LAPACK_LIBRARIES}) + endif (TARGET LAPACK::LAPACK) + endif (LAPACK_FOUND) + + # SuiteSparse version >= 4. + set(SuiteSparse_VERSION_FILE + ${SuiteSparse_Config_INCLUDE_DIR}/SuiteSparse_config.h) + if (NOT EXISTS ${SuiteSparse_VERSION_FILE}) + suitesparse_report_not_found( + "Could not find file: ${SuiteSparse_VERSION_FILE} containing version " + "information for >= v4 SuiteSparse installs, but SuiteSparse_config was " + "found (only present in >= v4 installs).") + else (NOT EXISTS ${SuiteSparse_VERSION_FILE}) + file(READ ${SuiteSparse_VERSION_FILE} Config_CONTENTS) + + string(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION[ \t]+([0-9]+)" + SuiteSparse_VERSION_LINE "${Config_CONTENTS}") + set (SuiteSparse_VERSION_MAJOR ${CMAKE_MATCH_1}) + + string(REGEX MATCH "#define SUITESPARSE_SUB_VERSION[ \t]+([0-9]+)" + SuiteSparse_VERSION_LINE "${Config_CONTENTS}") + set (SuiteSparse_VERSION_MINOR ${CMAKE_MATCH_1}) + + string(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION[ \t]+([0-9]+)" + SuiteSparse_VERSION_LINE "${Config_CONTENTS}") + set (SuiteSparse_VERSION_PATCH ${CMAKE_MATCH_1}) + + unset (SuiteSparse_VERSION_LINE) + + # This is on a single line s/t CMake does not interpret it as a list of + # elements and insert ';' separators which would result in 4.;2.;1 nonsense. + set(SuiteSparse_VERSION + "${SuiteSparse_VERSION_MAJOR}.${SuiteSparse_VERSION_MINOR}.${SuiteSparse_VERSION_PATCH}") + + if (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+") + set(SuiteSparse_VERSION_COMPONENTS 3) + else (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+") + message (WARNING "Could not parse SuiteSparse_config.h: SuiteSparse " + "version will not be available") + + unset (SuiteSparse_VERSION) + unset (SuiteSparse_VERSION_MAJOR) + unset (SuiteSparse_VERSION_MINOR) + unset (SuiteSparse_VERSION_PATCH) + endif (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+") + endif (NOT EXISTS ${SuiteSparse_VERSION_FILE}) +endif (TARGET SuiteSparse::Config) + +# CHOLMOD requires AMD CAMD CCOLAMD COLAMD +if (TARGET SuiteSparse::CHOLMOD) + foreach (component IN ITEMS AMD CAMD CCOLAMD COLAMD) + if (TARGET SuiteSparse::${component}) + set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SuiteSparse::${component}) + else (TARGET SuiteSparse::${component}) + # Consider CHOLMOD not found if COLAMD cannot be found + set (SuiteSparse_CHOLMOD_FOUND FALSE) + endif (TARGET SuiteSparse::${component}) + endforeach (component IN ITEMS AMD CAMD CCOLAMD COLAMD) +endif (TARGET SuiteSparse::CHOLMOD) + +# SPQR requires CHOLMOD +if (TARGET SuiteSparse::SPQR) + if (TARGET SuiteSparse::CHOLMOD) + set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD) + else (TARGET SuiteSparse::CHOLMOD) + # Consider SPQR not found if CHOLMOD cannot be found + set (SuiteSparse_SQPR_FOUND FALSE) + endif (TARGET SuiteSparse::CHOLMOD) +endif (TARGET SuiteSparse::SPQR) + +# Add SuiteSparse::Config as dependency to all components +if (TARGET SuiteSparse::Config) + foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS) + if (component STREQUAL Config) + continue () + endif (component STREQUAL Config) + + if (TARGET SuiteSparse::${component}) + set_property (TARGET SuiteSparse::${component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SuiteSparse::Config) + endif (TARGET SuiteSparse::${component}) + endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS) +endif (TARGET SuiteSparse::Config) + +# Check whether CHOLMOD was compiled with METIS support. The check can be +# performed only after the main components have been set up. +if (TARGET SuiteSparse::CHOLMOD) + # NOTE If SuiteSparse was compiled as a static library we'll need to link + # against METIS already during the check. Otherwise, the check can fail due to + # undefined references even though SuiteSparse was compiled with METIS. + find_package (METIS) + + if (TARGET METIS::METIS) + cmake_push_check_state (RESET) + set (CMAKE_REQUIRED_LIBRARIES SuiteSparse::CHOLMOD METIS::METIS) + check_symbol_exists (cholmod_metis cholmod.h SuiteSparse_CHOLMOD_USES_METIS) + cmake_pop_check_state () + + if (SuiteSparse_CHOLMOD_USES_METIS) + set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $) + + # Provide the SuiteSparse::Partition component whose availability indicates + # that CHOLMOD was compiled with the Partition module. + if (NOT TARGET SuiteSparse::Partition) + add_library (SuiteSparse::Partition IMPORTED INTERFACE) + endif (NOT TARGET SuiteSparse::Partition) + + set_property (TARGET SuiteSparse::Partition APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD) + endif (SuiteSparse_CHOLMOD_USES_METIS) + endif (TARGET METIS::METIS) +endif (TARGET SuiteSparse::CHOLMOD) + +# We do not use suitesparse_find_component to find Partition and therefore must +# handle the availability in an extra step. +if (TARGET SuiteSparse::Partition) + set (SuiteSparse_Partition_FOUND TRUE) +else (TARGET SuiteSparse::Partition) + set (SuiteSparse_Partition_FOUND FALSE) +endif (TARGET SuiteSparse::Partition) + +suitesparse_reset_find_library_prefix() + +# Handle REQUIRED and QUIET arguments to FIND_PACKAGE +include(FindPackageHandleStandardArgs) +if (SuiteSparse_FOUND) + find_package_handle_standard_args(SuiteSparse + REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS} + VERSION_VAR SuiteSparse_VERSION + FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse." + HANDLE_COMPONENTS) +else (SuiteSparse_FOUND) + # Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to + # find SuiteSparse to avoid a confusing autogenerated failure message + # that states 'not found (missing: FOO) (found version: x.y.z)'. + find_package_handle_standard_args(SuiteSparse + REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS} + FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse." + HANDLE_COMPONENTS) +endif (SuiteSparse_FOUND) + +# Pop CMP0057. +cmake_policy (POP) diff --git a/glomap/CMakeLists.txt b/glomap/CMakeLists.txt index c71b966..a5d8244 100644 --- a/glomap/CMakeLists.txt +++ b/glomap/CMakeLists.txt @@ -79,15 +79,10 @@ target_link_libraries( PUBLIC Eigen3::Eigen Ceres::ceres + SuiteSparse::CHOLMOD ${BOOST_LIBRARIES} - ${SuiteSparse_CHOLMOD_LIBRARY} -) -target_include_directories( - glomap - PUBLIC - .. - ${SuiteSparse_CHOLMOD_INCLUDE_DIR} ) +target_include_directories(glomap PUBLIC ..) if(OPENMP_FOUND) target_link_libraries(glomap PUBLIC OpenMP::OpenMP_CXX) diff --git a/scripts/shell/enter_vs_dev_shell.ps1 b/scripts/shell/enter_vs_dev_shell.ps1 new file mode 100644 index 0000000..9396c5c --- /dev/null +++ b/scripts/shell/enter_vs_dev_shell.ps1 @@ -0,0 +1,25 @@ +if (!$env:VisualStudioDevShell) { + $vswhere = "${Env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe" + if (!(Test-Path $vswhere)) { + throw "Failed to find vswhere.exe" + } + + & $vswhere -latest -format json + $vsInstance = & $vswhere -latest -format json | ConvertFrom-Json + if ($LASTEXITCODE) { + throw "vswhere.exe returned exit code $LASTEXITCODE" + } + + Import-Module "$($vsInstance.installationPath)/Common7/Tools/Microsoft.VisualStudio.DevShell.dll" + $prevCwd = Get-Location + try { + Enter-VsDevShell $vsInstance.instanceId -DevCmdArguments "-no_logo -host_arch=amd64 -arch=amd64" + } catch { + Write-Host $_ + Write-Error "Failed to enter Visual Studio Dev Shell" + exit 1 + } + Set-Location $prevCwd + + $env:VisualStudioDevShell = $true +} diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..4ec5778 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,46 @@ +{ + "name": "glomap", + "description": "GLOMAP is a general purpose global structure-from-motion pipeline for image-based reconstruction. GLOMAP requires a COLMAP database as input and outputs a COLMAP sparse reconstruction. As compared to COLMAP, this project provides a much more efficient and scalable reconstruction process, typically 1-2 orders of magnitude faster, with on-par or superior reconstruction quality.", + "homepage": "https://github.com/colmap/glomap", + "license": "BSD-3-Clause", + "supports": "(linux | (windows & !static) | osx) & (x86 | x64 | arm64)", + "dependencies": [ + "boost-algorithm", + "boost-filesystem", + "boost-graph", + "boost-heap", + "boost-program-options", + "boost-property-map", + "boost-property-tree", + { + "name": "ceres", + "features": [ + "lapack", + "suitesparse" + ] + }, + "eigen3", + "flann", + "freeimage", + "gflags", + "glog", + { + "name": "jasper", + "default-features": false + }, + "metis", + "sqlite3", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + "gtest", + "suitesparse" + ], + "features": { + } +}