GDAL with SAP HANA driver: build it

In the previous post “GDAL with SAP HANA driver: use it” I described examples of using some GDAL tools with SAP HANA. Here I am going to describe steps it took me to build GDAL with SAP HANA driver on my MacBook laptop with Apple M1 (ARM-based) chip.

The driver for SAP HANA is not included into read-to-use binaries of GDAL, so we have to build it from sources: https://gdal.org/download.html#development-source

  1. Open and use a terminal session in an x86 translated mode
  2. Get Homebrew for macOS Intel-based
  3. Use Homebrew to install prerequisites
  4. Build and install C++ Wrapper for ODBC, which is a build dependency for SAP HANA driver in GDAL
  5. Build and install GDAL

Use it!

Check that your session in running in Intel architecture mode (i386).

arch

ARM vs Intel arch on Apple silicon

As I mentioned I have MacBook with Apple M1. My first attempt to build and use GDAL for a native arm architecture did not work and caused the error

ERROR 1: HANA connection failed: ERROR: 0: 01000 : [unixODBC][Driver Manager]Can't open lib '/Applications/sap/hdbclient/libodbcHDB.dylib' : file not found

…because SAP HANA Client is available for Intel arch on macOS at the time of writing this post.

In case you are using a MacBook with an Apple silicon too, then I have posted an article already Running hdbcli on an Apple M1 chip: an alternative way with using arch command that describes how to start x86 translated mode in the terminal.

I assume you are already using Homebrew, if you are using macOS.

What I found helpful is that by default Homebrew is installed to different preferred prefix depending on the architecture: /usr/local for macOS Intel, /opt/homebrew for Apple Silicon.

In case of a laptop with Apple silicon I can have two different installations of Homebrew: in the native and in the Intel translated mode. Although for the latter it used /usr/local/homebrew.

Check your configuration with:

arch
sysctl -n machdep.cpu.brand_string
brew --prefix

At the time of writing this post, requirements listed at https://gdal.org/build_hints.html#build-hints were:

Let’s have a look:

  1. Compilers should be already, if you have Homebrew and its prerequisite installed.
  2. I found SQLite3 was not an optional (recommended) prerequisite, but was required during the build process (or maybe it was just an unresolved GDAL build issue on macOS at the time of writing this post)
  3. I could install and use cmake, proj, and sqlite using Homebrew.

So, to satisfy prerequisites run brew install like

brew install cmake
brew install proj
brew install sqlite

Important note about sqlite installation with Homebrew

If you carefully check logs of installation, then you should notice the following caveat:

==> Caveats
==> sqlite
sqlite is keg-only, which means it was not symlinked into /usr/local/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
... For compilers to find sqlite you may need to set: export LDFLAGS="-L/usr/local/homebrew/opt/sqlite/lib" export CPPFLAGS="-I/usr/local/homebrew/opt/sqlite/include"
...

As stated on the SAP HANA driver page for GDAL: odbc-cpp-wrapper is a build dependency for it.

C++ Wrapper for ODBC is an open-source project from SAP and is available on https://github.com/SAP/odbc-cpp-wrapper.

Prerequisites

Let’s have a look at its requirements:

We should have the first set of the requirements — a C++ compiler, the Git CLI and CMake — already satisfied.

Install unixODBC from Homebrew, if you haven’t done so yet:

brew install unixodbc

I did not plan generating the API documentation, so for the purpose of this post I skipped installing Oxygen.

Build and install

I followed the steps described in https://github.com/SAP/odbc-cpp-wrapper#building-and-installation with one additional step not listed there. Below are my notes.

git clone https://github.com/SAP/odbc-cpp-wrapper.git
mkdir odbc-cpp-wrapper/build && cd odbc-cpp-wrapper/build

But before running the cmake step to avoid a build error…

~/ProjectsLocal/odbc-cpp-wrapper/src/odbc/internal/Odbc.h:9:10: fatal error: 'sql.h' file not found

…I had to create CMake’s environment variables LDFLAGS and CXXFLAGS to point them to unixODBC includes and libraires:

export CXXFLAGS="-I$(brew --prefix)/include"
export LDFLAGS="-L$(brew --prefix)/lib" echo ${CXXFLAGS}
echo ${LDFLAGS} ls -l $(brew --prefix)/include | grep unixodbc
ls -l $(brew --prefix)/lib | grep unixodbc

As you can see required includes and libraries are already linked in Homebrew’s directory, so we do not need to pint to their specific destinations of unixODBC folders.

cmake ..
grep -e -I -e -L CMakeCache.txt

I have used cmake for the rest of the steps instead of the make as listed in the documentation.

cmake --build .
sudo cmake --install .
unset CXXFLAGS
unset LDFLAGS

Summary

Installed files can be found in the file install_manifest.txt, which included libraries

/usr/local/homebrew/lib/libodbccpp_static.a
/usr/local/homebrew/lib/libodbccpp.dylib

and includes in /usr/local/homebrew/include/odbc/.

In your installation the target folder might be different than /usr/local/homebrew/ depending on the configuration.

Now that all prerequisites are satisfied let’s clone the GDAL repository and create a build directory…

git clone https://github.com/OSGeo/gdal.git
mkdir gdal/build && cd gdal/build

…after which you should be able to build GDAL following https://gdal.org/build_hints.html#cmake.

Here are my notes.

Let’s check the latest tag in the repository.

git describe --tags `git rev-list --tags --max-count=1`

Set the required build configuration.

cmake .. \ -DSQLITE3_INCLUDE_DIR=$(brew --prefix sqlite)/include \ -DSQLITE3_LIBRARY=$(brew --prefix sqlite)/lib/libsqlite3.dylib \ -DCMAKE_INSTALL_RPATH=@loader_path/../lib \ -DOGR_ENABLE_DRIVER_HANA:BOOL=ON \ -DCMAKE_BUILD_TYPE=Release

Please note following in the output of the command execution:

...
-- Found ODBC: /usr/local/homebrew/lib/libodbc.dylib found components: ODBCINST
-- Found ODBCCPP: /usr/local/homebrew/lib/libodbccpp.dylib
...
-- Enabled drivers and features and found dependency packages
-- The following features have been enabled:
... * ogr_HANA, SAP HANA
...
-- The following OPTIONAL packages have been found: * ODBC Enable DB support through ODBC * ODBCCPP odbc-cpp library (external)
...

Let’s review options passed to the cmake command:

  1. A parameter OGR_ENABLE_DRIVER_HANA is optional, but shows you how to include (with ON) or exclude the driver from the build. HANA driver is included into the build if its build dependency (C++ Wrapper for ODBC) is satisfied.
  2. SQLITE3_INCLUDE_DIR and SQLITE3_LIBRARY are pointing directly to locations of SQLite includes directory and the dynamic library file. You might remember the note above from Homebrew installation of SQLite.
    Please note my use of $(brew --prefix sqlite) to avoid hardcoding the location that depends on the Homebrew installation.
  3. CMAKE_INSTALL_RPATH=@loader_path/../lib was included to avoid an error dyld[86048]: Library not loaded: @rpath/libgdal.31.dylib I was running into using installed binaries ogrinfo or ogr2ogr.
  4. CMAKE_BUILD_TYPE to avoid a self-explanatory warning Using -DCMAKE_BUILD_TYPE=Release is suggested. received when this flag was not set.
cmake --build .
sudo cmake --install .

Let’s check:

which ogrinfo
ogrinfo --formats


I hope you find my notes helpful, but I will be happy to see your comments and recommendations as my steps and approach might still not be further improved!

Regards,
-Vitaliy, aka @Sygyzmundovych