Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Building MobilityDuck

MobilityDuck is a DuckDB extension. One CMake project builds DuckDB itself
(~1300 source files), the bundled `spatial` and `icu` extensions, and
MobilityDuck (~36 source files). The MEOS, GEOS, PROJ, GDAL and GSL
dependencies are built by vcpkg and cached.

## One-time full build

```bash
make # release into build/release (use GEN=ninja for Ninja)
make debug # debug into build/debug
```

The first run compiles DuckDB and the vcpkg dependencies from source and is the
slow one. The result is `build/release/extension/mobilityduck/mobilityduck.duckdb_extension`
and a `build/release/duckdb` shell with the extension linked in.

## Fast iteration on MobilityDuck

After the one-time build, rebuild only the extension:

```bash
make ext # rebuild build/release extension only
make ext_debug # rebuild build/debug extension only
```

`make ext` recompiles only the changed MobilityDuck translation units and
relinks the `.duckdb_extension`. DuckDB, `spatial`, `icu`, `parquet` and the
vcpkg packages are not recompiled, because they are unchanged in the build tree.

Two settings cut the per-change cost further and apply automatically:

- A precompiled header (`src/include/mobilityduck_pch.hpp`) parses the heavy
DuckDB and MEOS headers once instead of in every translation unit.
- When `mold` is installed it is used to link the extension; the relink
dominates a single-file change and mold is much faster than the default
linker (`apt install mold`, or the equivalent for your platform). The build
falls back to the default linker when mold is absent.

Keep the build tree in sync with the checked-out branch: switching branches (or
building a different worktree) against a tree configured for another state makes
CMake detect changed headers and recompile broadly. A persistent, path-independent
`ccache` keeps those recompiles cheap (see below).

## ccache across branches and worktrees

`ccache` caches compiled objects. Making it path-independent lets a fresh
worktree or a branch switch reuse DuckDB's unchanged objects instead of
recompiling them:

```bash
export CCACHE_DIR="$HOME/.ccache"
export CCACHE_BASEDIR="$PWD"
ccache -M 30G
ccache -o hash_dir=false -o sloppiness=locale,time_macros
```

## vcpkg dependency cache

vcpkg stores built packages in `~/.cache/vcpkg/archives` and reuses them across
clean build trees. MEOS, GEOS, PROJ and GDAL are rebuilt only when their version
or the MEOS pin in `vcpkg_ports/meos/portfile.cmake` changes — ordinary
MobilityDuck edits reuse the cache.

## Installing without building

End users do not build the extension. They install the distributed binary:

```sql
INSTALL mobilityduck FROM '<extension-repository>';
LOAD mobilityduck;
```
19 changes: 19 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,25 @@ target_link_libraries(${LOADABLE_EXTENSION_NAME}
OpenSSL::Crypto
)

# -----------------------------
# Developer build speed
# -----------------------------
# Parse the heavy, stable DuckDB and MEOS headers once per build instead of in
# every translation unit.
target_precompile_headers(${EXTENSION_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src/include/mobilityduck_pch.hpp")
target_precompile_headers(${LOADABLE_EXTENSION_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src/include/mobilityduck_pch.hpp")

# Link the extension with mold when it is installed: relinking the extension
# dominates the cost of a single-file change, and mold relinks far faster than
# the default linker. Falls back to the default linker when mold is absent.
find_program(MOLD_LINKER mold)
if(MOLD_LINKER)
target_link_options(${EXTENSION_NAME} PRIVATE -fuse-ld=mold)
target_link_options(${LOADABLE_EXTENSION_NAME} PRIVATE -fuse-ld=mold)
endif()

# -----------------------------
# Install (static & loadable)
# -----------------------------
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ test_debug_internal:
./build/debug/$(TEST_PATH) "$(PROJ_DIR)test/*"
test_reldebug_internal:
$(call stage_icu,reldebug)
./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*"
./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*"

# Fast developer iteration: rebuild ONLY the MobilityDuck extension against the
# already-configured DuckDB build and vcpkg dependencies. Run a full `make`
# (release) / `make debug` once; thereafter `make ext` / `make ext_debug`
# recompiles just the changed MobilityDuck translation units and relinks
# build/<config>/extension/mobilityduck/mobilityduck.duckdb_extension without
# rebuilding DuckDB, spatial, icu, parquet or the vcpkg packages. See BUILDING.md.
.PHONY: ext ext_debug
ext:
cmake --build build/release --target mobilityduck_loadable_extension --parallel
ext_debug:
cmake --build build/debug --target mobilityduck_loadable_extension --parallel
17 changes: 17 additions & 0 deletions src/include/mobilityduck_pch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Precompiled header: the heavy, stable third-party headers shared by every
// MobilityDuck translation unit. Compiling these once per build instead of in
// each translation unit cuts incremental compile time. Only third-party
// headers belong here — adding a MobilityDuck header would rebuild the whole
// precompiled header whenever that header changes.
#pragma once

extern "C" {
#include <meos.h>
#include <meos_internal.h>
}

#include "duckdb/common/exception.hpp"
#include "duckdb/common/string_util.hpp"
#include "duckdb/function/scalar_function.hpp"
#include "duckdb/main/extension/extension_loader.hpp"
#include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
4 changes: 2 additions & 2 deletions vcpkg_ports/meos/portfile.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO estebanzimanyi/MobilityDB
REF a8178dc9d56d841d0eb5025a7e8717c8d25a1d0f
SHA512 030a144bb3247695702dd2de11f4c389ed28c6eb0186e6988a489e2b00e9801179ba8f27bcbcd81ae89e398a7277ed7f9ff7058dbf15f5db322ae4644365c560
REF 3db47f887c61f049a6a03db55c48bedf6d10eee4
SHA512 b73123bca036813c43937f90f0d0ce45af5cb9e39d6a597304199d21ae854212319a3a7b58ecd075eb5678d89d6d5990b9faf63dd29bd8c9a4e2ed83282b94c5
)

vcpkg_replace_string(
Expand Down
Loading