################################################################################ # # This file is part of CMake configuration for PROJ library (inspired from SOCI # CMake, Copyright (C) 2009-2010 Mateusz Loskot ) # # Copyright (C) 2011 Nicolas David # Distributed under the MIT license # ################################################################################ # General settings ################################################################################ cmake_minimum_required(VERSION 3.16) project(PROJ DESCRIPTION "PROJ coordinate transformation software library" LANGUAGES C CXX ) # Only interpret if() arguments as variables or keywords when unquoted cmake_policy(SET CMP0054 NEW) # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard version to use (default is 17)") message(STATUS "Requiring C++${CMAKE_CXX_STANDARD}") set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) message(STATUS "Requiring C++${CMAKE_CXX_STANDARD} - done") # Set C99 version # Make CMAKE_C_STANDARD available as cache option overridable by user set(CMAKE_C_STANDARD 99 CACHE STRING "C standard version to use (default is 99)") message(STATUS "Requiring C${CMAKE_C_STANDARD}") set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) message(STATUS "Requiring C${CMAKE_C_STANDARD} - done") # Set global -fvisibility=hidden set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) # Set warnings as variables, then store as cache options set(PROJ_common_WARN_FLAGS # common only to GNU/Clang C/C++ -Wall -Wdate-time -Werror=format-security -Werror=vla -Wextra -Wformat -Wmissing-declarations -Wshadow -Wswitch -Wunused-parameter ) if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") set(PROJ_common_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wimplicit-fallthrough ) set(PROJ_C_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wmissing-prototypes ) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8) set(PROJ_CXX_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wextra-semi) endif() set(PROJ_CXX_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Weffc++ # -Wold-style-cast -Woverloaded-virtual -Wzero-as-null-pointer-constant -Wdeprecated-copy-dtor ) elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") set(PROJ_common_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wcomma -Wdeprecated -Wdocumentation -Wno-documentation-deprecated-sync -Wfloat-conversion -Wlogical-op-parentheses -Wimplicit-fallthrough ) # Not sure about the minimum version, but clang 12 complains about \file, @cond Doxygen_Suppress, etc. if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER_EQUAL 18.0.0) set(PROJ_common_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wdocumentation-unknown-command) endif() set(PROJ_C_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Wmissing-prototypes -Wc11-extensions ) set(PROJ_CXX_WARN_FLAGS ${PROJ_common_WARN_FLAGS} -Weffc++ -Wextra-semi # -Wold-style-cast -Woverloaded-virtual -Wshorten-64-to-32 -Wunused-private-field -Wzero-as-null-pointer-constant -Wdeprecated-copy-dtor -Wweak-vtables ) elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Eliminate deprecation warnings set(PROJ_C_WARN_FLAGS /W4 /wd4706 # Suppress warning about assignment within conditional expression /wd4996 # Suppress warning about sprintf, etc., being unsafe ) if("$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "arm64") # Suppress an inaccurate warning when compiling for an MSVC/ARM64 platform # It incorrectly assumes a division by zero is possible despite a check set(PROJ_C_WARN_FLAGS ${PROJ_C_WARN_FLAGS} /wd4723) endif() set(PROJ_CXX_WARN_FLAGS /EHsc ${PROJ_C_WARN_FLAGS}) elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") if(MSVC) set(PROJ_C_WARN_FLAGS /Wall) set(PROJ_CXX_WARN_FLAGS /Wall) else() set(PROJ_C_WARN_FLAGS -Wall) set(PROJ_CXX_WARN_FLAGS -Wall) endif() endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") # Intel CXX compiler based on clang defaults to -ffast-math, which # breaks std::isinf(), std::isnan(), etc. set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -fno-fast-math) set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -fno-fast-math) endif () set(PROJ_C_WARN_FLAGS "${PROJ_C_WARN_FLAGS}" CACHE STRING "C flags used to compile PROJ targets") set(PROJ_CXX_WARN_FLAGS "${PROJ_CXX_WARN_FLAGS}" CACHE STRING "C++ flags used to compile PROJ targets") ################################################################################ # PROJ CMake modules ################################################################################ # Path to additional CMake modules set(CMAKE_MODULE_PATH ${PROJ_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) include(ProjUtilities) message(STATUS "Configuring PROJ:") ################################################################################ #PROJ version information ################################################################################ include(ProjVersion) proj_version(MAJOR 9 MINOR 8 PATCH 0) set(PROJ_SOVERSION 25) set(PROJ_BUILD_VERSION "${PROJ_SOVERSION}.${PROJ_VERSION}") ################################################################################ # Build features and variants ################################################################################ include(Ccache) include(ProjConfig) include(ProjMac) include(policies) ############################################## ### SWITCH BETWEEN STATIC OR SHARED LIBRARY### ############################################## # default config is shared option(BUILD_SHARED_LIBS "Build PROJ library shared." ON) ################################################################################ # Check for nlohmann_json ################################################################################ set(NLOHMANN_JSON_ORIGIN "auto" CACHE STRING "nlohmann/json origin. The default auto will try to use external \ nlohmann/json if possible") set_property(CACHE NLOHMANN_JSON_ORIGIN PROPERTY STRINGS auto internal external) # Probably not the strictest minimum, but known to work with it set(MIN_NLOHMANN_JSON_VERSION 3.7.0) if(NLOHMANN_JSON_ORIGIN STREQUAL "external") find_package(nlohmann_json REQUIRED) set(NLOHMANN_JSON "external") elseif(NLOHMANN_JSON_ORIGIN STREQUAL "internal") set(NLOHMANN_JSON "internal") else() find_package(nlohmann_json QUIET) if(nlohmann_json_FOUND) set(NLOHMANN_JSON "external") else() set(NLOHMANN_JSON "internal") endif() endif() if(NLOHMANN_JSON STREQUAL "external") # Check minimum version if(nlohmann_json_VERSION VERSION_LESS MIN_NLOHMANN_JSON_VERSION) message(STATUS "external nlohmann/json version ${nlohmann_json_VERSION} " "is older than minimum requirement ${MIN_NLOHMANN_JSON_VERSION}") set(NLOHMANN_JSON "internal") else() message(STATUS "found nlohmann/json version ${nlohmann_json_VERSION}") endif() endif() message(STATUS "nlohmann/json: ${NLOHMANN_JSON}") ################################################################################ # Check for sqlite3 ################################################################################ find_program(EXE_SQLITE3 sqlite3) if(NOT EXE_SQLITE3) message(SEND_ERROR "sqlite3 binary not found!") endif() # Deprecated variables since PROJ 9.4.0 if(DEFINED SQLITE3_INCLUDE_DIR) message(DEPRECATION "Use SQLite3_INCLUDE_DIR instead of SQLITE3_INCLUDE_DIR") set(SQLite3_INCLUDE_DIR ${SQLITE3_INCLUDE_DIR}) endif() if(DEFINED SQLITE3_LIBRARY) message(DEPRECATION "Use SQLite3_LIBRARY instead of SQLITE3_LIBRARY") set(SQLite3_LIBRARY ${SQLITE3_LIBRARY}) endif() find_package(SQLite3 REQUIRED) # Would build and run with older versions, but with horrible performance # See https://github.com/OSGeo/PROJ/issues/1718 if(SQLite3_VERSION VERSION_LESS "3.11") message(SEND_ERROR "SQLite3 >= 3.11 required!") endif() ################################################################################ # Check for libtiff ################################################################################ option(ENABLE_TIFF "Enable TIFF support to read some grids" ON) mark_as_advanced(ENABLE_TIFF) set(TIFF_ENABLED FALSE) if(ENABLE_TIFF) find_package(TIFF REQUIRED) if(TIFF_FOUND) set(TIFF_ENABLED TRUE) else() message(SEND_ERROR "libtiff dependency not found! Use ENABLE_TIFF=OFF to force it off") endif() else() message(WARNING "TIFF support is not enabled and will result in the inability to read " "some grids") endif() ################################################################################ # Check for curl ################################################################################ option(ENABLE_CURL "Enable Curl support" ON) set(CURL_ENABLED FALSE) if(ENABLE_CURL) find_package(CURL REQUIRED) if(CURL_FOUND) set(CURL_ENABLED TRUE) # Curl SSL options are described in # https://curl.se/libcurl/c/CURLOPT_SSL_OPTIONS.html #set(CURLSSLOPT_NO_REVOKE 2) #set(SSL_OPTIONS ${CURLSSLOPT_NO_REVOKE}) #add_compile_definitions(SSL_OPTIONS=${SSL_OPTIONS}) else() message(SEND_ERROR "curl dependency not found!") endif() endif() ################################################################################ option(EMBED_PROJ_DATA_PATH "Whether the PROJ_DATA_PATH should be embedded" ON) if(DEFINED PROJ_LIB_ENV_VAR_TRIED_LAST) set(PROJ_DATA_ENV_VAR_TRIED_LAST ${PROJ_LIB_ENV_VAR_TRIED_LAST}) message(WARNING "PROJ_LIB_ENV_VAR_TRIED_LAST option has been renamed to PROJ_DATA_ENV_VAR_TRIED_LAST. PROJ_LIB_ENV_VAR_TRIED_LAST is still working for now, but may be completely replaced by PROJ_DATA_ENV_VAR_TRIED_LAST in a future release") else() option(PROJ_DATA_ENV_VAR_TRIED_LAST "Whether the PROJ_DATA environment variable should be tried after the hardcoded location" OFF) endif() if(PROJ_DATA_ENV_VAR_TRIED_LAST) add_definitions(-DPROJ_DATA_ENV_VAR_TRIED_LAST) endif() ################################################################################ # threading configuration ################################################################################ set(CMAKE_THREAD_PREFER_PTHREAD TRUE) find_package(Threads) if(Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}") endif() # Set a default build type for single-configuration cmake generators if # no build type is set. if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() if(MSVC OR CMAKE_CONFIGURATION_TYPES) # For multi-config systems and for Visual Studio, the debug version of # the library has _d appended. set(CMAKE_DEBUG_POSTFIX _d) endif() # Put the libraries and binaries that get built into directories at the # top of the build tree rather than in hard-to-find leaf # directories. This simplifies manual testing and the use of the build # tree rather than installed PROJ libraries. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJ_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJ_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJ_BINARY_DIR}/bin) link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) ################################################################################ # Installation ################################################################################ include(ProjInstallPath) # By default GNUInstallDirs will use the upper case project name # for CMAKE_INSTALL_DOCDIR, resulting in something like share/doc/PROJ # instead of share/doc/proj which historically have been the path used # by the project. # Here force the use of a lower case project name and reset after # GNUInstallDirs has done its thing set(PROJECT_NAME_ORIGINAL "${PROJECT_NAME}") string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME) include(GNUInstallDirs) set(PROJECT_NAME "${PROJECT_NAME_ORIGINAL}") set(PROJ_DATA_PATH "${CMAKE_INSTALL_FULL_DATADIR}/proj") ################################################################################ # Tests ################################################################################ option(BUILD_TESTING "Build the testing tree." ON) if(BUILD_TESTING) enable_testing() include(ProjTest) else() message(STATUS "Testing disabled") endif() ################################################################################ # Whether we should embed resources ################################################################################ function (is_sharp_embed_available res) if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.21 AND ((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0) OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0))) # CMAKE_C_STANDARD=23 only supported since CMake 3.21 set(TEST_SHARP_EMBED "static const unsigned char embedded[] = {\n#embed __FILE__\n};\nint main() { (void)embedded; return 0;}" ) set(CMAKE_C_STANDARD_BACKUP "${CMAKE_C_STANDARD}") set(CMAKE_C_STANDARD "23") check_c_source_compiles("${TEST_SHARP_EMBED}" _TEST_SHARP_EMBED) set(CMAKE_C_STANDARD "${CMAKE_C_STANDARD_BACKUP}") if (_TEST_SHARP_EMBED) set(${res} ON PARENT_SCOPE) else() set(${res} OFF PARENT_SCOPE) endif() else() set(${res} OFF PARENT_SCOPE) endif() endfunction() is_sharp_embed_available(IS_SHARP_EMBED_AVAILABLE_RES) if (NOT DEFINED BUILD_SHARED_LIBS) message(FATAL_ERROR "BUILD_SHARED_LIBS should be set") endif() if (NOT BUILD_SHARED_LIBS) set(DEFAULT_EMBED_RESOURCE_FILES ON) else() set(DEFAULT_EMBED_RESOURCE_FILES OFF) endif() option(EMBED_RESOURCE_FILES "Whether resource files (limited to proj.db) should be embedded into the PROJ library" ${DEFAULT_EMBED_RESOURCE_FILES}) option(USE_ONLY_EMBEDDED_RESOURCE_FILES "Whether embedded resource files (limited to proj.db) should be used (should nominally be used together with EMBED_RESOURCE_FILES=ON, otherwise this will result in non-functional builds)" OFF) if (USE_ONLY_EMBEDDED_RESOURCE_FILES AND NOT EMBED_RESOURCE_FILES) message(WARNING "USE_ONLY_EMBEDDED_RESOURCE_FILES=ON set but EMBED_RESOURCE_FILES=OFF: some drivers will lack required resource files") endif() ################################################################################ # Build configured components ################################################################################ set(PROJ_DICTIONARY world other.extra nad27 GL27 nad83 nad.lst CH ITRF2000 ITRF2008 ITRF2014 ITRF2020 ) include_directories(${PROJ_SOURCE_DIR}/src) add_subdirectory(data) add_subdirectory(include) add_subdirectory(src) add_subdirectory(man) add_subdirectory(cmake) if(BUILD_TESTING) add_subdirectory(test) endif() option(BUILD_EXAMPLES "Whether to build example programs" OFF) if(BUILD_EXAMPLES) add_subdirectory(examples) endif() add_subdirectory(scripts) set(docfiles COPYING NEWS.md AUTHORS.md) install(FILES ${docfiles} DESTINATION ${CMAKE_INSTALL_DOCDIR}) ################################################################################ # Build debug symbols ################################################################################ option(EXPORT_PDB "Export PDB file" OFF) if (WIN32 AND EXPORT_PDB) target_compile_options(proj PRIVATE /Zi /Zf) target_link_options(proj PRIVATE /DEBUG /OPT:REF /OPT:ICF) if(BUILD_SHARED_LIBS) set(pdbFile $) else() set(pdbDirFullPath ${CMAKE_BINARY_DIR}/lib) set_target_properties(proj PROPERTIES COMPILE_PDB_OUTPUT_DIRECTORY ${pdbDirFullPath} COMPILE_PDB_NAME proj) set(pdbFile ${pdbDirFullPath}/proj.pdb) endif() install(FILES ${pdbFile} DESTINATION lib) endif() ################################################################################ # pkg-config support ################################################################################ configure_proj_pc() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/proj.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") ################################################################################ # "make dist" workalike ################################################################################ set(CPACK_SOURCE_GENERATOR "TGZ;ZIP") set(CPACK_SOURCE_PACKAGE_FILE_NAME "proj-${PROJ_VERSION}") set(CPACK_PACKAGE_VENDOR "OSGeo") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJ_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJ_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJ_VERSION_PATCH}) set(CPACK_VERBATIM_VARIABLES TRUE) set(CPACK_SOURCE_IGNORE_FILES /\\..* # any file/directory starting with . /.*\\.yml /.*\\.gz /.*\\.zip /.*build.*/ \\.deps /autogen\\.sh /autom4te\\.cache /CODE_OF_CONDUCT.md /CONTRIBUTING.md /disabled_workflows/ /Dockerfile /docs/ /Doxyfile /HOWTO-RELEASE.md /m4/lt* /m4/libtool* /media/ /schemas/ /test/fuzzers/ /test/gigs/.*gie\\.failing /test/postinstall/ /travis/ ${PROJECT_BINARY_DIR} ) include(CPack) get_property(_is_multi_config_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(NOT _is_multi_config_generator) add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source ) message(STATUS "PROJ: Configured 'dist' target") endif() configure_file(cmake/uninstall.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake) message(STATUS "EMBED_RESOURCE_FILES=${EMBED_RESOURCE_FILES}")