相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

On Debian, I've installed cmake and geographiclib like so:

stew@stewbian:~$apt-get install build-essential cmake libgeographic-dev

My CMakeLists.txt file looks like so:

cmake_minimum_required(VERSION 3.7)
project(geoexample)
find_package(GeographicLib REQUIRED)
add_executable(geoexample main.cpp)
target_include_directories(geoexample PRIVATE ${GeographicLib_INCLUDE_DIRS})
target_compile_definitions(geoexample PRIVATE ${GeographicLib_DEFINITIONS})
target_link_libraries     (geoexample         ${GeographicLib_LIBRARIES})

My main.cpp is also very simple (taken directly from examples):

#include <iostream>
#include <GeographicLib/Geodesic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
    const Geodesic& geod = Geodesic::WGS84();
    // Distance from JFK to LHR
    double
      lat1 = 40.6, lon1 = -73.8, // JFK Airport
      lat2 = 51.6, lon2 = -0.5;  // LHR Airport
    double s12;
    geod.Inverse(lat1, lon1, lat2, lon2, s12);
    cout << s12 / 1000 << " km\n";
    return 0;

When I run mkdir build && cd build && cmake .. I get

stew@stewbian:~/src/geoexample/build$ cmake ..
CMake Error at CMakeLists.txt:3 (find_package):
  By not providing "FindGeographicLib.cmake" in CMAKE_MODULE_PATH this
  project has asked CMake to find a package configuration file provided by
  "GeographicLib", but CMake did not find one.

I think that by default, cmake searches /usr/share/cmake-3.7/Modules, but libgeographic-dev seems to have installed its Find*.cmake to /usr/share/cmake/geographiclib/FindGeographicLib.cmake. That's frustrating, but myself (plus everyone who will ever need to compile my code) should be able to use a work-around for this simple case (it wouldn't work so well if I need to also include something like FindBoost.cmake from the old location).

stew@stewbian:~/src/geoexample/build$ cmake .. -DCMAKE_MODULE_PATH=/usr/share/cmake/geographiclib
CMake Error at /usr/share/cmake-3.7/Modules/FindPackageHandleStandardArgs.cmake:138 (message):
  Could NOT find GeographicLib (missing: GeographicLib_LIBRARY_DIRS
  GeographicLib_INCLUDE_DIRS)
Call Stack (most recent call first):
  /usr/share/cmake-3.7/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake/geographiclib/FindGeographicLib.cmake:28 (find_package_handle_standard_args)
  CMakeLists.txt:4 (find_package)
-- Configuring incomplete, errors occurred!

Now I'm not sure what to do here. I can confirm that libgeographic-dev package installed /usr/lib/x86_64-linux-gnu/libGeographic.a and /usr/lib/x86_64-linux-gnu/libGeographic.so

The geographiclib-dev installer puts the FindGeographicLib.cmake file in: /usr/share/cmake/geographiclib/FindGeographicLib.cmake

The correct location is: /usr/share/cmake-3.5/Modules

Indeed it depends by the version of cmake currently installed. In Ubuntu 18.04, it's 3-10.

So you can fix the issue this way:

sudo ln -s /usr/share/cmake/geographiclib/FindGeographicLib.cmake /usr/share/cmake-3.10/Modules/

I wrote my own FindGeographicLib.cmake to find this and installed it in a subfolder of my project. Then I pointed ${CMAKE_MODULES_PATH} to this folder in my project's CMakeLists.txt:

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)

I started by adding the one deployed by libgeographic-dev:

cp /usr/share/cmake/geographiclib/FindGeographicLib.cmake ./modules/FindGeographicLib.cmake

Unfortunately, that didn't work out of the box. The library was found at /usr/lib/x86_64-linux-gnu/libGeographic.so and the extra x86_64-linux-gnu wasn't handled well by the script. It tried (and failed) to find the headers in /usr/lib/include. I made some tweaks to the scripts to also check for this case and now I have a working solution.

The new FindGeographicLib.cmake is shown below. My changes are indicated with comments to the right of the applicable lines.

# Look for GeographicLib
# Sets
#  GeographicLib_FOUND = TRUE
#  GeographicLib_INCLUDE_DIRS = /usr/local/include
#  GeographicLib_LIBRARIES = /usr/local/lib/libGeographic.so
#  GeographicLib_LIBRARY_DIRS = /usr/local/lib
find_library (GeographicLib_LIBRARIES Geographic
  PATHS "${CMAKE_INSTALL_PREFIX}/../GeographicLib/lib")
  if (GeographicLib_LIBRARIES)
  get_filename_component (GeographicLib_LIBRARY_DIRS
    "${GeographicLib_LIBRARIES}" PATH)
  get_filename_component (_ROOT_DIR "${GeographicLib_LIBRARY_DIRS}" PATH)
  set (GeographicLib_INCLUDE_DIRS "${_ROOT_DIR}/include")
  set (GeographicLib_BINARY_DIRS "${_ROOT_DIR}/bin")
  if (NOT EXISTS "${GeographicLib_INCLUDE_DIRS}/GeographicLib/Config.h")
    get_filename_component(_ROOT_DIR "${_ROOT_DIR}" PATH)                     # Added to script
    set (GeographicLib_INCLUDE_DIRS "${_ROOT_DIR}/include")                   # Added to script
    set (GeographicLib_BINARY_DIRS "${_ROOT_DIR}/bin")                        # Added to script
    if (NOT EXISTS "${GeographicLib_INCLUDE_DIRS}/GeographicLib/Config.h")    # Added to script
      unset (GeographicLib_INCLUDE_DIRS)
      unset (GeographicLib_LIBRARIES)
      unset (GeographicLib_LIBRARY_DIRS)
      unset (GeographicLib_BINARY_DIRS)
    endif()                                                                   # Added to script
  endif ()
  unset (_ROOT_DIR)                                                           # Moved below if() statements
endif ()
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (GeographicLib DEFAULT_MSG
  GeographicLib_LIBRARY_DIRS GeographicLib_LIBRARIES GeographicLib_INCLUDE_DIRS)
mark_as_advanced (GeographicLib_LIBRARY_DIRS GeographicLib_LIBRARIES
  GeographicLib_INCLUDE_DIRS)

Workaround for downstream projects: add

set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/share/cmake/geographiclib")

just before find_package(GeographicLib REQUIRED). This fixes the broken Debian/Ubuntu installer. Other distros may put the files elsewhere, though...

At least Ubuntu 18.04 has already fixed the CMake find module to be also able to find libraries in the x86_64 subfolder... That was one part of the original problem. The other part - nonstandard location of the cmake file - is resolved by the line I've posted. – Martin Pecka Aug 8, 2022 at 14:59

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.