diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000000..4c26bc340f --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,91 @@ +name: Continuous Integration + +on: + push: + branches: + - master + - develop + # Skip jobs when only documentation files are changed + paths-ignore: + - '**.md' + - '**.rst' + - 'docs/**' + pull_request: + paths-ignore: + - '**.md' + - '**.rst' + - 'docs/**' + +jobs: + build: + runs-on: ubuntu-latest + container: + image: alicevision/alicevision-deps:ci-2020.05.08-centos7-cuda9.0 + env: + DEPS_INSTALL_DIR: /opt/AliceVision_install + BUILD_TYPE: Release + CTEST_OUTPUT_ON_FAILURE: 1 + steps: + - uses: actions/checkout@v1 + + - name: Prepare File Tree + run: | + mkdir ./build + mkdir ./build_as_3rdparty + mkdir ./functional_tests + mkdir ../AV_install + git submodule update -i + + - name: Configure CMake + working-directory: ./build + run: | + cmake .. \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DBUILD_SHARED_LIBS:BOOL=ON \ + -DCMAKE_PREFIX_PATH="${DEPS_INSTALL_DIR}" \ + -DCMAKE_INSTALL_PREFIX:PATH=$PWD/../../AV_install \ + -DTARGET_ARCHITECTURE=core \ + -DALICEVISION_BUILD_TESTS:BOOL=ON \ + -DALICEVISION_BUILD_EXAMPLES:BOOL=ON \ + -DALICEVISION_USE_OPENCV:BOOL=ON \ + -DALICEVISION_USE_CUDA:BOOL=ON \ + -DALICEVISION_USE_CCTAG:BOOL=ON \ + -DALICEVISION_USE_POPSIFT:BOOL=ON \ + -DALICEVISION_USE_ALEMBIC:BOOL=ON \ + -DOpenCV_DIR:PATH="${DEPS_INSTALL_DIR}/share/OpenCV" \ + -DALICEVISION_USE_OPENGV:BOOL=ON \ + -DOPENGV_DIR:PATH="${DEPS_INSTALL_DIR}" \ + -DBOOST_NO_CXX11:BOOL=ON \ + -DCeres_DIR:PATH="${DEPS_INSTALL_DIR}/share/Ceres" \ + -DEIGEN_INCLUDE_DIR_HINTS:PATH="${DEPS_INSTALL_DIR}" \ + -DAlembic_DIR:PATH="${DEPS_INSTALL_DIR}/lib/cmake/Alembic" + + - name: Build + working-directory: ./build + run: | + make -j8 install + + - name: Unit Tests + working-directory: ./build + run: | + make test + + - name: Build As Third Party + working-directory: ./build_as_3rdparty + run: | + cmake ../src/samples/aliceVisionAs3rdParty \ + -DBUILD_SHARED_LIBS:BOOL=ON \ + -DCMAKE_PREFIX_PATH:PATH="$PWD/../../AV_install;${DEPS_INSTALL_DIR}" + make -j8 + + - name: Functional Tests + working-directory: ./functional_tests + run: | + git clone --branch master https://github.com/alicevision/SfM_quality_evaluation.git + cd SfM_quality_evaluation/ + # checkout a specific commit to ensure repeatability + git checkout 203e55c6e70de5f79496407961eb10b15deece4b + export LD_LIBRARY_PATH=$PWD/../../../AV_install/lib64:${DEPS_INSTALL_DIR}/lib64:${DEPS_INSTALL_DIR}/lib:${LD_LIBRARY_PATH} + echo "ldd aliceVision_cameraInit" + ldd $PWD/../../../AV_install/bin/aliceVision_cameraInit + python EvaluationLauncher.py -s $PWD/../../../AV_install/bin -i $PWD/Benchmarking_Camera_Calibration_2008/ -o $PWD/reconstructions/ -r $PWD/results.json -v diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0d8f6f4329..b457672855 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -20,9 +20,4 @@ jobs: days-before-stale: 360 days-before-close: 7 exempt-pr-label: 'type:pr' - exempt-issue-label: - - 'feature' - - 'do not close' - - 'feature request' - - 'scope:doc' - - 'new feature' + exempt-issue-label: 'feature,do not close,feature request,scope:doc,new feature' diff --git a/CMakeLists.txt b/CMakeLists.txt index 72724251b1..a20c3f6318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ option(AV_BUILD_ALICEVISION "Enable building of AliceVision" ON) option(AV_USE_CUDA "Enable CUDA" ON) +option(BUILD_SHARED_LIBS "Build shared libraries" ON) + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type for AliceVision" FORCE) endif() @@ -178,6 +180,7 @@ set(TBB_CMAKE_FLAGS -DTBB_INCLUDE_DIRS:PATH=${CMAKE_INSTALL_PREFIX}/include -DTB # Add Eigen set(EIGEN_TARGET eigen) +set(EIGEN_DISABLE_ALIGN_FLAGS -DEIGEN_MAX_ALIGN_BYTES=0 -DEIGEN_MAX_STATIC_ALIGN_BYTES=0) ExternalProject_Add(${EIGEN_TARGET} URL https://github.com/eigenteam/eigen-git-mirror/archive/3.3.7.tar.gz PREFIX ${BUILD_DIR} @@ -187,9 +190,9 @@ ExternalProject_Add(${EIGEN_TARGET} SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/eigen BINARY_DIR ${BUILD_DIR}/eigen_build INSTALL_DIR ${CMAKE_INSTALL_PREFIX} - CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} -DCMAKE_INSTALL_PREFIX:PATH= + CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${EIGEN_DISABLE_ALIGN_FLAGS} -DCMAKE_INSTALL_PREFIX:PATH= ) -set(EIGEN_CMAKE_FLAGS -DEigen3_DIR:PATH=${CMAKE_INSTALL_PREFIX}/share/eigen3/cmake -DEIGEN3_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3 -DEIGEN_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3 -DEigen_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3) +set(EIGEN_CMAKE_FLAGS ${EIGEN_DISABLE_ALIGN_FLAGS} -DEigen3_DIR:PATH=${CMAKE_INSTALL_PREFIX}/share/eigen3/cmake -DEIGEN3_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3 -DEIGEN_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3 -DEigen_INCLUDE_DIR=${CMAKE_INSTALL_PREFIX}/include/eigen3) if(AV_BUILD_OPENGV) set(OPENGV_TARGET opengv) @@ -234,7 +237,7 @@ set(SUITESPARSE_TARGET suitesparse) set(SUITESPARSE_INTERNAL_MAKE_CMD LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} make BLAS="${BLAS_LIBRARIES}" LAPACK="${LAPACK_LIBRARIES}") ExternalProject_Add(${SUITESPARSE_TARGET} # URL https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/v4.5.6.tar.gz - URL https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/v5.6.0.tar.gz # requires gxx >= 4.9, centos 7 use gxx-4.8.5 by default + URL https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/v5.7.2.tar.gz # requires gxx >= 4.9, centos 7 use gxx-4.8.5 by default PREFIX ${BUILD_DIR} BUILD_IN_SOURCE 0 BUILD_ALWAYS 0 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index cf6b66bf99..31b3f6ccf5 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,6 +12,7 @@ Individuals - Clement Debize - Cyril Pichard - Fabien Castan +- Fabien Servant - Gregoire De Lillo - Havard Espeland - Jean Melou diff --git a/Dockerfile b/Dockerfile index 8e2d8893e8..c286bd5321 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,14 +24,21 @@ ENV AV_DEV=/opt/AliceVision_git \ COPY . "${AV_DEV}" WORKDIR "${AV_BUILD}" + RUN cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS:BOOL=ON -DTARGET_ARCHITECTURE=core \ -DALICEVISION_BUILD_DEPENDENCIES:BOOL=OFF \ -DCMAKE_PREFIX_PATH:PATH="${AV_INSTALL}" \ -DCMAKE_INSTALL_PREFIX:PATH="${AV_INSTALL}" -DALICEVISION_BUNDLE_PREFIX="${AV_BUNDLE}" \ -DALICEVISION_USE_ALEMBIC=ON -DMINIGLOG=ON -DALICEVISION_USE_CCTAG=ON -DALICEVISION_USE_OPENCV=ON -DALICEVISION_USE_OPENGV=ON \ -DALICEVISION_USE_POPSIFT=ON -DALICEVISION_USE_CUDA=ON -DALICEVISION_BUILD_DOC=OFF -DALICEVISION_BUILD_EXAMPLES=OFF \ - "${AV_DEV}" + "${AV_DEV}" && \ +\ +make install && \ +\ +make bundle && \ +\ +cd /opt && \ +\ +rm -rf "${AV_BUILD}" -RUN make install && make bundle -# && cd /opt && rm -rf "${AV_BUILD}" diff --git a/Dockerfile_deps b/Dockerfile_deps index 95875cee13..b8a90da5e7 100644 --- a/Dockerfile_deps +++ b/Dockerfile_deps @@ -17,30 +17,39 @@ LABEL maintainer="AliceVision Team alicevision-team@googlegroups.com" # OS/Version (FILE): cat /etc/issue.net # Cuda version (ENV): $CUDA_VERSION -ENV AV_DEV=/opt/AliceVisionDeps_git \ - AV_BUILD=/tmp/AliceVisionDeps_build \ +ENV AV_DEPS_DEV=/opt/AliceVisionDeps_git \ + AV_DEPS_BUILD=/tmp/AliceVisionDeps_build \ AV_INSTALL=/opt/AliceVision_install \ AV_BUNDLE=/opt/AliceVision_bundle \ PATH="${PATH}:${AV_BUNDLE}" \ - VERBOSE=1 + VERBOSE=1 \ + YUM_INSTALL='yum install -y --setopt=tsflags=nodocs' +# # Install all compilation tools # - file and openssl are needed for cmake -RUN yum -y install centos-release-scl -RUN yum -y install \ - devtoolset-6 \ - devtoolset-6-make \ - devtoolset-6-gcc-gfortran \ - file \ - git \ - wget \ - unzip \ - yasm \ - pkg-config \ - libtool \ - nasm \ - automake \ - openssl-devel +# +# Workaround to give access to deprecated devtoolset-6 is taken from ASWF container: +# https://github.com/AcademySoftwareFoundation/aswf-docker/blob/master/scripts/common/install_yumpackages.sh#L119 +# +# Install packages one by one with yum to ensure that it creates an error if a package is missing. +# +RUN $YUM_INSTALL centos-release-scl-rh && \ + $YUM_INSTALL yum-utils && \ + sed -i 's/7/7.6.1810/g; s|^#\s*\(baseurl=http://\)mirror|\1vault|g; /mirrorlist/d' /etc/yum.repos.d/CentOS-SCLo-*.repo && \ + yum clean all && \ + $YUM_INSTALL devtoolset-6-toolchain --nogpgcheck && \ + $YUM_INSTALL --enablerepo=extras epel-release && \ + $YUM_INSTALL file && \ + $YUM_INSTALL git && \ + $YUM_INSTALL wget && \ + $YUM_INSTALL unzip && \ + $YUM_INSTALL yasm && \ + $YUM_INSTALL pkgconfig && \ + $YUM_INSTALL libtool && \ + $YUM_INSTALL nasm && \ + $YUM_INSTALL automake && \ + $YUM_INSTALL openssl-devel # Okay, change our shell to specifically use our software collections. # (default was SHELL [ "/bin/sh", "-c" ]) @@ -60,12 +69,27 @@ RUN wget https://cmake.org/files/v3.16/cmake-3.16.3.tar.gz && tar zxvf cmake-3.1 WORKDIR "${AV_BUNDLE}/share/aliceVision" RUN wget https://gitlab.com/alicevision/trainedVocabularyTreeData/raw/master/vlfeat_K80L3.SIFT.tree -COPY . "${AV_DEV}" +COPY . "${AV_DEPS_DEV}" + +WORKDIR "${AV_DEPS_BUILD}" +# Build and clear build files in one line to reduce image size (avoid intermediate cache) +RUN \ +\ +cmake "${AV_DEPS_DEV}" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS:BOOL=ON -DALICEVISION_BUILD_DEPENDENCIES:BOOL=ON -DAV_DEPS_BUILD_ALICEVISION:BOOL=OFF -DCMAKE_INSTALL_PREFIX="${AV_INSTALL}" -DALICEVISION_BUNDLE_PREFIX="${AV_BUNDLE}" && \ +\ +make -j8 && \ +\ +make install && \ +\ +mv ${AV_INSTALL}/bin ${AV_INSTALL}/bin_deps && \ +\ +cd /opt && \ +\ +rm -rf "${AV_DEPS_BUILD}" -WORKDIR "${AV_BUILD}" -RUN cmake "${AV_DEV}" -DCMAKE_BUILD_TYPE=Release -DALICEVISION_BUILD_DEPENDENCIES:BOOL=ON -DAV_BUILD_ALICEVISION:BOOL=OFF -DCMAKE_INSTALL_PREFIX="${AV_INSTALL}" -DALICEVISION_BUNDLE_PREFIX="${AV_BUNDLE}" +## To debug a specific library -WORKDIR "${AV_BUILD}" +# WORKDIR "${AV_DEPS_BUILD}" # RUN make zlib # RUN make geogram # RUN make tbb @@ -84,5 +108,3 @@ WORKDIR "${AV_BUILD}" # RUN make alembic # RUN make popsift -RUN make install && mv ${AV_INSTALL}/bin ${AV_INSTALL}/bin_deps -# && cd /opt && rm -rf "${AV_BUILD}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c713b92a0b..968650aaae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -346,7 +346,7 @@ find_package(Eigen3 3.3 REQUIRED) if(Eigen3_FOUND OR EIGEN3_FOUND) message(STATUS "EIGEN_INCLUDE_DIR: ${EIGEN_INCLUDE_DIR}") # See https://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html - set(AV_EIGEN_DEFINITIONS EIGEN_DONT_ALIGN_STATICALLY EIGEN_DONT_VECTORIZE) + set(AV_EIGEN_DEFINITIONS -DEIGEN_MAX_ALIGN_BYTES=0 -DEIGEN_MAX_STATIC_ALIGN_BYTES=0) else() message(FATAL_ERROR " EIGEN NOT FOUND. EIGEN_INCLUDE_DIR: ${EIGEN_INCLUDE_DIR}") endif() diff --git a/src/aliceVision/prettyprint.hpp b/src/aliceVision/prettyprint.hpp index 557be4773f..ca6225e0e2 100644 --- a/src/aliceVision/prettyprint.hpp +++ b/src/aliceVision/prettyprint.hpp @@ -49,17 +49,33 @@ namespace pretty_print struct has_begin_end : private sfinae_base { private: +#ifdef _MSC_VER + // Work around MSVC ICE in 15.9.x by moving decltype out to template + // typename + template + static yes & f(typename std::enable_if< + std::is_same(&C::begin)), + typename C::const_iterator(C::*)() const>::value>::type *); +#else // _MSCV_VER template static yes & f(typename std::enable_if< std::is_same(&C::begin)), typename C::const_iterator(C::*)() const>::value>::type *); +#endif // _MSCV_VER template static no & f(...); +#ifdef _MSC_VER + template + static yes & g(typename std::enable_if< + std::is_same(&C::end)), + typename C::const_iterator(C::*)() const>::value, void>::type*); +#else // _MSCV_VER template static yes & g(typename std::enable_if< - std::is_same(&C::end)), - typename C::const_iterator(C::*)() const>::value, void>::type*); + std::is_same(&C::end)), + typename C::const_iterator(C::*)() const>::value, void>::type*); +#endif // _MSCV_VER template static no & g(...); diff --git a/src/aliceVision/sensorDB/cameraSensors.db b/src/aliceVision/sensorDB/cameraSensors.db index dc8dffefdd..bc166d8ee0 100644 --- a/src/aliceVision/sensorDB/cameraSensors.db +++ b/src/aliceVision/sensorDB/cameraSensors.db @@ -625,6 +625,7 @@ Canon;Canon EOS M3;22.3;dpreview,digicamdb,imaging-resource,dxomark Canon;Canon EOS M5;22.3;dpreview,digicamdb,imaging-resource,dxomark Canon;Canon EOS M50;22.3;dpreview,digicamdb,imaging-resource,dxomark Canon;Canon EOS M6;22.3;dpreview,digicamdb,imaging-resource,dxomark +Canon;Canon EOS M6 Mark II;22.3;dpreview,digicamdb,imaging-resource,dxomark Canon;Canon EOS R;36.0;dpreview,digicamdb,imaging-resource Canon;Canon EOS Rebel SL1;22.3;dpreview,digicamdb,imaging-resource Canon;Canon EOS Rebel SL2;22.3;dpreview,digicamdb,imaging-resource diff --git a/src/aliceVision/voctree/Database.cpp b/src/aliceVision/voctree/Database.cpp index dd064210e4..9154213399 100644 --- a/src/aliceVision/voctree/Database.cpp +++ b/src/aliceVision/voctree/Database.cpp @@ -119,7 +119,7 @@ void Database::find( const SparseHistogram& query, std::size_t N, std::vector + namespace aliceVision { namespace voctree { float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const std::string &distanceMethod, const std::vector& word_weights) { - float distance = 0.0f; - float epsilon = 0.001; + float distance{0.0f}; + const float epsilon{0.001f}; - SparseHistogram::const_iterator i1 = v1.begin(), i1e = v1.end(); - SparseHistogram::const_iterator i2 = v2.begin(), i2e = v2.end(); + auto i1 = v1.cbegin(); + auto i1e = v1.cend(); + auto i2 = v2.cbegin(); + auto i2e = v2.cend(); - if(distanceMethod.compare("classic") == 0) + if(distanceMethod == "classic") { while(i1 != i1e && i2 != i2e) { @@ -34,7 +38,8 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const } else { - distance += fabs(i1->second.size() - i2->second.size()); + const auto val = std::minmax(i1->second.size(), i2->second.size()); + distance += static_cast(val.second - val.first); ++i1; ++i2; } @@ -53,11 +58,11 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const } } - else if(distanceMethod.compare("commonPoints") == 0) + else if(distanceMethod == "commonPoints") { - double score = 0.0; - double N1 = 0.0; - double N2 = 0.0; + float score{0.f}; + float N1{0.f}; + float N2{0.f}; while(i1 != i1e && i2 != i2e) { @@ -96,11 +101,11 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const distance = - score; } - else if(distanceMethod.compare("strongCommonPoints") == 0) + else if(distanceMethod == "strongCommonPoints") { - double score = 0.0; - double N1 = 0.0; - double N2 = 0.0; + float score{0.f}; + float N1{0.f}; + float N2{0.f}; while(i1 != i1e && i2 != i2e) { @@ -116,7 +121,7 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const } else { - if( ( fabs(i1->second.size() - 1.0) < epsilon ) && ( fabs(i2->second.size() - 1.0) < epsilon) ) + if( ( fabs(i1->second.size() - 1.f) < epsilon ) && ( fabs(i2->second.size() - 1.f) < epsilon) ) { score += 1; N1 += 1; @@ -142,11 +147,11 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const distance = - score; } - else if(distanceMethod.compare("weightedStrongCommonPoints") == 0) + else if(distanceMethod == "weightedStrongCommonPoints") { - double score = 0.0; - double N1 = 0.0; - double N2 = 0.0; + float score{0.f}; + float N1{0.f}; + float N2{0.f}; while(i1 != i1e && i2 != i2e) { @@ -160,7 +165,7 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const N1 += i1->second.size()*word_weights[i1->first]; ++i1; } - if( ( fabs(i1->second.size() - 1.0) < epsilon ) && ( fabs(i2->second.size() - 1.0) < epsilon) ) + if( ( fabs(i1->second.size() - 1.f) < epsilon ) && ( fabs(i2->second.size() - 1.f) < epsilon) ) { score += word_weights[i1->first]; N1 += word_weights[i1->first]; @@ -185,12 +190,12 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const distance = - score; } - else if(distanceMethod.compare("inversedWeightedCommonPoints") == 0) + else if(distanceMethod == "inversedWeightedCommonPoints") { - double score = 0.0; - double N1 = 0.0; - double N2 = 0.0; - std::map compteur; + float score{0.f}; + float N1{0.f}; + float N2{0.f}; + std::map counter; while(i1 != i1e && i2 != i2e) { @@ -206,7 +211,7 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const } else { - compteur[i1->first] += std::min(i1->second.size(), i2->second.size()); + counter[i1->first] += std::min(i1->second.size(), i2->second.size()); N1 += i1->second.size() / word_weights[i1->first]; N2 += i2->second.size() / word_weights[i2->first]; ++i1; @@ -222,12 +227,12 @@ float sparseDistance(const SparseHistogram& v1, const SparseHistogram& v2, const while(i2 != i2e) { - N2 += i2->second.size() / word_weights[i2->first];; + N2 += i2->second.size() / word_weights[i2->first]; ++i2; } - for(auto iCompteur = compteur.begin(); iCompteur != compteur.end(); iCompteur++) - score += (1.0/iCompteur->second) * word_weights[iCompteur->first]; + for(const auto elem : counter) + score += (1.f/ elem.second) * word_weights[elem.first]; distance = - score; } diff --git a/src/cmake/FindOpenEXR.cmake b/src/cmake/FindOpenEXR.cmake index 9a49580206..a13de99af1 100644 --- a/src/cmake/FindOpenEXR.cmake +++ b/src/cmake/FindOpenEXR.cmake @@ -63,11 +63,11 @@ if (EXISTS "${OPENEXR_INCLUDE_PATH}/OpenEXR/ImfMultiPartInputFile.h") # Must be at least 2.0 file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_STRING .*$") - string (REGEX MATCHALL "[0-9]+[.0-9]+" OPENEXR_VERSION ${TMP}) + string (REGEX MATCHALL "[0-9]+[.0-9]+" OPENEXR_VERSION "${TMP}") file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_MAJOR .*$") - string (REGEX MATCHALL "[0-9]+" OPENEXR_VERSION_MAJOR ${TMP}) + string (REGEX MATCHALL "[0-9]+" OPENEXR_VERSION_MAJOR "${TMP}") file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_MINOR .*$") - string (REGEX MATCHALL "[0-9]+" OPENEXR_VERSION_MINOR ${TMP}) + string (REGEX MATCHALL "[0-9]+" OPENEXR_VERSION_MINOR "${TMP}") else () message(STATUS "File ${OPENEXR_INCLUDE_PATH}/OpenEXR/ImfMultiPartInputFile.h does not exist. Default to 1.6.1") # Assume an old one, predates 2.x that had versions