From fa2de5747e76f32283fec9460b4f4277333c18c1 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Fri, 29 May 2026 22:09:16 +0200 Subject: [PATCH 1/2] Pin MEOS with the wasm pg_config SIZEOF_LONG_LONG fix Adds the SIZEOF_LONG_LONG emission to the rendered pg_config.h so the DuckDB-Wasm (wasm32-emscripten / ILP32) build of MEOS no longer fails the pg_bitutils integer-width check. --- vcpkg_ports/meos/portfile.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcpkg_ports/meos/portfile.cmake b/vcpkg_ports/meos/portfile.cmake index 82619e3a..9aeff5d5 100644 --- a/vcpkg_ports/meos/portfile.cmake +++ b/vcpkg_ports/meos/portfile.cmake @@ -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( From 700099b6b6e6c8711cf135d2feef43cd7a8ba642 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 28 May 2026 22:43:54 +0200 Subject: [PATCH 2/2] Speed up developer builds of the MobilityDuck extension Add make targets ext / ext_debug that rebuild only the MobilityDuck extension against the already-built DuckDB and vcpkg dependencies. Add a precompiled header (src/include/mobilityduck_pch.hpp) so the heavy DuckDB and MEOS headers are parsed once per build rather than in every translation unit, and link the extension with mold when it is installed for a far faster relink, falling back to the default linker otherwise. BUILDING.md documents the one-time full build, the fast iteration loop, path-independent ccache, the vcpkg dependency cache, and binary install for end users. --- BUILDING.md | 73 ++++++++++++++++++++++++++++++++ CMakeLists.txt | 19 +++++++++ Makefile | 14 +++++- src/include/mobilityduck_pch.hpp | 17 ++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 BUILDING.md create mode 100644 src/include/mobilityduck_pch.hpp diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 00000000..ef2747ec --- /dev/null +++ b/BUILDING.md @@ -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 ''; +LOAD mobilityduck; +``` diff --git a/CMakeLists.txt b/CMakeLists.txt index 47640ba4..3963be86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) # ----------------------------- diff --git a/Makefile b/Makefile index 6ee08484..9e7941b7 100644 --- a/Makefile +++ b/Makefile @@ -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/*" \ No newline at end of file + ./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//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 diff --git a/src/include/mobilityduck_pch.hpp b/src/include/mobilityduck_pch.hpp new file mode 100644 index 00000000..47aa02e4 --- /dev/null +++ b/src/include/mobilityduck_pch.hpp @@ -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 +#include +} + +#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"