From 08cc5e4c73175ebf3e9bb2295f718e914366d51b Mon Sep 17 00:00:00 2001 From: Kai Pastor Date: Wed, 15 Dec 2021 09:32:10 +0100 Subject: [PATCH] Find PROJ via cmake config or via pkg-config Drop the custom find module for PROJ. Cmake config or pkg-config data is provided from PROJ's build system. This covers PROJ 4.9 to 8.2, dynamic and static linkage, including transitive dependencies. --- CMakeLists.txt | 23 ++-- cmake/FindPROJ4.cmake | 152 ------------------------- doc/licensing/linux-distribution.cmake | 5 +- packaging/CMakeLists.txt | 25 ++-- packaging/android/Mapper.pro.in | 2 +- src/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 7 files changed, 31 insertions(+), 180 deletions(-) delete mode 100644 cmake/FindPROJ4.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index da5ad1e7b..e6a6ddeaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,20 +203,27 @@ endif() # We must not require a minimum version of PROJ via find_package # because PROJ config requires the major version to match exactly. -find_package(PROJ4 REQUIRED) -if(NOT TARGET PROJ4::proj) - include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindPROJ.cmake") +find_package(PROJ CONFIG) +if(NOT PROJ_LIBRARIES) + find_package(PkgConfig REQUIRED) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PROJ4_PC IMPORTED_TARGET proj) + endif() + if(TARGET PkgConfig::PROJ4_PC) + set(PROJ_LIBRARIES PkgConfig::PROJ4_PC) + set(PROJ_VERSION "${PROJ4_PC_VERSION}") + endif() endif() -if(NOT PROJ4_VERSION OR PROJ4_VERSION VERSION_LESS 4.9) +if(NOT PROJ_VERSION OR PROJ_VERSION VERSION_LESS 4.9) message(FATAL_ERROR "At least PROJ 4.9 is required") -elseif(PROJ4_VERSION VERSION_LESS 6.1) +elseif(PROJ_VERSION VERSION_LESS 6.1) # New PROJ API missing or incomplete. # (proj_normalize_for_visualization() came in 6.1.) - set_property(TARGET PROJ4::proj APPEND PROPERTY + set_property(TARGET "${PROJ_LIBRARIES}" APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS ACCEPT_USE_OF_DEPRECATED_PROJ_API_H) -elseif(PROJ4_VERSION VERSION_LESS 6.2.1) +elseif(PROJ_VERSION VERSION_LESS 6.2.1) # Datum Potsdam issue, https://github.com/OSGeo/PROJ/pull/1573 - set_property(TARGET PROJ4::proj APPEND PROPERTY + set_property(TARGET "${PROJ_LIBRARIES}" APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS PROJ_ISSUE_1573) endif() diff --git a/cmake/FindPROJ4.cmake b/cmake/FindPROJ4.cmake deleted file mode 100644 index 093deaa79..000000000 --- a/cmake/FindPROJ4.cmake +++ /dev/null @@ -1,152 +0,0 @@ -#.rst: -# FindPROJ4 -# -------- -# -# Find the proj includes and library. -# -# IMPORTED Targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines :prop_tgt:`IMPORTED` target ``PROJ4::proj``, -# if Proj.4 has been found. -# -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following variables: -# -# :: -# -# PROJ4_INCLUDE_DIRS - where to find proj_api.h, etc. -# PROJ4_LIBRARIES - List of libraries when using libproj. -# PROJ4_FOUND - True if libproj found. -# -# :: -# -# PROJ4_VERSION - The version of libproj found (x.y.z) -# PROJ4_VERSION_MAJOR - The major version of libproj -# PROJ4_VERSION_MINOR - The minor version of libproj -# PROJ4_VERSION_PATCH - The patch version of libproj -# PROJ4_VERSION_TWEAK - always 0 -# PROJ4_VERSION_COUNT - The number of version components, always 3 -# -# Hints -# ^^^^^ -# -# A user may set ``PROJ4_ROOT`` to a libproj installation root to tell this -# module where to look exclusively. - -#============================================================================= -# Copyright 2016 Kai Pastor -# -# -# This file was derived from CMake 3.5's module FindZLIB.cmake -# which has the following terms: -# -# Copyright 2001-2011 Kitware, Inc. -# -# 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. -# -# * The names of Kitware, Inc., the Insight Consortium, or the names of -# any consortium members, or of any contributors, may not be used to -# endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 AUTHORS 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. -#============================================================================= - -# Search PROJ4_ROOT exclusively if it is set. -if(PROJ4_ROOT) - set(_PROJ4_SEARCH PATHS ${PROJ4_ROOT} NO_DEFAULT_PATH) -else() - set(_PROJ4_SEARCH) -endif() - -find_path(PROJ4_INCLUDE_DIR NAMES proj_api.h ${_PROJ4_SEARCH} PATH_SUFFIXES include) -mark_as_advanced(PROJ4_INCLUDE_DIR) - -if(PROJ4_INCLUDE_DIR AND EXISTS "${PROJ4_INCLUDE_DIR}/proj_api.h") - file(STRINGS "${PROJ4_INCLUDE_DIR}/proj_api.h" PROJ4_H REGEX "^#define PJ_VERSION [0-9]+$") - - string(REGEX REPLACE "^.*PJ_VERSION ([0-9]).*$" "\\1" PROJ4_VERSION_MAJOR "${PROJ4_H}") - string(REGEX REPLACE "^.*PJ_VERSION [0-9]([0-9]).*$" "\\1" PROJ4_VERSION_MINOR "${PROJ4_H}") - string(REGEX REPLACE "^.*PJ_VERSION [0-9][0-9]([0-9]).*$" "\\1" PROJ4_VERSION_PATCH "${PROJ4_H}") - set(PROJ4_VERSION "${PROJ4_VERSION_MAJOR}.${PROJ4_VERSION_MINOR}.${PROJ4_VERSION_PATCH}") - set(PROJ4_VERSION_COUNT 3) -endif() - -# Allow PROJ4_LIBRARY to be set manually, as the location of the proj library -if(NOT PROJ4_LIBRARY) - set(PROJ4_NAMES proj) - set(PROJ4_NAMES_DEBUG projd) - if(WIN32 AND DEFINED PROJ4_VERSION_MAJOR AND DEFINED PROJ4_VERSION_MINOR) - list(APPEND PROJ4_NAMES proj_${PROJ4_VERSION_MAJOR}_${PROJ4_VERSION_MINOR}) - list(APPEND PROJ4_NAMES projd_${PROJ4_VERSION_MAJOR}_${PROJ4_VERSION_MINOR}) - endif() - find_library(PROJ4_LIBRARY_RELEASE NAMES ${PROJ4_NAMES} ${_PROJ4_SEARCH} PATH_SUFFIXES lib) - find_library(PROJ4_LIBRARY_DEBUG NAMES ${PROJ4_NAMES_DEBUG} ${_PROJ4_SEARCH} PATH_SUFFIXES lib) - include(SelectLibraryConfigurations) - select_library_configurations(PROJ4) -endif() - -# handle the QUIETLY and REQUIRED arguments and set PROJ4_FOUND to TRUE if -# all listed variables are TRUE -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(PROJ4 - REQUIRED_VARS - PROJ4_LIBRARY - PROJ4_INCLUDE_DIR - VERSION_VAR - PROJ4_VERSION -) - -if(PROJ4_FOUND) - set(PROJ4_INCLUDE_DIRS ${PROJ4_INCLUDE_DIR}) - - if(NOT PROJ4_LIBRARIES) - set(PROJ4_LIBRARIES ${PROJ4_LIBRARY}) - endif() - - if(NOT TARGET PROJ4::proj) - add_library(PROJ4::proj UNKNOWN IMPORTED) - set_target_properties(PROJ4::proj PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PROJ4_INCLUDE_DIRS}") - - if(PROJ4_LIBRARY_RELEASE) - set_property(TARGET PROJ4::proj APPEND PROPERTY - IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(PROJ4::proj PROPERTIES - IMPORTED_LOCATION_RELEASE "${PROJ4_LIBRARY_RELEASE}") - endif() - - if(PROJ4_LIBRARY_DEBUG) - set_property(TARGET PROJ4::proj APPEND PROPERTY - IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(PROJ4::proj PROPERTIES - IMPORTED_LOCATION_DEBUG "${PROJ4_LIBRARY_DEBUG}") - endif() - - if(NOT PROJ4_LIBRARY_RELEASE AND NOT PROJ4_LIBRARY_DEBUG) - set_property(TARGET PROJ4::proj APPEND PROPERTY - IMPORTED_LOCATION "${PROJ4_LIBRARY}") - endif() - endif() -endif() diff --git a/doc/licensing/linux-distribution.cmake b/doc/licensing/linux-distribution.cmake index b2bc5d72c..7a1d39f7b 100644 --- a/doc/licensing/linux-distribution.cmake +++ b/doc/licensing/linux-distribution.cmake @@ -106,9 +106,8 @@ foreach(dependency ${easy_dependencies}) elseif(dependency STREQUAL "libpolyclipping") find_package(Polyclipping) list(APPEND explicit_copyright_${dependency} "${POLYCLIPPING_VERSION}") - elseif(dependency STREQUAL "proj") - find_package(PROJ4) - list(APPEND explicit_copyright_${dependency} "${PROJ4_VERSION}") + elseif(dependency STREQUAL "proj" AND PROJ_VERSION) + list(APPEND explicit_copyright_${dependency} "${PROJ_VERSION}") elseif(dependency STREQUAL "zlib") find_package(ZLIB) list(APPEND explicit_copyright_${dependency} "${ZLIB_VERSION_STRING}") diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 4a981c681..eabb4bb14 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -235,25 +235,22 @@ unset(MAPPER_LIBS) if(Mapper_PACKAGE_PROJ) if(NOT PROJ_DATA_DIR) - unset(PROJ_DATA_DIR CACHE) - if(PROJ4_ROOT) - set(proj_data_paths "${PROJ4_ROOT}/share/proj") - elseif(PROJ4_DIR) + if(PROJ_DIR) # Cf. find_package documentation - string(REGEX REPLACE "/CMake$|/cmake$" "" proj_data_paths "${PROJ4_DIR}") # U - string(REGEX REPLACE "/PROJ4[^/]*$|/proj4[^/]*$" "" proj_data_paths "${proj_data_paths}") # U, W - string(REGEX REPLACE "/cmake$" "" proj_data_paths "${proj_data_paths}") # U - string(REGEX REPLACE "/lib/[^/]*$|/lib$|/share$" "" proj_data_paths "${proj_data_paths}") # U, W - set(proj_data_paths "${proj_data_paths}/share/proj") - elseif(PROJ4_INCLUDE_DIRS) - string(REGEX REPLACE "/include$" "/share/proj" proj_data_paths ${PROJ4_INCLUDE_DIRS}) # MSYS2 et al. + string(REGEX REPLACE "/CMake$|/cmake$" "" proj_prefix "${PROJ_DIR}") # U + string(REGEX REPLACE "/PROJ[^/]*$|/proj[^/]*$" "" proj_prefix "${proj_prefix}") # U, W + string(REGEX REPLACE "/cmake$" "" proj_prefix "${proj_prefix}") # U + string(REGEX REPLACE "/lib/[^/]*$|/lib$|/share$" "" proj_prefix "${proj_prefix}") # U, W + elseif(PROJ4_PC_PREFIX) + set(proj_prefix "${PROJ4_PC_PREFIX}") else() - set(proj_data_paths PATHS "${CMAKE_INSTALL_PREFIX}/share/proj") + set(proj_prefix "${CMAKE_INSTALL_PREFIX}") endif() find_path(PROJ_DATA_DIR DOC "The PROJ data files directory" NAMES epsg proj.db - PATHS ${proj_data_paths} + PATHS ${proj_prefix} + PATH_SUFFIXES "share/proj" "share" NO_DEFAULT_PATH ) endif() @@ -266,7 +263,7 @@ if(Mapper_PACKAGE_PROJ) install( DIRECTORY "${PROJ_DATA_DIR}" DESTINATION "${MAPPER_DATA_DESTINATION}") - list(APPEND MAPPER_LIB_HINTS ${PROJ4_ROOT}/bin) + list(APPEND MAPPER_LIB_HINTS "${proj_prefix}/bin") endif() if(Mapper_PACKAGE_GDAL) diff --git a/packaging/android/Mapper.pro.in b/packaging/android/Mapper.pro.in index b3e88ca11..2017e3933 100644 --- a/packaging/android/Mapper.pro.in +++ b/packaging/android/Mapper.pro.in @@ -38,7 +38,7 @@ PROJECT_BINARY_DIR = "@PROJECT_BINARY_DIR@" # in CPackConfig.cmake when a package version changes. CPACK_CONFIG_CLEANUP_TRIGGER = \ GDAL: @GDAL_VERSION@ \ - PROJ: @PROJ4_VERSION@ \ + PROJ: @PROJ_VERSION@ \ Qt5: @Qt5Core_VERSION@ # For the generated .pro file to be used in Qt Creator, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a4b7d1454..aff2fa8e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -301,7 +301,7 @@ add_dependencies(Mapper_Common ) target_link_libraries(Mapper_Common Polyclipping::Polyclipping - PROJ4::proj + ${PROJ_LIBRARIES} Qt5::Widgets ) foreach(lib diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 37d5278da..19b2567d9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -65,7 +65,7 @@ function(add_test_helper testname autorun) endforeach() add_executable(${testname} ${testname}.cpp ${TEST_${testname}_SRCS}) target_link_libraries(${testname} PRIVATE - PROJ4::proj + ${PROJ_LIBRARIES} Qt5::Test Qt5::Gui Polyclipping::Polyclipping