-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor CMake build configuration (#3)
* allow using pre-built or pre-installed s2geometry Enabled by default. For downloading and building s2geometry as part of building s2geography, set `S2GEOGRAPHY_FETCH_S2GEOMETRY=ON`. * manage absl build and install externally Currently we do not support downloading, building and installing absl as part of this project (not sure we will ever need it?). absl supports cmake's find_package(): abseil/abseil-cpp#111 * fix typo * allow using pre-built or pre-installed googletest Enabled by default. To download and build googletest as part of building s2geography tests, set `S2GEOGRAPHY_FETCH_GTEST=ON`. * set C++ standard to c++17 Use `CACHE` for `CMAKE_CXX_STANDARD` so that it can be overriden. * update cmake preset example * build shared libraries by default * exclude googletest from all installed targets * update CI * temp fix for CI run example? * review dependencies management in the CMake build - Use an approach inspired by Arrow for getting s2geometry - Always bundle GTest (update to last version to suppress the MACOSX_RPATH CMake warning) * fix S2_SOURCE AUTO mode * quick and dirty fix for Homebrew installed S2 * tell which version of S2 is bundled * fix openssl header homebrew + bundled * fix conda s2geometry Prevent picking the wrong s2geometry install when it is both installed in a conda active environment and another default system location. * fix typo * update README * fix BREW mode (variable conflict) * more verbose (absl and s2 found) * fix linking error with absl shared lib
- Loading branch information
Showing
5 changed files
with
291 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,29 +5,138 @@ message(STATUS "Building using CMake version: ${CMAKE_VERSION}") | |
|
||
project(S2Geography) | ||
|
||
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED True) | ||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to build with") | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
set(CMAKE_CXX_EXTENSIONS OFF) | ||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
set(ABSL_ENABLE_INSTALL ON) | ||
|
||
option(S2GEOGRAPHY_BUILD_TESTS "Build tests" OFF) | ||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/third_party/cmake") | ||
|
||
option(S2GEOGRAPHY_BUILD_TESTS "Build tests" OFF) | ||
option(S2GEOGRAPHY_CODE_COVERAGE "Enable coverage reporting" OFF) | ||
add_library(coverage_config INTERFACE) | ||
|
||
option(S2GEOGRAPHY_BUILD_EXAMPLES "Build s2geography examples" OFF) | ||
option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) | ||
option(BUILD_SHARED_LIBS "Build using shared libraries" ON) | ||
|
||
# Dependencies | ||
# ------------ | ||
|
||
# openssl on Apple / Homebrew (dependency via s2geometry) | ||
# copied from Arrow | ||
# (copyright The Apache Software Foundation, Apache License, Version 2.0) | ||
|
||
if(APPLE AND NOT OPENSSL_ROOT_DIR) | ||
find_program(BREW_PROG brew) | ||
if(BREW_PROG) | ||
execute_process(COMMAND ${BREW_PROG} --prefix "[email protected]" | ||
OUTPUT_VARIABLE OPENSSL11_BREW_PREFIX | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
if(OPENSSL11_BREW_PREFIX) | ||
set(OPENSSL_ROOT_DIR ${OPENSSL11_BREW_PREFIX}) | ||
else() | ||
execute_process(COMMAND ${BREW_PROG} --prefix "openssl" | ||
OUTPUT_VARIABLE OPENSSL_BREW_PREFIX | ||
OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
if(OPENSSL_BREW_PREFIX) | ||
set(OPENSSL_ROOT_DIR ${OPENSSL_BREW_PREFIX}) | ||
endif() | ||
endif() | ||
endif() | ||
endif() | ||
|
||
# s2geometry | ||
|
||
if(DEFINED ENV{CONDA_PREFIX}) | ||
set(S2GEOGRAPHY_S2_SOURCE_DEFAULT "CONDA") | ||
else() | ||
set(S2GEOGRAPHY_S2_SOURCE_DEFAULT "AUTO") | ||
endif() | ||
|
||
set(S2GEOGRAPHY_S2_SOURCE | ||
"${S2GEOGRAPHY_S2_SOURCE_DEFAULT}" | ||
CACHE STRING "Method to use for acquiring the s2geometry dependency") | ||
|
||
message(STATUS "Using ${S2GEOGRAPHY_S2_SOURCE} approach to find s2geometry") | ||
|
||
macro(build_s2) | ||
message(STATUS "Building s2geometry from source (version 0.10.0)") | ||
|
||
FetchContent_Declare( | ||
s2 | ||
GIT_REPOSITORY https://github.com/google/s2geometry.git | ||
GIT_TAG tags/v0.10.0 | ||
GIT_SHALLOW TRUE) | ||
FetchContent_MakeAvailable(s2) | ||
|
||
set_property(TARGET s2 PROPERTY CXX_STANDARD ${CMAKE_CXX_STANDARD}) | ||
|
||
# this might be needed since s2geometry includes it in general | ||
# but not for any target explicilty? | ||
find_package(OpenSSL) | ||
target_include_directories(s2 INTERFACE ${OPENSSL_INCLUDE_DIR}) | ||
endmacro() | ||
|
||
if(${S2GEOGRAPHY_S2_SOURCE} STREQUAL "CONDA") | ||
set(S2_ROOT_DIR "$ENV{CONDA_PREFIX}") | ||
set(S2_SOURCE "SYSTEM") | ||
elseif(${S2GEOGRAPHY_S2_SOURCE} STREQUAL "BREW") | ||
# required for Homebrew installed s2geometry headers to find OpenSSL headers | ||
find_package(OpenSSL) | ||
include_directories(${OPENSSL_INCLUDE_DIR}) | ||
set(S2_SOURCE "SYSTEM") | ||
else() | ||
set(S2_SOURCE ${S2GEOGRAPHY_S2_SOURCE}) | ||
endif() | ||
|
||
if(${S2_SOURCE} STREQUAL "AUTO") | ||
find_package(s2 QUIET) | ||
if(${s2_FOUND}) | ||
message(STATUS "Found s2: ${s2_INCLUDE_DIRS}") | ||
else() | ||
build_s2() | ||
endif() | ||
elseif(${S2_SOURCE} STREQUAL "BUNDLED") | ||
build_s2() | ||
elseif(${S2_SOURCE} STREQUAL "SYSTEM") | ||
find_package(s2 REQUIRED) | ||
if(NOT ${s2_FOUND}) | ||
message(FATAL_ERROR "Couldn't find s2geometry") | ||
endif() | ||
endif() | ||
|
||
# Abseil (bundled build not supported) | ||
|
||
FetchContent_Declare( | ||
s2 | ||
GIT_REPOSITORY https://github.com/google/s2geometry.git | ||
GIT_TAG tags/v0.10.0 | ||
GIT_SHALLOW TRUE) | ||
FetchContent_MakeAvailable(s2) | ||
find_package(absl REQUIRED) | ||
if(${absl_FOUND}) | ||
get_target_property(ABSL_INCLUDE_DIRS absl::memory INTERFACE_INCLUDE_DIRECTORIES) | ||
message(STATUS "Found absl: ${ABSL_INCLUDE_DIRS}/absl") | ||
else() | ||
message(FATAL_ERROR "Couldn't find absl") | ||
endif() | ||
|
||
# GTest (always bundled) | ||
|
||
if(S2GEOGRAPHY_BUILD_TESTS) | ||
FetchContent_Declare( | ||
googletest | ||
GIT_REPOSITORY https://github.com/google/googletest | ||
GIT_TAG tags/release-1.12.0 | ||
GIT_SHALLOW TRUE | ||
) | ||
FetchContent_MakeAvailable(googletest) | ||
|
||
# do not install googletest by default when running cmake --install | ||
set_property(DIRECTORY ${googletest_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL YES) | ||
|
||
if(S2GEOGRAPHY_CODE_COVERAGE) | ||
add_library(coverage_config INTERFACE) | ||
endif() | ||
endif() | ||
|
||
# Build s2geography | ||
# ----------------- | ||
|
||
include_directories(src) | ||
|
||
include_directories(src ${OPENSSL_INCLUDE_DIR}) | ||
include_directories(src ${ABSL_INCLUDE_DIR}) | ||
add_library(s2geography | ||
src/s2geography/accessors-geog.cc | ||
src/s2geography/coverings.cc | ||
|
@@ -43,26 +152,9 @@ add_library(s2geography | |
set_target_properties(s2geography PROPERTIES | ||
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}) | ||
|
||
target_link_libraries(s2geography s2) | ||
|
||
if(BUILD_EXAMPLES) | ||
add_executable(example-simple examples/example-simple/example-simple.cc) | ||
target_link_libraries(example-simple PUBLIC s2geography s2) | ||
endif() | ||
|
||
install(TARGETS s2geography DESTINATION lib) | ||
install(DIRECTORY src/ DESTINATION include FILES_MATCHING PATTERN "*.h") | ||
|
||
if(S2GEOGRAPHY_BUILD_EXAMPLES) | ||
install(TARGETS example-simple DESTINATION examples) | ||
endif() | ||
target_link_libraries(s2geography s2 absl::memory absl::str_format) | ||
|
||
if(S2GEOGRAPHY_BUILD_TESTS) | ||
FetchContent_Declare( | ||
googletest | ||
URL https://github.com/google/googletest/archive/release-1.11.0.zip | ||
) | ||
FetchContent_MakeAvailable(googletest) | ||
enable_testing() | ||
|
||
add_executable(distance_test src/s2geography/distance_test.cc) | ||
|
@@ -73,9 +165,24 @@ if(S2GEOGRAPHY_BUILD_TESTS) | |
target_link_libraries(s2geography coverage_config) | ||
endif() | ||
|
||
target_link_libraries(distance_test s2geography gtest_main) | ||
target_link_libraries(distance_test s2geography GTest::gtest_main) | ||
|
||
include(GoogleTest) | ||
gtest_discover_tests(distance_test) | ||
endif() | ||
|
||
if(S2GEOGRAPHY_BUILD_EXAMPLES) | ||
add_executable(example-simple examples/example-simple/example-simple.cc) | ||
target_link_libraries(example-simple PUBLIC s2geography s2) | ||
endif() | ||
|
||
# Install s2geography | ||
# ------------------- | ||
|
||
install(TARGETS s2geography DESTINATION lib) | ||
install(DIRECTORY src/ DESTINATION include FILES_MATCHING PATTERN "*.h") | ||
|
||
if(S2GEOGRAPHY_BUILD_EXAMPLES) | ||
install(TARGETS example-simple DESTINATION examples) | ||
endif() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,46 +49,96 @@ Many operations in S2 require a `S2ShapeIndex` as input. This concept is similar | |
The s2geography library sits on top of the s2geometry library, and you can and should use s2 directly! | ||
## Installation | ||
## Build and Installation (from source) | ||
s2geography depends on s2geometry, which depends on [Abseil](https://github.com/abseil/abseil-cpp) and OpenSSL. You will need to install Abseil from source and install it to the same place you install s2geography (e.g., the homebrew/distributed versions are unlikely to work). Configure with `cmake <src dir> -Dabsl_DIR=.../cmake/absl`, where `.../cmake/absl` contains the `abslConfig.cmake` file. You may also need to specify the location of OpenSSL using `-DOPENSSL_ROOT_DIR=/path/to/[email protected]`. The s2 library is fetched and built using CMake's FetchContent module, so you don't need to clone it separately. | ||
There is no s2geography package available yet. If you want to use it, you need to build it from source. You can download the source by cloning this repository: | ||
The project is structured such that the VSCode `cmake` integration is triggered when the folder is open (if the default build doesn't work, consider adding `CMakeUserPresets.json` to configure things like the install directory, absl_DIR, or the location of OpenSSL). | ||
```bash | ||
git clone https://github.com/paleolimbot/s2geography.git | ||
``` | ||
|
||
### Requirements | ||
|
||
- [CMake](https://cmake.org/) | ||
- s2geometry | ||
- [Abseil](https://github.com/abseil/abseil-cpp) | ||
- OpenSSL (via s2geometry) | ||
|
||
For example, the GitHub Actions Ubuntu runner is configured like this: | ||
### Conda | ||
|
||
All the required dependencies above are available on conda-forge. You can install them using conda (or mamba): | ||
|
||
```bash | ||
# clone this repo | ||
git clone https://github.com/paleolimbot/s2geography.git | ||
conda install cmake libabseil s2geometry openssl -c conda-forge | ||
``` | ||
|
||
# build abseil-cpp in the build/ directory, install to dist/ | ||
mkdir s2geography/build && cd s2geography/build | ||
git clone https://github.com/abseil/abseil-cpp.git | ||
cmake abseil-cpp -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_CXX_STANDARD=11 -DABSL_ENABLE_INSTALL=ON | ||
cmake --build abseil-cpp | ||
cmake --install abseil-cpp --prefix ../dist | ||
### Homebrew (MacOS) | ||
|
||
# build s2geography (also fetches and builds s2) | ||
cmake .. -Dabsl_DIR=`pwd`/../dist/lib/cmake/absl -DS2GEOGRAPHY_BUILD_TESTS=ON | ||
Alternatively, you can install the required dependencies on MacOS with Homebrew: | ||
|
||
``` bash | ||
brew install cmake abseil s2geometry openssl | ||
``` | ||
|
||
### Build using CMake | ||
|
||
s2geography uses CMake to build the library. You first need to configure the build, e.g, using the following commands (from where the source has been downloaded or cloned): | ||
|
||
```bash | ||
mkdir build | ||
cd build | ||
cmake .. -DS2GEOGRAPHY_S2_SOURCE=AUTO -DCMAKE_CXX_STANDARD=17 | ||
cmake --build . | ||
cmake --install . --prefix ../dist | ||
``` | ||
|
||
Locally (M1 mac), I have to add `-DOPENSSL_ROOT_DIR=/opt/homebrew/opt/[email protected]` to `cmake ..` when building s2geography. | ||
The CMake option `S2GEOGRAPHY_S2_SOURCE` specifies the method to use for acquiring s2geometry: | ||
|
||
- `AUTO`: try to find s2geometry on the system default locations or download and build it from source if not found (default) | ||
- `BUNDLED`: download and build s2geometry automatically from source | ||
- `SYSTEM`: use s2geometry installed on one of the system default locations | ||
- `CONDA`: use s2geometry installed in a conda environment (automatically selected when the environment is active) | ||
- `BREW`: use s2geometry (and OpenSSL) installed with Homebrew | ||
|
||
Note: s2geography does not support automatically acquiring and building Abseil and OpenSSL from source. If you don't have installed those libraries with conda or Homebrew, you might need to manually specify their location using the CMake options`absl_DIR` and `OPENSSL_ROOT_DIR`. | ||
|
||
The CMake option `CMAKE_CXX_STANDARD` should be set according to the standard used to build Abseil and s2geometry (C++17 is set by default). | ||
|
||
The project is structured such that the VSCode CMake integration is triggered when the folder is open (if the default build doesn't work, consider adding `CMakeUserPresets.json` to configure things like the install directory, absl_DIR, or the location of OpenSSL). | ||
|
||
### Install | ||
|
||
After building the library, you can install it using: | ||
|
||
```bash | ||
cmake --install . --prefix ../dist | ||
``` | ||
|
||
## Development | ||
|
||
The easiest way to get started with s2geography development is using VSCode with the C/C++ and CMake extensions. See the CMakeUserPresets.json.example file for a possible test/configuration preset that will build and run the tests and the examples. You can also invoke `ctest` directly to run tests: | ||
s2geography provides units tests that can be built and run using [GTest](https://github.com/google/googletest). To enable it, use the CMake option `S2GEOGRAPHY_BUILD_TESTS=ON` (GTest will be downloaded and built automatically): | ||
|
||
```bash | ||
cd build | ||
cmake .. -DS2GEOGRAPHY_BUILD_TESTS=ON | ||
cmake --build . | ||
``` | ||
|
||
You can then run the tests using `ctest`: | ||
|
||
```bash | ||
ctest -T test --output-on-failure . | ||
``` | ||
|
||
You can run specific tests using `ctest`'s `-R` flag: | ||
You can also run specific tests using `ctest`'s `-R` flag: | ||
|
||
```bash | ||
ctest -T test . -R "Distance$" | ||
``` | ||
|
||
s2geography also provides some examples that can be build using: | ||
|
||
```bash | ||
cmake .. -DS2GEOGRAPHY_BUILD_EXAMPLES=ON | ||
cmake --build . | ||
``` | ||
|
||
For VSCode users (with the C/C++ and CMake extensions), the CMakeUserPresets.json.example file shows a possible test/configuration preset that will build and run the tests and the examples. |
Oops, something went wrong.