在 Debian 上的 CMake 中查找 GeographicLib
Finding GeographicLib in CMake on Debian
在 Debian 上,我像这样安装了 cmake 和 geographiclib:
stew@stewbian:~$apt-get install build-essential cmake libgeographic-dev
我的 CMakeLists.txt 文件如下所示:
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})
我的main.cpp也很简单(直接取自例子):
#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;
}
当我 运行 mkdir build && cd build && cmake ..
我得到
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.
我认为默认情况下,cmake 会搜索 /usr/share/cmake-3.7/Modules
,但 libgeographic-dev 似乎已将其 Find*.cmake 安装到 /usr/share/cmake/geographiclib/FindGeographicLib.cmake
。这令人沮丧,但我自己(以及所有需要编译我的代码的人)应该能够针对这个简单的案例使用变通方法(如果我还需要包含 FindBoost.cmake 从旧位置)。
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!
现在我不确定在这里做什么。我可以确认安装了 libgeographic-dev 包 /usr/lib/x86_64-linux-gnu/libGeographic.a
和 /usr/lib/x86_64-linux-gnu/libGeographic.so
我自己编写了 FindGeographicLib.cmake 来找到它并将其安装在我项目的子文件夹中。然后我将 ${CMAKE_MODULES_PATH}
指向项目 CMakeLists.txt 中的这个文件夹:
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)
我首先添加了 libgeographic-dev 部署的那个:
cp /usr/share/cmake/geographiclib/FindGeographicLib.cmake ./modules/FindGeographicLib.cmake
不幸的是,这不是开箱即用的。在 /usr/lib/x86_64-linux-gnu/libGeographic.so
处找到了该库,脚本没有很好地处理额外的 x86_64-linux-gnu
。它尝试(但失败了)在 /usr/lib/include
中找到 headers。我对脚本进行了一些调整以检查这种情况,现在我有了一个可行的解决方案。
新的FindGeographicLib.cmake
如下所示。我的更改在适用行的右侧用注释表示。
# 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)
据此Bug Report,
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
确实取决于当前安装的cmake版本。在Ubuntu 18.04 中,它是 3-10。
所以您可以这样解决问题:
sudo ln -s /usr/share/cmake/geographiclib/FindGeographicLib.cmake /usr/share/cmake-3.10/Modules/
在 Debian 上,我像这样安装了 cmake 和 geographiclib:
stew@stewbian:~$apt-get install build-essential cmake libgeographic-dev
我的 CMakeLists.txt 文件如下所示:
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})
我的main.cpp也很简单(直接取自例子):
#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;
}
当我 运行 mkdir build && cd build && cmake ..
我得到
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.
我认为默认情况下,cmake 会搜索 /usr/share/cmake-3.7/Modules
,但 libgeographic-dev 似乎已将其 Find*.cmake 安装到 /usr/share/cmake/geographiclib/FindGeographicLib.cmake
。这令人沮丧,但我自己(以及所有需要编译我的代码的人)应该能够针对这个简单的案例使用变通方法(如果我还需要包含 FindBoost.cmake 从旧位置)。
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!
现在我不确定在这里做什么。我可以确认安装了 libgeographic-dev 包 /usr/lib/x86_64-linux-gnu/libGeographic.a
和 /usr/lib/x86_64-linux-gnu/libGeographic.so
我自己编写了 FindGeographicLib.cmake 来找到它并将其安装在我项目的子文件夹中。然后我将 ${CMAKE_MODULES_PATH}
指向项目 CMakeLists.txt 中的这个文件夹:
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)
我首先添加了 libgeographic-dev 部署的那个:
cp /usr/share/cmake/geographiclib/FindGeographicLib.cmake ./modules/FindGeographicLib.cmake
不幸的是,这不是开箱即用的。在 /usr/lib/x86_64-linux-gnu/libGeographic.so
处找到了该库,脚本没有很好地处理额外的 x86_64-linux-gnu
。它尝试(但失败了)在 /usr/lib/include
中找到 headers。我对脚本进行了一些调整以检查这种情况,现在我有了一个可行的解决方案。
新的FindGeographicLib.cmake
如下所示。我的更改在适用行的右侧用注释表示。
# 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)
据此Bug Report,
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
确实取决于当前安装的cmake版本。在Ubuntu 18.04 中,它是 3-10。
所以您可以这样解决问题:
sudo ln -s /usr/share/cmake/geographiclib/FindGeographicLib.cmake /usr/share/cmake-3.10/Modules/