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
32 changes: 31 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,39 @@ include extension-ci-tools/makefiles/duckdb_extension.Makefile
# both MEOS (meos_initialize_timezone) and DuckDB (DBConfig::SetOptionByName
# "TimeZone") to Europe/Brussels. Tests pass on any OS timezone — the
# extension is the single source of truth, no TZ env var needed.
#
# LoadInternal also calls ExtensionHelper::AutoLoadExtension(db, "icu") so
# the timezone option is honoured. Autoload looks for the extension on disk
# at $HOME/.duckdb/extensions/<duckdb_version>/<platform>/icu.duckdb_extension
# and falls back to a hub download. That fails both inside the linux_amd64
# test docker container (empty path, no network egress) and on the macOS
# osx_arm64 test runner (hub icu not reliably resolvable). We copy the
# icu.duckdb_extension that was built locally as part of this extension's
# build (declared in extension_config.cmake) into the expected path,
# matched to the DuckDB platform string, before running the unittester.
DUCKDB_VERSION_TAG := v1.4.4

define stage_icu
@if [ -f ./build/$(1)/extension/icu/icu.duckdb_extension ]; then \
case "$$(uname -s)-$$(uname -m)" in \
Linux-x86_64) platform=linux_amd64 ;; \
Linux-aarch64) platform=linux_arm64 ;; \
Darwin-arm64) platform=osx_arm64 ;; \
Darwin-x86_64) platform=osx_amd64 ;; \
*) platform=$$(uname -m) ;; \
esac; \
target=$$HOME/.duckdb/extensions/$(DUCKDB_VERSION_TAG)/$$platform; \
mkdir -p "$$target" && cp -f ./build/$(1)/extension/icu/icu.duckdb_extension "$$target/" && \
echo "Staged icu.duckdb_extension at $$target/"; \
fi
endef

test_release_internal:
$(call stage_icu,release)
./build/release/$(TEST_PATH) "$(PROJ_DIR)test/*"
test_debug_internal:
$(call stage_icu,debug)
./build/debug/$(TEST_PATH) "$(PROJ_DIR)test/*"
test_reldebug_internal:
./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*"
$(call stage_icu,reldebug)
./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*"
26 changes: 21 additions & 5 deletions src/include/tydef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,27 @@ extern "C" {
#include <meos_internal.h>
}

// Forward-compat alias for the meosType → MeosType rename (MobilityDB
// pr785-sync-script). Vcpkg's MEOS exposes `MeosType`; existing
// MobilityDuck code still uses `meosType`. This alias bridges the two
// without touching every reference site.
using meosType = MeosType;
// MEOS naming history: `meosType` is the **pre-consolidation** spelling
// and `MeosType` is the **post-consolidation** target (the rename is
// part of the upstream consolidation sweep, not yet reached by the
// vcpkg pin). The current pin
// (`vcpkg_ports/meos/portfile.cmake` REF f11b7443ee98…) is still
// pre-consolidation and exposes `meosType` — see
// meos/include/temporal/meos_catalog.h, where line 121 declares
// `} meosType;`. MobilityDuck's source consistently uses
// `meosType` (verified via `grep -rn '\bmeosType\b' src/`), which
// matches the pin, so no alias is needed today.
//
// An earlier version of this file added `using meosType = MeosType;`
// as a forward-looking bridge for the eventual consolidation bump.
// That alias references `MeosType`, which the current pin does NOT
// yet expose, so it broke the build:
// "'MeosType' does not name a type; did you mean 'meosType'?".
//
// When the MEOS pin is bumped past the consolidation point, restore
// a bridge here (`using meosType = MeosType;` becomes valid then) or
// sweep the source `meosType → MeosType` in one PR — whichever the
// project prefers at that time.

namespace duckdb {

Expand Down
1 change: 1 addition & 0 deletions vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"vcpkg-cmake",
"openssl",
"zlib",
"libxml2",
"expat",
{
"name": "sqlite3",
Expand Down
152 changes: 152 additions & 0 deletions vcpkg_ports/meos/portfile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,127 @@ endif()
]=]
)

# pgPointCloud enabler. -DPOINTCLOUD=ON makes meos/src/pointcloud/
# CMakeLists.txt FATAL_ERROR unless pointcloud-pg/lib/libpc.a exists; it
# is built as a side effect of pgPointCloud's `./autogen.sh &&
# ./configure && make`, which cannot run in the manylinux extension-ci
# container (no autotools-usable PostgreSQL, no pg_config). The vendored
# pointcloud-pg/lib/ archive sources include only libxml2 and zlib (no
# PostgreSQL headers), and pointcloud-pg/lib/Makefile builds the libpc.a
# target directly via `ar rs` with only the XML2/ZLIB CPPFLAGS from
# config.mk — the CUnit dependency is confined to the `all:` cunit/
# recurse. So we generate config.mk and lib/pc_config.h the way
# pgPointCloud's autotools would (filling only the @VARS@ that
# config.mk.in declares and the lib OBJS sources consume, with vcpkg's
# libxml2/zlib paths), then build the libpc.a archive target directly.
set(POINTCLOUD_DIR "${SOURCE_PATH}/pointcloud-pg")

# config.mk: fill the @VARS@ declared by pointcloud-pg/config.mk.in.
# XML2_CPPFLAGS mirrors `xml2-config --cflags` (-I<prefix>/include/libxml2);
# ZLIB_CPPFLAGS is empty because zlib.h is on the default include path
# (-I<prefix>/include); the *_LDFLAGS mirror `xml2-config --libs` / -lz
# but only matter for linking, not for the `ar rs` static archive. LazPerf
# and CUnit are disabled exactly as configure leaves them when neither is
# present (no HAVE_LAZPERF / HAVE_CUNIT define).
file(WRITE "${POINTCLOUD_DIR}/config.mk"
"CC = cc
CFLAGS = -O2 -fPIC
CXXFLAGS += -fPIC -std=c++0x
SQLPP =

XML2_CPPFLAGS = -I${CURRENT_INSTALLED_DIR}/include/libxml2
XML2_LDFLAGS = -L${CURRENT_INSTALLED_DIR}/lib -lxml2

ZLIB_CPPFLAGS = -I${CURRENT_INSTALLED_DIR}/include
ZLIB_LDFLAGS = -L${CURRENT_INSTALLED_DIR}/lib -lz

CUNIT_CPPFLAGS =
CUNIT_LDFLAGS =

PG_CONFIG =
PGXS =

LIB_A = libpc.a
LIB_A_LAZPERF = liblazperf.a

LAZPERF_STATUS = disabled
LAZPERF_CPPFLAGS =

PGSQL_MAJOR_VERSION =
")

# lib/pc_config.h: pc_api.h does `#include \"pc_config.h\"`, normally
# emitted by config.status from lib/pc_config.h.in. Mirror the autotools
# no-lazperf / no-cunit output: substitute the always-AC_DEFINE'd
# version vars, and leave HAVE_LAZPERF / HAVE_CUNIT undefined (so the
# pc_patch_lazperf.c `#ifndef HAVE_LAZPERF` early-return guards stay
# active and no liblazperf symbols are referenced). POINTCLOUD_VERSION
# is pointcloud-pg/Version.config = 1.2.5.
file(WRITE "${POINTCLOUD_DIR}/lib/pc_config.h"
"/* #undef LIBXML2_VERSION */

/* #undef PGSQL_VERSION */

/* #undef HAVE_LAZPERF */

/* #undef HAVE_CUNIT */

#define PROJECT_SOURCE_DIR \"${POINTCLOUD_DIR}\"

#define POINTCLOUD_VERSION \"1.2.5\"
")

# Build the libpc.a archive target directly (NOT `all`, which recurses
# into cunit/ and needs CUnit). config.mk is included by lib/Makefile.
vcpkg_execute_required_process(
COMMAND make -C "${POINTCLOUD_DIR}/lib" libpc.a
WORKING_DIRECTORY "${POINTCLOUD_DIR}/lib"
LOGNAME "build-libpc-${TARGET_TRIPLET}"
)

# pgPointCloud's lib/stringbuffer.c is a verbatim fork of PostGIS
# liblwgeom/stringbuffer.c (identical stringbuffer_t layout, identical
# stringbuffer_* signatures). MEOS already bundles liblwgeom — including
# its stringbuffer.c — into libmeos.a, so carrying pgPointCloud's copy in
# libpc.a as well makes the final static link fail with `multiple
# definition of stringbuffer_*`. liblwgeom additionally exports only some
# of these symbols out-of-line (stringbuffer_append / _append_char /
# _append_double are header-only `static inline` there), so simply
# dropping pgPointCloud's stringbuffer.o leaves its callers with
# unresolved stringbuffer_append. Instead, rename every stringbuffer_*
# symbol in libpc.a — definitions and the cross-object references in
# pc_point.o / pc_schema.o / pc_dimstats.o / pc_patch_uncompressed.o — to
# a private pc_stringbuffer_* namespace. libpc.a then resolves these
# entirely against its own copy and never collides with liblwgeom.
vcpkg_execute_required_process(
COMMAND ${CMAKE_COMMAND} -E env bash -c
"set -e
cd '${POINTCLOUD_DIR}/lib'
: > redefine.map
for s in $(nm libpc.a 2>/dev/null | awk '$NF ~ /^stringbuffer_/ {print $NF}' | sort -u); do
echo \"$s pc_$s\" >> redefine.map
done
tmp=$(mktemp -d)
cd \"$tmp\"
ar x '${POINTCLOUD_DIR}/lib/libpc.a'
for o in *.o; do
objcopy --redefine-syms='${POINTCLOUD_DIR}/lib/redefine.map' \"$o\"
done
rm -f '${POINTCLOUD_DIR}/lib/libpc.a'
ar rcs '${POINTCLOUD_DIR}/lib/libpc.a' *.o
cd /
rm -rf \"$tmp\" '${POINTCLOUD_DIR}/lib/redefine.map'"
WORKING_DIRECTORY "${POINTCLOUD_DIR}/lib"
LOGNAME "namespace-libpc-stringbuffer-${TARGET_TRIPLET}"
)

# meos/src/pointcloud/CMakeLists.txt checks exactly this path.
if(NOT EXISTS "${POINTCLOUD_DIR}/lib/libpc.a")
message(FATAL_ERROR
"pgPointCloud enabler failed: ${POINTCLOUD_DIR}/lib/libpc.a "
"was not produced by the libpc.a make target.")
endif()

vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
Expand All @@ -54,6 +175,7 @@ vcpkg_cmake_configure(
-DNPOINT=ON
-DPOSE=ON
-DRGEO=ON
-DPOINTCLOUD=ON
-DBUILD_SHARED_LIBS=ON
-DCMAKE_C_FLAGS="-Dsession_timezone=meos_session_timezone"
-DCMAKE_CXX_FLAGS="-Dsession_timezone=meos_session_timezone"
Expand All @@ -63,6 +185,18 @@ vcpkg_cmake_configure(
vcpkg_cmake_build(TARGET all)
vcpkg_cmake_install()

# meos/src/pointcloud/CMakeLists.txt links libpc.a into the `pointcloud`
# OBJECT library with target_link_libraries(... PRIVATE libpc.a xml2 z).
# That is only a usage requirement: the static libmeos.a archive does
# not absorb libpc.a's objects nor carry a link interface, so a consumer
# linking the static libmeos.a sees unresolved pc_point_get_x/y/z/...
# Install libpc.a alongside libmeos.a and propagate it (plus libxml2 and
# zlib) through the MEOS::meos imported target's INTERFACE_LINK_LIBRARIES
# so the extension link resolves the pgPointCloud symbols — mirroring the
# canonical POINTCLOUD_LINK_LIBS = libpc.a xml2 z.
file(INSTALL "${SOURCE_PATH}/pointcloud-pg/lib/libpc.a"
DESTINATION "${CURRENT_PACKAGES_DIR}/lib")

file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/share/meos")
file(WRITE "${CURRENT_PACKAGES_DIR}/share/meos/MEOSConfig.cmake" [=[
# Minimal imported target for MEOS
Expand All @@ -87,6 +221,24 @@ if (NOT TARGET MEOS::meos)
IMPORTED_LOCATION "${_meos_lib}"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/../../include"
)
# When MEOS was built with -DPOINTCLOUD=ON, libmeos.a calls into the
# pgPointCloud archive libpc.a (and libxml2 / zlib). The static
# libmeos.a does not carry that link interface, so propagate it here.
set(_meos_libdir "${CMAKE_CURRENT_LIST_DIR}/../../lib")
if (EXISTS "${_meos_libdir}/libpc.a")
set(_meos_pc_iface "${_meos_libdir}/libpc.a")
file(GLOB _meos_xml2 "${_meos_libdir}/libxml2.a" "${_meos_libdir}/libxml2.lib")
file(GLOB _meos_zlib "${_meos_libdir}/libz.a" "${_meos_libdir}/libzlib.a" "${_meos_libdir}/zlib.lib")
if (_meos_xml2)
list(APPEND _meos_pc_iface ${_meos_xml2})
endif()
if (_meos_zlib)
list(APPEND _meos_pc_iface ${_meos_zlib})
endif()
set_target_properties(MEOS::meos PROPERTIES
INTERFACE_LINK_LIBRARIES "${_meos_pc_iface}"
)
endif()
endif()
]=])

Expand Down
6 changes: 4 additions & 2 deletions vcpkg_ports/meos/vcpkg.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "meos",
"version-string": "git",
"port-version": 1,
"port-version": 2,
"description": "MEOS - Mobility Engine Open Source C library (built from MobilityDB with -DMEOS=ON)",
"homepage": "https://libmeos.org/",
"dependencies": [
Expand All @@ -10,6 +10,8 @@
"geos",
"proj",
"json-c",
"gsl"
"gsl",
"libxml2",
"zlib"
]
}
Loading