Files

1060 lines
41 KiB
Makefile

.PHONY: all opt unit clean debug release test unittest allunit benchmark docs doxygen format sqlite smoke runnertests sync_out_of_tree_extensions
all: release
opt: release
unit: unittest
EXTENSION_CONFIG_STEP ?=
GENERATOR ?=
FORCE_COLOR ?=
WARNINGS_AS_ERRORS ?=
FORCE_WARN_UNUSED_FLAG ?=
DISABLE_UNITY_FLAG ?=
DISABLE_SANITIZER_FLAG ?=
FORCE_32_BIT_FLAG ?=
CONFIGS_DIR = ./test/configs
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
PROJ_DIR := $(dir $(MKFILE_PATH))
PYTHON ?= python3
PREPARE_VENV ?= .cache/prepare-venv
FORMAT_VENV ?= $(PREPARE_VENV)
FORMAT_PYTHON := $(FORMAT_VENV)/bin/python
FORMAT_SETUP_DEPS := format_venv
CAPIGEN_VENV ?= $(PREPARE_VENV)
CAPIGEN_PYTHON := $(CAPIGEN_VENV)/bin/python
CAPIGEN_SETUP_DEPS := capigen_venv
EXE_SUFFIX :=
ifeq ($(OS),Windows_NT)
EXE_SUFFIX := .exe
endif
UNITTEST_BINARY ?= test/unittest$(EXE_SUFFIX)
SMOKE_UNITTEST ?= build/relassert/$(UNITTEST_BINARY)
SMOKE_RUNNER ?= build/relassert/test/run
UNITTEST_SLOW_FLAGS ?= --track-runtime=100
UNITTEST_HUGE_FLAGS ?= --workers=50% $(UNITTEST_SLOW_FLAGS)
# Allow setting extra unit test parameters using `make smoke T=...`.
T ?=
CI_CPU_COUNT := $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || printf '%s\n' "$${NUMBER_OF_PROCESSORS:-1}")
CI_BUILD_JOBS := $(shell jobs=$$(( $(CI_CPU_COUNT) * 80 / 100 )); [ $$jobs -lt 1 ] && jobs=1; echo $$jobs)
ifndef CMAKE_BUILD_PARALLEL_LEVEL
CMAKE_BUILD_PARALLEL_LEVEL := $(CI_BUILD_JOBS)
endif
export CMAKE_BUILD_PARALLEL_LEVEL
export CI_TIDY_JOBS := $(shell jobs=$$(( $(CI_CPU_COUNT) * 50 / 100 )); [ $$jobs -lt 1 ] && jobs=1; echo $$jobs)
# Assume Ninja is the default generator (if missing), but verify ninja exists.
# Cache Ninja detection so we only probe `ninja --version` once.
ifeq ($(GEN),)
NINJA_VERSION_FILE := build/ninja_version.txt
ifeq ($(wildcard $(NINJA_VERSION_FILE)),)
NINJA_DETECTED := $(strip $(shell mkdir -p build >/dev/null 2>&1; \
v=$$(ninja --version 2>/dev/null | head -n 1); \
if [ -n "$$v" ]; then \
printf '%s\n' "$$v" > "$(NINJA_VERSION_FILE)"; \
echo 1; \
fi))
ifneq ($(NINJA_DETECTED),)
GEN := ninja
endif
else
GEN := ninja
endif
endif
ifeq ($(GEN),ninja)
GENERATOR=-G "Ninja"
FORCE_COLOR=-DFORCE_COLORED_OUTPUT=1
endif
DUCKDB_NINJA_FILTER ?= $(if $(CI),1,0)
NINJA_BUILD_WRAPPER :=
ifeq ($(GEN),ninja)
ifneq ($(DUCKDB_NINJA_FILTER),0)
NINJA_BUILD_WRAPPER=$(PYTHON) ${PROJ_DIR}scripts/ci/filter_ninja_output.py --
endif
endif
ifeq (${TREAT_WARNINGS_AS_ERRORS}, 1)
WARNINGS_AS_ERRORS=-DTREAT_WARNINGS_AS_ERRORS=1
endif
ifeq (${FORCE_32_BIT}, 1)
FORCE_32_BIT_FLAG=-DFORCE_32_BIT=1
endif
ifeq (${FORCE_WARN_UNUSED}, 1)
FORCE_WARN_UNUSED_FLAG=-DFORCE_WARN_UNUSED=1
endif
ifeq (${DISABLE_UNITY}, 1)
DISABLE_UNITY_FLAG=-DDISABLE_UNITY=1
endif
ifeq (${DISABLE_SANITIZER}, 1)
DISABLE_SANITIZER_FLAG=-DENABLE_SANITIZER=FALSE -DENABLE_UBSAN=0
endif
ifeq (${DISABLE_UBSAN}, 1)
DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DENABLE_UBSAN=0
endif
ifeq (${DISABLE_VPTR_SANITIZER}, 1)
DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DDISABLE_VPTR_SANITIZER=1
endif
ifeq (${RELEASE_SANITIZER}, 1)
DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DRELEASE_SANITIZER=1
endif
ifeq (${THREADSAN}, 1)
DISABLE_SANITIZER_FLAG:=${DISABLE_SANITIZER_FLAG} -DENABLE_THREAD_SANITIZER=1
endif
ifeq (${STATIC_LIBCPP}, 1)
STATIC_LIBCPP=-DSTATIC_LIBCPP=TRUE
endif
GIT_BASE_BRANCH:=main
ifneq (${DUCKDB_GIT_BASE_BRANCH}, )
GIT_BASE_BRANCH:=${DUCKDB_GIT_BASE_BRANCH}
endif
COMMON_CMAKE_VARS ?=
CMAKE_VARS_BUILD ?=
CMAKE_LLVM_VARS ?=
SKIP_EXTENSIONS ?=
BUILD_EXTENSIONS ?=
CORE_EXTENSIONS ?=
UNSAFE_NUMERIC_CAST ?=
ifdef DUCKDB_VERSION
COMMON_CMAKE_VARS:=${COMMON_CMAKE_VARS} -DDUCKDB_EXPLICIT_VERSION="${DUCKDB_VERSION}"
else ifdef OVERRIDE_GIT_DESCRIBE
COMMON_CMAKE_VARS:=${COMMON_CMAKE_VARS} -DDUCKDB_EXPLICIT_VERSION="${OVERRIDE_GIT_DESCRIBE}"
else ifdef DUCKDB_EXPLICIT_VERSION
COMMON_CMAKE_VARS:=${COMMON_CMAKE_VARS} -DDUCKDB_EXPLICIT_VERSION="${DUCKDB_EXPLICIT_VERSION}"
else
COMMON_CMAKE_VARS:=${COMMON_CMAKE_VARS} -DDUCKDB_EXPLICIT_VERSION=""
endif
ifdef DUCKDB_COMMIT
COMMON_CMAKE_VARS:=${COMMON_CMAKE_VARS} -DGIT_COMMIT_HASH="${DUCKDB_COMMIT}"
endif
ifneq (${CXX_STANDARD}, )
CMAKE_VARS:=${CMAKE_VARS} -DCMAKE_CXX_STANDARD="${CXX_STANDARD}"
endif
ifneq (${DUCKDB_EXTENSIONS}, )
BUILD_EXTENSIONS:=${DUCKDB_EXTENSIONS}
endif
ifneq (${CORE_EXTENSIONS}, )
CORE_EXTENSIONS:=${CORE_EXTENSIONS}
endif
ifeq (${DISABLE_PARQUET}, 1)
SKIP_EXTENSIONS:=${SKIP_EXTENSIONS};parquet
endif
ifeq (${DISABLE_MAIN_DUCKDB_LIBRARY}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_MAIN_DUCKDB_LIBRARY=0
endif
ifneq (${EXTENSION_STATIC_BUILD}, )
CMAKE_VARS:=${CMAKE_VARS} -DEXTENSION_STATIC_BUILD=${EXTENSION_STATIC_BUILD}
endif
ifeq (${DISABLE_BUILTIN_EXTENSIONS}, 1)
$(warning DISABLE_BUILTIN_EXTENSIONS is deprecated, use STATICALLY_LINK_EXTENSIONS=core_functions)
STATICALLY_LINK_EXTENSIONS ?= core_functions
endif
ifeq (${GENERATE_EXTENSION_ENTRIES}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DGENERATE_EXTENSION_ENTRIES=1
endif
ifneq (${UNSAFE_NUMERIC_CAST}, )
CMAKE_VARS:=${CMAKE_VARS} -DUNSAFE_NUMERIC_CAST=1
endif
ifeq (${BUILD_EXTENSIONS_ONLY}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_EXTENSIONS_ONLY=1
endif
ifeq (${BUILD_BENCHMARK}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_BENCHMARKS=1
endif
ifeq (${BUILD_AUTOCOMPLETE}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};autocomplete
endif
ifeq (${BUILD_ICU}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};icu
endif
ifeq (${BUILD_TPCH}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};tpch
endif
ifeq (${BUILD_TPCDS}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};tpcds
endif
ifeq (${BUILD_FTS}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};fts
endif
ifeq (${BUILD_HTTPFS}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};httpfs
endif
ifeq (${BUILD_JSON}, 1)
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};json
endif
ifdef BUILD_JEMALLOC
CMAKE_VARS:=${CMAKE_VARS} -DENABLE_JEMALLOC=${BUILD_JEMALLOC}
endif
ifdef CORE_EXTENSIONS
BUILD_EXTENSIONS:=${BUILD_EXTENSIONS};${CORE_EXTENSIONS}
endif
ifeq (${BUILD_ALL_EXT}, 1)
EXTENSION_CONFIGS:=.github/config/in_tree_extensions.cmake;.github/config/out_of_tree_extensions.cmake;.github/config/rust_based_extensions.cmake
else ifeq (${BUILD_ALL_IT_EXT}, 1)
EXTENSION_CONFIGS:=.github/config/in_tree_extensions.cmake
else ifeq (${BUILD_ALL_OOT_EXT}, 1)
EXTENSION_CONFIGS:=.github/config/out_of_tree_extensions.cmake
endif
# Extension-selecting Make builds use the synchronized extension source tree by default.
# DUCKDB_NEW_EXTENSION_BUILD=0 remains available as a temporary legacy escape hatch.
ifneq ($(strip $(BUILD_EXTENSIONS)$(EXTENSION_CONFIGS)),)
ifeq ($(origin DUCKDB_NEW_EXTENSION_BUILD), undefined)
DUCKDB_NEW_EXTENSION_BUILD:=1
endif
endif
ifneq ($(filter-out 0,$(strip $(DUCKDB_NEW_EXTENSION_BUILD))),)
DUCKDB_NEW_EXTENSION_BUILD_ENABLED:=1
export DUCKDB_NEW_EXTENSION_BUILD
endif
ifndef DUCKDB_NEW_EXTENSION_BUILD_ENABLED
ifdef USE_MERGED_VCPKG_MANIFEST
EXTENSION_CONFIG_STEP = build/extension_configuration/vcpkg.json
endif
endif
ifeq (${STATIC_OPENSSL}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DOPENSSL_USE_STATIC_LIBS=1
endif
ifeq (${BUILD_TPCE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_TPCE=1
endif
ifeq (${CONFIGURE_R}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DCONFIGURE_R=1
endif
ifneq ($(TIDY_BINARY),)
TIDY_BINARY_PARAMETER := -clang-tidy-binary ${TIDY_BINARY}
endif
TIDY_SHARD_COUNT ?= 1
TIDY_SHARD_INDEX ?= 0
TIDY_SHARD_PARAMETERS := --shard-count ${TIDY_SHARD_COUNT} --shard-index ${TIDY_SHARD_INDEX}
CLANGD_TIDY_VERSION := 1.1.1
CLANGD_TIDY_VENV ?= $(abspath build/clangd-tidy-venv)
ifeq ($(CLANGD_TIDY_BINARY),)
ifneq ($(wildcard $(CLANGD_TIDY_VENV)/bin/clangd-tidy),)
CLANGD_TIDY_BINARY := $(CLANGD_TIDY_VENV)/bin/clangd-tidy
endif
endif
ifeq ($(CLANGD_BINARY),)
ifneq ("${CMAKE_LLVM_PATH}", "")
CLANGD_BINARY := ${CMAKE_LLVM_PATH}/bin/clangd
endif
endif
ifneq ($(CLANGD_TIDY_BINARY),)
CLANGD_TIDY_BINARY_PARAMETER := --clangd-tidy-binary ${CLANGD_TIDY_BINARY}
endif
ifneq ($(CLANGD_BINARY),)
CLANGD_BINARY_PARAMETER := --clangd-binary ${CLANGD_BINARY}
endif
ifneq ($(CLANGD_TIDY_QUERY_DRIVER),)
CLANGD_TIDY_QUERY_DRIVER_PARAMETER := --query-driver ${CLANGD_TIDY_QUERY_DRIVER}
endif
ifneq ($(TIDY_CHECKS),)
TIDY_PERFORM_CHECKS := '-checks=${TIDY_CHECKS}'
endif
ifneq ("${FORCE_QUERY_LOG}a", "a")
CMAKE_VARS:=${CMAKE_VARS} -DFORCE_QUERY_LOG=${FORCE_QUERY_LOG}
endif
ifneq ($(BUILD_EXTENSIONS),)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_EXTENSIONS="$(BUILD_EXTENSIONS)"
endif
ifneq ($(EXTENSION_CONFIG_BASE_DIR),)
CMAKE_VARS:=${CMAKE_VARS} -DEXTENSION_CONFIG_BASE_DIR="$(EXTENSION_CONFIG_BASE_DIR)"
endif
ifeq ($(SHADOW_FORBIDDEN_FUNCTIONS),1)
CMAKE_VARS:=${CMAKE_VARS} -DSHADOW_FORBIDDEN_FUNCTIONS=1
endif
ifneq ($(SKIP_EXTENSIONS),)
CMAKE_VARS:=${CMAKE_VARS} -DSKIP_EXTENSIONS="$(SKIP_EXTENSIONS)"
endif
# LINK_CORE_EXTENSIONS=1 also links the extensions named in BUILD_EXTENSIONS / CORE_EXTENSIONS, which otherwise are only
# built; always passed, so leaving it out turns it off again
CMAKE_VARS:=${CMAKE_VARS} -DLINK_CORE_EXTENSIONS=$(if $(filter 1 ON on TRUE true,$(LINK_CORE_EXTENSIONS)),ON,OFF)
# what the DuckDB targets link (space or semicolon separated, or none); always passed, so leaving them out restores the
# defaults
CMAKE_VARS:=${CMAKE_VARS} -DSTATICALLY_LINK_EXTENSIONS="$(STATICALLY_LINK_EXTENSIONS)"
CMAKE_VARS:=${CMAKE_VARS} -DDUCKDB_CAPABILITIES="$(DUCKDB_CAPABILITIES)"
ifneq ($(EXTENSION_CONFIGS),)
CMAKE_VARS:=${CMAKE_VARS} -DDUCKDB_EXTENSION_CONFIGS="$(EXTENSION_CONFIGS)"
endif
ifeq ($(EXTENSION_TESTS_ONLY), 1)
CMAKE_VARS:=${CMAKE_VARS} -DEXTENSION_TESTS_ONLY=1
endif
ifneq ($(EXTRA_CMAKE_VARIABLES),)
CMAKE_VARS:=${CMAKE_VARS} ${EXTRA_CMAKE_VARIABLES}
endif
ifeq (${CRASH_ON_ASSERT}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DCRASH_ON_ASSERT=1
endif
ifeq (${FORCE_ASSERT}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DFORCE_ASSERT=1
endif
ifeq (${FORCE_DEBUG}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DFORCE_DEBUG=1
endif
ifneq (${SMALLER_BINARY},)
CMAKE_VARS:=${CMAKE_VARS} -DSMALLER_BINARY='${SMALLER_BINARY}'
endif
ifneq (${SMALLER_BINARY_EXCEPT},)
CMAKE_VARS:=${CMAKE_VARS} -DSMALLER_BINARY_EXCEPT='${SMALLER_BINARY_EXCEPT}'
endif
ifeq (${DISABLE_STRING_INLINE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDISABLE_STR_INLINE=1
endif
ifeq (${DISABLE_MEMORY_SAFETY}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDISABLE_MEMORY_SAFETY=1
endif
ifeq (${DISABLE_RTTI}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDISABLE_RTTI=1
endif
ifeq (${DISABLE_ASSERTIONS}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDISABLE_ASSERTIONS=1
endif
ifeq (${DESTROY_UNPINNED_BLOCKS}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDESTROY_UNPINNED_BLOCKS=1
endif
ifeq (${FORCE_ASYNC_SINK_SOURCE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DFORCE_ASYNC_SINK_SOURCE=1
endif
ifeq (${RUN_SLOW_VERIFIERS}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DRUN_SLOW_VERIFIERS=1
endif
ifeq (${ALTERNATIVE_VERIFY}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DALTERNATIVE_VERIFY=1
endif
ifeq (${DISABLE_POINTER_SALT}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDISABLE_POINTER_SALT=1
endif
ifeq (${HASH_ZERO}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DHASH_ZERO=1
endif
ifeq (${LATEST_STORAGE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DLATEST_STORAGE=1
endif
ifeq (${BLOCK_VERIFICATION}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBLOCK_VERIFICATION=1
endif
ifneq (${DISABLE_CPP_UNITTESTS}, )
CMAKE_VARS:=${CMAKE_VARS} -DENABLE_UNITTEST_CPP_TESTS=0
endif
ifeq (${DEBUG_MOVE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDEBUG_MOVE=1
endif
ifeq (${DEBUG_ALLOCATION}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDEBUG_ALLOCATION=1
endif
ifeq (${DEBUG_STACKTRACE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DDEBUG_STACKTRACE=1
endif
ifeq (${DISABLE_CORE_FUNCTIONS}, 1)
SKIP_EXTENSIONS:=${SKIP_EXTENSIONS};core_functions
endif
ifeq (${DISABLE_EXTENSION_LOAD}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DENABLE_EXTENSION_LOAD=0
endif
ifeq (${DISABLE_BUILTIN_HTTPLIB}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DENABLE_BUILTIN_HTTPLIB=0
endif
ifeq (${DISABLE_SHELL}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DBUILD_SHELL=0
endif
CMAKE_VARS:=${CMAKE_VARS} -DLOCAL_EXTENSION_REPO="${LOCAL_EXTENSION_REPO}"
ifneq (${OSX_BUILD_ARCH}, )
CMAKE_VARS:=${CMAKE_VARS} -DOSX_BUILD_ARCH=${OSX_BUILD_ARCH}
endif
ifeq (${OSX_BUILD_UNIVERSAL}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DOSX_BUILD_UNIVERSAL=1
endif
ifneq ("${DUCKDB_LINKER}", "")
CMAKE_VARS:=${CMAKE_VARS} -DDUCKDB_LINKER=${DUCKDB_LINKER}
endif
ifdef SKIP_PLATFORM_UTIL
CMAKE_VARS:=${CMAKE_VARS} -DSKIP_PLATFORM_UTIL=1
endif
ifdef DEBUG_STACKTRACE
CMAKE_VARS:=${CMAKE_VARS} -DDEBUG_STACKTRACE=1
endif
ifeq (${NATIVE_ARCH}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DNATIVE_ARCH=1
endif
ifneq (${DUCKDB_OPTIMIZATION_PROFILE}, )
CMAKE_VARS:=${CMAKE_VARS} -DDUCKDB_OPTIMIZATION_PROFILE=${DUCKDB_OPTIMIZATION_PROFILE}
endif
ifeq (${OVERRIDE_NEW_DELETE}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DOVERRIDE_NEW_DELETE=1
endif
ifeq (${STANDALONE_DEBUG}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DSTANDALONE_DEBUG=1
endif
ifneq (${DUCKDB_PREBUILT_LIBRARY}, )
CMAKE_VARS:=${CMAKE_VARS} -DPREBUILT_BINARY=${DUCKDB_PREBUILT_LIBRARY}
endif
ifdef REDUCE_SYMBOLS
CMAKE_VARS:=${CMAKE_VARS} -DREDUCE_SYMBOLS=1
endif
# Optional overrides
ifneq (${STANDARD_VECTOR_SIZE}, )
CMAKE_VARS:=${CMAKE_VARS} -DSTANDARD_VECTOR_SIZE=${STANDARD_VECTOR_SIZE}
endif
# Enable VCPKG for this build
ifneq ("${VCPKG_TOOLCHAIN_PATH}", "")
CMAKE_VARS_BUILD:=${CMAKE_VARS_BUILD} -DCMAKE_TOOLCHAIN_FILE='${VCPKG_TOOLCHAIN_PATH}' -DVCPKG_BUILD=1
endif
ifneq ("${VCPKG_TARGET_TRIPLET}", "")
CMAKE_VARS_BUILD:=${CMAKE_VARS_BUILD} -DVCPKG_TARGET_TRIPLET='${VCPKG_TARGET_TRIPLET}'
endif
ifndef DUCKDB_NEW_EXTENSION_BUILD_ENABLED
ifeq (${USE_MERGED_VCPKG_MANIFEST}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DVCPKG_MANIFEST_DIR='${PROJ_DIR}build/extension_configuration'
endif
endif
sync_extensions_into =
vcpkg_cmake_flag =
ifdef DUCKDB_NEW_EXTENSION_BUILD_ENABLED
sync_extensions_into = $(PYTHON) scripts/sync_out_of_tree_extensions.py $(if $(BUILD_EXTENSIONS),--build-extensions "$(BUILD_EXTENSIONS)") $(if $(EXTENSION_CONFIGS),--extension-configs "$(EXTENSION_CONFIGS)") $(if $(EXTENSION_CONFIG_BASE_DIR),--extension-config-base-dir "$(EXTENSION_CONFIG_BASE_DIR)") --output-dir '$(1)' &&
ifneq ("${VCPKG_TOOLCHAIN_PATH}", "")
vcpkg_cmake_flag = -DVCPKG_MANIFEST_DIR='$(1)'
endif
endif
ifneq ("${LTO}", "")
CMAKE_VARS:=${CMAKE_VARS} -DCMAKE_LTO='${LTO}'
endif
ifneq ("${LTO_JOBS}", "")
CMAKE_VARS:=${CMAKE_VARS} -DCMAKE_LTO_JOBS='${LTO_JOBS}'
endif
ifeq (${EXPORT_DYNAMIC_SYMBOLS}, 1)
CMAKE_VARS:=${CMAKE_VARS} -DEXPORT_DYNAMIC_SYMBOLS=1
endif
ifneq ("${CMAKE_LLVM_PATH}", "")
CMAKE_VARS:=${CMAKE_VARS} -DCMAKE_RANLIB='${CMAKE_LLVM_PATH}/bin/llvm-ranlib' -DCMAKE_AR='${CMAKE_LLVM_PATH}/bin/llvm-ar' -DCMAKE_CXX_COMPILER='${CMAKE_LLVM_PATH}/bin/clang++' -DCMAKE_C_COMPILER='${CMAKE_LLVM_PATH}/bin/clang' -DCMAKE_EXE_LINKER_FLAGS_INIT='-L${CMAKE_LLVM_PATH}/lib -L${CMAKE_LLVM_PATH}/lib/c++' -DCMAKE_SHARED_LINKER_FLAGS_INIT='-L${CMAKE_LLVM_PATH}/lib -L${CMAKE_LLVM_PATH}/lib/c++' -DCMAKE_MODULE_LINKER_FLAGS_INIT='-L${CMAKE_LLVM_PATH}/lib -L${CMAKE_LLVM_PATH}/lib/c++'
endif
CMAKE_VARS:=${CMAKE_VARS} ${COMMON_CMAKE_VARS}
ifdef DUCKDB_PLATFORM
ifneq ("${DUCKDB_PLATFORM}", "")
CMAKE_VARS:=${CMAKE_VARS} -DDUCKDB_EXPLICIT_PLATFORM='${DUCKDB_PLATFORM}'
endif
endif
clean:
rm -rf build
EXTENSION_REPOSITORY_PATH ?= build/release/repository
EXTENSION_BUCKET ?= duckdb-core-extensions
SIGNED_EXTENSIONS_DIR ?= $(EXTENSION_REPOSITORY_PATH)
EXTENSION_SIGNING_PUBLIC_KEY_FILE ?=
.PHONY: upload-extensions
upload-extensions:
CI_CPU_COUNT="$(CI_CPU_COUNT)" ./scripts/extension-upload-repository.sh "$(EXTENSION_REPOSITORY_PATH)" "$(EXTENSION_BUCKET)"
.PHONY: verify-extension-signing
verify-extension-signing:
CI_CPU_COUNT="$(CI_CPU_COUNT)" ./scripts/verify-extension-signing.sh "$(SIGNED_EXTENSIONS_DIR)" "$(EXTENSION_SIGNING_PUBLIC_KEY_FILE)"
define cmake_build
mkdir -p ./$(1) && \
$(call sync_extensions_into,${PROJ_DIR}$(1)) \
cd $(1) && \
cmake $(GENERATOR) $(FORCE_COLOR) ${WARNINGS_AS_ERRORS} ${FORCE_32_BIT_FLAG} ${DISABLE_UNITY_FLAG} ${DISABLE_SANITIZER_FLAG} ${STATIC_LIBCPP} ${CMAKE_VARS} ${CMAKE_VARS_BUILD} $(call vcpkg_cmake_flag,${PROJ_DIR}$(1)) $(3) -DCMAKE_BUILD_TYPE=$(2) ../.. && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config $(2)
endef
debug: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/debug,Debug,-DDEBUG_MOVE=1)
release: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/release,Release,${FORCE_WARN_UNUSED_FLAG})
WINDOWS_GENERATOR_PLATFORM ?= x64
BUNDLED_EXTENSIONS_CONFIGS ?= $(PWD)/.github/config/bundled_extensions.cmake
windows_release: ${EXTENSION_CONFIG_STEP}
$(call sync_extensions_into,${PROJ_DIR}) \
cmake $(GENERATOR) $(FORCE_COLOR) $(if $(filter ninja,$(GEN)),,-DCMAKE_GENERATOR_PLATFORM=$(WINDOWS_GENERATOR_PLATFORM)) ${WARNINGS_AS_ERRORS} ${FORCE_WARN_UNUSED_FLAG} ${FORCE_32_BIT_FLAG} ${DISABLE_SANITIZER_FLAG} ${STATIC_LIBCPP} ${CMAKE_VARS} ${CMAKE_VARS_BUILD} $(call vcpkg_cmake_flag,${PROJ_DIR}) -DCMAKE_BUILD_TYPE=Release -DDUCKDB_CAPABILITIES="httplib;loadable_extensions" -DDUCKDB_EXTENSION_CONFIGS="$(BUNDLED_EXTENSIONS_CONFIGS)" . && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config Release
windows_release_32: ${EXTENSION_CONFIG_STEP}
$(call sync_extensions_into,${PROJ_DIR}) \
cmake $(GENERATOR) $(FORCE_COLOR) $(if $(filter ninja,$(GEN)),,-DCMAKE_GENERATOR_PLATFORM=Win32) ${WARNINGS_AS_ERRORS} ${FORCE_WARN_UNUSED_FLAG} ${FORCE_32_BIT_FLAG} ${DISABLE_SANITIZER_FLAG} ${STATIC_LIBCPP} ${CMAKE_VARS} ${CMAKE_VARS_BUILD} $(call vcpkg_cmake_flag,${PROJ_DIR}) -DCMAKE_BUILD_TYPE=Release -DDUCKDB_CAPABILITIES="httplib;loadable_extensions" -DDUCKDB_EXTENSION_CONFIGS="$(BUNDLED_EXTENSIONS_CONFIGS)" . && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config Release
# The wasm targets do not go through CMAKE_VARS, so DISABLE_RTTI is forwarded explicitly.
# Off by default, like every other target: a wasm build pulls in out-of-tree extensions that
# carry their own vcpkg dependencies, and whether those are built without RTTI is a decision
# for the extension, not for duckdb's Makefile.
ifeq (${DISABLE_RTTI}, 1)
WASM_RTTI_FLAG:=-DDISABLE_RTTI=1
endif
wasm_mvp: ${EXTENSION_CONFIG_STEP}
mkdir -p ./build/wasm_mvp && \
emcmake cmake $(GENERATOR) -DWASM_LOADABLE_EXTENSIONS=1 -DBUILD_EXTENSIONS_ONLY=1 -Bbuild/wasm_mvp ${WASM_RTTI_FLAG} -DCMAKE_CXX_FLAGS="-DDUCKDB_CUSTOM_PLATFORM=wasm_mvp" -DDUCKDB_EXPLICIT_PLATFORM="wasm_mvp" ${COMMON_CMAKE_VARS} ${TOOLCHAIN_FLAGS} && \
emmake make -j${CI_BUILD_JOBS} -Cbuild/wasm_mvp
wasm_eh: WASM_EH_CMAKE_VARS=-DBUILD_EXTENSIONS_ONLY=1
wasm_ci: WASM_EH_CMAKE_VARS=
wasm_eh wasm_ci: ${EXTENSION_CONFIG_STEP}
mkdir -p ./build/wasm_eh && \
emcmake cmake $(GENERATOR) -DWASM_LOADABLE_EXTENSIONS=1 $(WASM_EH_CMAKE_VARS) -Bbuild/wasm_eh ${WASM_RTTI_FLAG} -DCMAKE_CXX_FLAGS="-fwasm-exceptions -DDUCKDB_NO_THREADS=1 -DWEBDB_FAST_EXCEPTIONS=1 -DDUCKDB_CUSTOM_PLATFORM=wasm_eh" -DDUCKDB_EXPLICIT_PLATFORM="wasm_eh" ${COMMON_CMAKE_VARS} ${TOOLCHAIN_FLAGS} && \
emmake make -j${CI_BUILD_JOBS} -Cbuild/wasm_eh
wasm_threads: ${EXTENSION_CONFIG_STEP}
mkdir -p ./build/wasm_threads && \
emcmake cmake $(GENERATOR) -DWASM_LOADABLE_EXTENSIONS=1 -DBUILD_EXTENSIONS_ONLY=1 -Bbuild/wasm_threads ${WASM_RTTI_FLAG} -DCMAKE_CXX_FLAGS="-fwasm-exceptions -DWEBDB_FAST_EXCEPTIONS=1 -DWITH_WASM_THREADS=1 -DWITH_WASM_SIMD=1 -DWITH_WASM_BULK_MEMORY=1 -DDUCKDB_CUSTOM_PLATFORM=wasm_threads -pthread" -DDUCKDB_EXPLICIT_PLATFORM="wasm_threads" ${COMMON_CMAKE_VARS} -DUSE_WASM_THREADS=1 -DCMAKE_C_FLAGS="-pthread" ${TOOLCHAIN_FLAGS} && \
emmake make -j${CI_BUILD_JOBS} -Cbuild/wasm_threads
cldebug: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/cldebug,Debug,-DENABLE_SANITIZER=0 -DENABLE_UBSAN=0)
codecov: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/codecov,Release,-DENABLE_SANITIZER=0 -DENABLE_UBSAN=0 -DCOVERAGE=1)
clreldebug:
mkdir -p ./build/clreldebug && \
cd build/clreldebug && \
cmake $(GENERATOR) $(FORCE_COLOR) ${WARNINGS_AS_ERRORS} ${FORCE_32_BIT_FLAG} ${DISABLE_UNITY_FLAG} ${STATIC_LIBCPP} ${CMAKE_VARS} -DBUILD_FTS_EXTENSION=1 -DENABLE_SANITIZER=0 -DENABLE_UBSAN=0 -DCMAKE_BUILD_TYPE=RelWithDebInfo ../.. && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config RelWithDebInfo
SYNC_OUTPUT_DIR ?= build
sync_out_of_tree_extensions:
$(PYTHON) scripts/sync_out_of_tree_extensions.py $(if $(BUILD_EXTENSIONS),--build-extensions "$(BUILD_EXTENSIONS)") $(if $(EXTENSION_CONFIGS),--extension-configs "$(EXTENSION_CONFIGS)") $(if $(EXTENSION_CONFIG_BASE_DIR),--extension-config-base-dir "$(EXTENSION_CONFIG_BASE_DIR)") --output-dir '${PROJ_DIR}$(SYNC_OUTPUT_DIR)'
extension_configuration: build/extension_configuration/vcpkg.json
extension/extension_config_local.cmake:
touch extension/extension_config_local.cmake
build/extension_configuration/vcpkg.json: extension/extension_config_local.cmake extension/extension_config.cmake
mkdir -p ./build/extension_configuration && \
cd build/extension_configuration && \
cmake $(GENERATOR) $(FORCE_COLOR) ${CMAKE_VARS} -DEXTENSION_CONFIG_BUILD=TRUE -DVCPKG_BUILD=1 -DCMAKE_BUILD_TYPE=Release ../.. && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config Release
unittest: debug
build/debug/test/run $(T)
unittest_reldebug:
build/reldebug/test/run $(UNITTEST_SLOW_FLAGS) $(T)
ifneq ($(SKIP_BUILD),1)
unittest_release: release
endif
unittest_release:
build/release/test/run $(T)
TEST_CONFIGS_QUERY_VERIFICATION := \
test/configs/verify_statement_explain_sql.json \
test/configs/verify_statement_copy.json \
test/configs/verify_statement_to_string.json \
test/configs/verify_statement_explain.json \
test/configs/verify_statement_prepare.json \
test/configs/verify_serializer.json \
test/configs/verify_stats.json \
test/configs/verify_statement_serialization.json \
test/configs/disable_optimizer.json \
test/configs/verification_projection.json \
test/configs/verify_column_bindings.json
TEST_CONFIGS_EXECUTION := \
test/configs/internal_vector_serialization.json \
test/configs/internal_vector_verification.json \
test/configs/force_external.json \
test/configs/verify_fetch_row.json \
test/configs/disable_caching_operators.json \
test/configs/variant_vector.json \
test/configs/verify_aggregate_state_export.json \
test/configs/verify_functions.json \
test/configs/shredded_vector.json \
test/configs/verify_progress.json
TEST_CONFIGS_PERSISTENCE := \
test/configs/force_storage.json \
test/configs/force_storage_restart.json \
test/configs/latest_storage.json \
test/configs/wal_verification.json \
test/configs/vacuum_rebuild_indexes_force_storage.json \
test/configs/no_local_filesystem.json \
test/configs/encryption.json \
test/configs/v1_storage.json \
test/configs/v1_storage_block_size_16kB.json
TEST_CONFIGS_STORAGE_ENGINE := \
test/configs/verify_compression.json \
test/configs/block_verification.json \
test/configs/block_verification_latest.json \
test/configs/block_size_16kB.json \
test/configs/latest_storage_block_size_16kB.json \
test/configs/compressed_in_memory.json \
test/configs/prefetch_all_storage.json \
test/configs/force_storage_mmap.json
TEST_CONFIGS := $(TEST_CONFIGS_QUERY_VERIFICATION) $(TEST_CONFIGS_EXECUTION) $(TEST_CONFIGS_PERSISTENCE) \
$(TEST_CONFIGS_STORAGE_ENGINE)
.PHONY: test_configs test_configs_query_verification test_configs_execution test_configs_persistence \
test_configs_storage_engine
test_configs:
./build/release/test/run $(foreach cfg,$(TEST_CONFIGS),--test-config=$(cfg))
test_configs_query_verification:
./build/release/test/run $(foreach cfg,$(TEST_CONFIGS_QUERY_VERIFICATION),--test-config=$(cfg))
test_configs_execution:
./build/release/test/run $(foreach cfg,$(TEST_CONFIGS_EXECUTION),--test-config=$(cfg))
test_configs_persistence:
./build/release/test/run $(foreach cfg,$(TEST_CONFIGS_PERSISTENCE),--test-config=$(cfg))
test_configs_storage_engine:
./build/release/test/run $(foreach cfg,$(TEST_CONFIGS_STORAGE_ENGINE),--test-config=$(cfg))
test_vector:
./build/release/test/run --test-flags="--verify-vector dictionary_expression --skip-compiled"
./build/release/test/run --test-flags="--verify-vector dictionary_operator --skip-compiled"
./build/release/test/run --test-flags="--verify-vector constant_operator --skip-compiled"
./build/release/test/run --test-flags="--verify-vector sequence_operator --skip-compiled"
./build/release/test/run --test-flags="--verify-vector nested_shuffle --skip-compiled"
test_table_scan:
./build/release/test/run --test-flags='--on-init "SET debug_physical_table_scan_execution_strategy=SYNCHRONOUS;"'
test_storage:
$(PYTHON) scripts/test_storage_compatibility.py --versions "1.2.1|1.3.2|1.4.3" --new-unittest build/release/$(UNITTEST_BINARY)
.PHONY: alltest_release_tag test_release_tag
alltest_release_tag:
./build/release/test/run --test-flags="--select-tag release" '*' $(T)
test_release_tag:
./build/release/test/run --test-flags="--select-tag release" $(T)
unittest_relassert:
build/relassert/test/run $(UNITTEST_SLOW_FLAGS) $(T)
smoke:
$(SMOKE_RUNNER) --batch-timeout 120 --test-list test/smoke_tests.list $(T)
unittestarrow:
build/debug/test/run "[arrow]"
allunit:
./build/release/test/run --workers=50% '*' $(T)
ifndef CI
allunit: release
endif
unittest_threadsan: export TSAN_OPTIONS ?= "suppressions=./.sanitizer-thread-suppressions.txt"
unittest_threadsan: unittest_reldebug
build/reldebug/test/run $(UNITTEST_HUGE_FLAGS) --test-config test/configs/threadsan.json "[intraquery],[interquery],[detailed_profiler],test/sql/tpch/tpch_sf01.test_slow" $(T)
build/reldebug/test/run $(UNITTEST_HUGE_FLAGS) --test-config test/configs/threadsan.json --test-flags="--force-storage --force-reload" "[interquery]" $(T)
.PHONY: unittest_threadsan_extra
unittest_threadsan_extra: export TSAN_OPTIONS ?= "suppressions=./.sanitizer-thread-suppressions.txt"
unittest_threadsan_extra: unittest_reldebug
build/reldebug/test/run $(UNITTEST_HUGE_FLAGS) --test-config test/configs/threadsan.json --test-flags="--force-storage" "[interquery]" $(T)
docs:
mkdir -p ./build/docs && \
doxygen Doxyfile
doxygen: docs
open build/docs/html/index.html
reldebug: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/reldebug,RelWithDebInfo,)
relassert: ${EXTENSION_CONFIG_STEP}
$(call cmake_build,build/relassert,RelWithDebInfo,-DFORCE_ASSERT=1)
.PHONY: relassert-artifact
relassert-artifact:
RELEASE_ARTIFACT_SOURCE_DIR="$(RELEASE_ARTIFACT_SOURCE_DIR)" \
RELEASE_ARTIFACT_STAGING_DIR="$(RELEASE_ARTIFACT_STAGING_DIR)" \
RELEASE_ARTIFACT_TARBALL="$(RELEASE_ARTIFACT_TARBALL)" \
bash scripts/prepare_build_artifact.sh relassert
.PHONY: release-artifact
release-artifact:
RELEASE_ARTIFACT_SOURCE_DIR="$(RELEASE_ARTIFACT_SOURCE_DIR)" \
RELEASE_ARTIFACT_STAGING_DIR="$(RELEASE_ARTIFACT_STAGING_DIR)" \
RELEASE_ARTIFACT_TARBALL="$(RELEASE_ARTIFACT_TARBALL)" \
bash scripts/prepare_build_artifact.sh release
.PHONY: cli-release-artifact
cli-release-artifact:
bash scripts/package_release_artifact.sh cli "$(ARTIFACT_SUFFIX)" "$(CLI_BINARY)"
.PHONY: shared-libs-release-artifact
shared-libs-release-artifact:
bash scripts/package_release_artifact.sh shared-libs "$(ARTIFACT_SUFFIX)" $(SHARED_LIBRARIES)
# Writes a C source defining duckdb_register_static_extensions(), which links statically built extensions and
# capabilities into a program: compile it next to your own sources, put their archives before libduckdb_static.a, and
# call the function before opening a database (or compile extension/loader/static_extension_autoregister.cpp too to have
# it called before main). DUCKDB_CAPABILITIES and STATICALLY_LINK_EXTENSIONS pick them (LINK_EXTENSIONS is
# the older name for the latter, 'none' picks nothing); each defaults to every archive of its kind in
# STATIC_EXTENSION_LOADER_BUILD_DIR.
LOADER_BUILT_CAPABILITIES = $(if $(wildcard $(STATIC_EXTENSION_LOADER_BUILD_DIR)/src/main/http/libduckdb_httplib.a),httplib) $(if $(wildcard $(STATIC_EXTENSION_LOADER_BUILD_DIR)/src/main/extension/libduckdb_loadable_extensions.a),loadable_extensions)
LOADER_BUILT_EXTENSIONS = $(patsubst lib%_extension.a,%,$(notdir $(wildcard $(STATIC_EXTENSION_LOADER_BUILD_DIR)/extension/*/lib*_extension.a)))
LOADER_CAPABILITIES = $(if $(strip $(DUCKDB_CAPABILITIES)),$(subst ;, ,$(DUCKDB_CAPABILITIES)),$(LOADER_BUILT_CAPABILITIES))
LOADER_EXTENSIONS = $(or $(strip $(subst ;, ,$(STATICALLY_LINK_EXTENSIONS) $(LINK_EXTENSIONS))),$(LOADER_BUILT_EXTENSIONS))
STATIC_EXTENSION_LOADER_BUILD_DIR ?= build/release
STATIC_EXTENSION_LOADER_FILE ?= $(STATIC_EXTENSION_LOADER_BUILD_DIR)/static_extension_loader.c
.PHONY: static_extension_loader
static_extension_loader:
$(PYTHON) scripts/generate_static_extension_loader.py --output "$(STATIC_EXTENSION_LOADER_FILE)" \
$(filter-out none,$(LOADER_CAPABILITIES) $(LOADER_EXTENSIONS))
@echo "Wrote $(STATIC_EXTENSION_LOADER_FILE)"
.PHONY: static-libs-release-artifact
static-libs-release-artifact:
bash scripts/package_release_artifact.sh static-libs "$(ARTIFACT_SUFFIX)" $(STATIC_LIBRARIES)
.PHONY: symbol-checks symbol-leakage-check banned-symbol-check
symbol-checks: symbol-leakage-check banned-symbol-check
symbol-leakage-check:
$(PYTHON) scripts/exported_symbols_check.py build/release/src/libduckdb*.so
banned-symbol-check:
$(PYTHON) scripts/banned_symbols_check.py --directory build/release/src
.PHONY: linux-release-link-checks
linux-release-link-checks:
bash scripts/ci/linux_release_link_checks.sh
define ensure_apt_commands
missing=0; \
for cmd in $(1); do \
command -v $$cmd >/dev/null 2>&1 || missing=1; \
done; \
if [ $$missing -eq 1 ]; then \
sudo apt-get $(APT_TIMEOUT_OPTS) update -y -q && \
sudo apt-get $(APT_TIMEOUT_OPTS) install -y -q $(2); \
fi
endef
define ensure_apt_packages
missing=0; \
for pkg in $(1); do \
dpkg-query -W -f='$${Status}' $$pkg 2>/dev/null | grep -q "install ok installed" || missing=1; \
done; \
if [ $$missing -eq 1 ]; then \
sudo apt-get $(APT_TIMEOUT_OPTS) update -y -q && \
sudo apt-get $(APT_TIMEOUT_OPTS) install -y -q $(1); \
fi
endef
APT_TIMEOUT_OPTS=-o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 -o DPkg::Lock::Timeout=30
.PHONY: toolsci
toolsci:
$(call ensure_apt_commands,ninja mold ccache pkg-config pigz clang++-20 clangd-20,ninja-build mold ccache pkg-config pigz clang++-20 clangd-20)
$(call ensure_apt_packages,python3-requests libcurl4-openssl-dev llvm-20-dev libclang-rt-20-dev)
ls -lh /usr/bin/gcc* /usr/bin/g++* /usr/bin/clang++*
gcc --version
g++ --version
clang++ --version
test_ci:
$(PYTHON) scripts/ci/run_unit_tests.py --jobs $(CI_CPU_COUNT) $(T)
.PHONY: prepare_tools format_tools parser_tools spell_tools
prepare_tools: spell_tools capigen_venv
format_tools: parser_tools spell_tools
parser_tools:
$(call ensure_apt_commands,ninja,ninja-build)
sudo pip3 install --break-system-packages cxxheaderparser pcpp
@echo "::group::Installed Python packages"
pip3 freeze
@echo "::endgroup::"
spell_tools:
@if [ "$$(uname -s)" != "Linux" ]; then \
echo "Skipping spell_tools on non-Linux"; \
else \
set -eu; \
VERSION=1.45.1; \
if [ "$$(uname -m)" = "arm64" ] || [ "$$(uname -m)" = "aarch64" ]; then \
ARCH="aarch64"; \
else \
ARCH="x86_64"; \
fi; \
TARGET_FILE="$${ARCH}-unknown-linux-musl"; \
FILE_NAME="typos-v$${VERSION}-$${TARGET_FILE}.tar.gz"; \
DOWNLOAD_URL="https://github.com/crate-ci/typos/releases/download/v$${VERSION}/$${FILE_NAME}"; \
$(PYTHON) scripts/ci/retry.py -- curl --fail --location --silent --show-error --output "/tmp/$${FILE_NAME}" "$${DOWNLOAD_URL}"; \
TMP_DIR="$$(mktemp -d)"; \
tar -xzf "/tmp/$${FILE_NAME}" -C "$${TMP_DIR}"; \
TYPOS_BIN="$$(find "$${TMP_DIR}" -type f -name typos | head -n 1)"; \
if [ -w /usr/local/bin ]; then \
install -m 0755 "$${TYPOS_BIN}" /usr/local/bin/typos; \
else \
sudo install -m 0755 "$${TYPOS_BIN}" /usr/local/bin/typos; \
fi; \
typos --version; \
fi
.PHONY: enum-integrity-check
enum-integrity-check:
$(PYTHON) scripts/verify_enum_integrity.py src/include/duckdb.h
.PHONY: extension-patch-check
extension-patch-check:
cmake -DCONFIG_DIR=.github/config -DPATCH_DIR=.github/patches/extensions -P scripts/check_extension_patches.cmake
.PHONY: format_venv
format_venv:
@if [ ! -x "$(FORMAT_PYTHON)" ]; then \
mkdir -p "$(dir $(FORMAT_VENV))" && \
$(PYTHON) -m venv "$(FORMAT_VENV)"; \
fi
@$(FORMAT_PYTHON) -m pip show black >/dev/null 2>&1 || $(FORMAT_PYTHON) -m pip install black==24.*
@$(FORMAT_PYTHON) -m pip show cmake-format >/dev/null 2>&1 || $(FORMAT_PYTHON) -m pip install cmake-format
@$(FORMAT_PYTHON) -m pip show clang_format >/dev/null 2>&1 || $(FORMAT_PYTHON) -m pip install clang_format==11.0.1
# Venv holding capigen (the C API generator) and the formatters it needs, pinned by api_spec/pyproject.toml
.PHONY: capigen_venv
capigen_venv:
@if [ ! -x "$(CAPIGEN_PYTHON)" ]; then \
mkdir -p "$(dir $(CAPIGEN_VENV))" && \
$(PYTHON) -m venv "$(CAPIGEN_VENV)" && \
$(CAPIGEN_PYTHON) -m pip install -U pip; \
fi
@$(CAPIGEN_PYTHON) -m pip show capigen >/dev/null 2>&1 || $(CAPIGEN_PYTHON) -m pip install --group api_spec/pyproject.toml:generate
benchmark:
mkdir -p ./build/release && \
cd build/release && \
cmake $(GENERATOR) $(FORCE_COLOR) ${WARNINGS_AS_ERRORS} ${FORCE_WARN_UNUSED_FLAG} ${FORCE_32_BIT_FLAG} ${DISABLE_UNITY_FLAG} ${DISABLE_SANITIZER_FLAG} ${STATIC_LIBCPP} ${CMAKE_VARS} -DBUILD_BENCHMARKS=1 -DCMAKE_BUILD_TYPE=Release ../.. && \
$(NINJA_BUILD_WRAPPER) cmake --build . --config Release
.PHONY: test_benchmark_sql
test_benchmark_sql:
$(PYTHON) -u scripts/test_benchmark_sql_runner.py --shell build/relassert/duckdb
tidy-check:
mkdir -p ./build/tidy && \
cd build/tidy && \
cmake -DCLANG_TIDY=1 -DDISABLE_UNITY=1 -DBUILD_EXTENSIONS=parquet -DBUILD_SHELL=0 ../.. && \
$(PYTHON) ../../scripts/run-clang-tidy.py -quiet -j $(CI_CPU_COUNT) ${TIDY_BINARY_PARAMETER} ${TIDY_SHARD_PARAMETERS} ${TIDY_PERFORM_CHECKS}
install-clangd-tidy:
mkdir -p $(dir $(CLANGD_TIDY_VENV)) && \
$(PYTHON) -m venv $(CLANGD_TIDY_VENV) && \
$(CLANGD_TIDY_VENV)/bin/pip install --upgrade 'clangd-tidy==$(CLANGD_TIDY_VERSION)'
tidy-check-clangd:
mkdir -p ./build/tidy && \
cd build/tidy && \
cmake $(GENERATOR) $(FORCE_COLOR) ${STATIC_LIBCPP} ${CMAKE_VARS} -DCLANG_TIDY=1 -DDISABLE_UNITY=1 -DBUILD_EXTENSIONS=parquet -DBUILD_SHELL=0 ../.. && \
trap 'rm -rf ./pchs' EXIT && \
$(PYTHON) -u ../../scripts/run-clangd-tidy.py -j $(CI_TIDY_JOBS) ${CLANGD_TIDY_BINARY_PARAMETER} ${CLANGD_BINARY_PARAMETER} ${CLANGD_TIDY_QUERY_DRIVER_PARAMETER}
tidy-check-diff:
mkdir -p ./build/tidy && \
cd build/tidy && \
cmake -DCLANG_TIDY=1 -DDISABLE_UNITY=1 -DBUILD_EXTENSIONS=parquet -DBUILD_SHELL=0 ../.. && \
cd ../../ && \
git diff origin/${GIT_BASE_BRANCH} . ':(exclude)tools' ':(exclude)extension' ':(exclude)test' ':(exclude)benchmark' ':(exclude)third_party' ':(exclude)src/common/adbc' ':(exclude)src/main/capi' ':(exclude)examples/embedded-c' | $(PYTHON) scripts/clang-tidy-diff.py -path build/tidy -quiet -j $(CI_CPU_COUNT) ${TIDY_BINARY_PARAMETER} ${TIDY_PERFORM_CHECKS} -p1
tidy-fix:
mkdir -p ./build/tidy && \
cd build/tidy && \
cmake -DCLANG_TIDY=1 -DDISABLE_UNITY=1 -DBUILD_EXTENSIONS=parquet -DBUILD_SHELL=0 ../.. && \
$(PYTHON) ../../scripts/run-clang-tidy.py -fix
test_compile: # test compilation of individual cpp files
$(PYTHON) scripts/test_compile.py
format-check: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py --all --check $(T)
format-check-silent: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py --all --check --silent $(T)
format-check-files: $(FORMAT_SETUP_DEPS)
@test -n "$(FORMAT_FILES_FROM)" || (echo "FORMAT_FILES_FROM is required" >&2; exit 1)
$(FORMAT_PYTHON) scripts/format.py --files-from "$(FORMAT_FILES_FROM)" --check --silent $(T)
format-fix-files: $(FORMAT_SETUP_DEPS)
@test -n "$(FORMAT_FILES_FROM)" || (echo "FORMAT_FILES_FROM is required" >&2; exit 1)
$(FORMAT_PYTHON) scripts/format.py --files-from "$(FORMAT_FILES_FROM)" --fix --noconfirm $(T)
format-fix: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py --all --fix --noconfirm $(T)
format-parser-grammar: $(FORMAT_SETUP_DEPS)
printf '%s\n' \
src/include/duckdb/parser/peg/transformer/peg_transformer.hpp \
src/parser/peg/transformer/transform_generated_trampoline.cpp \
src/parser/peg/compiled_grammar.cpp \
src/parser/peg/matcher_factory.cpp \
src/parser/peg/peg_rule_id.cpp \
src/include/duckdb/parser/peg/peg_rule_id.hpp \
src/parser/peg/matcher.cpp | \
$(FORMAT_PYTHON) scripts/format.py --files-from - --fix --noconfirm
.PHONY: parser-grammar-tools parser-grammar
parser-grammar-tools: $(FORMAT_SETUP_DEPS)
@$(FORMAT_PYTHON) -m pip show pyyaml >/dev/null 2>&1 || $(FORMAT_PYTHON) -m pip install PyYAML
parser-grammar: parser-grammar-tools
PYTHON="$(FORMAT_PYTHON)" ./scripts/parser/build_grammar.sh
.PHONY: check-extension-entries
check-extension-entries: extension_configuration $(FORMAT_SETUP_DEPS)
$(PYTHON) scripts/generate_extensions_function.py
$(FORMAT_PYTHON) scripts/format.py src/include/duckdb/main/extension_entries.hpp --fix --noconfirm
@git diff -- src/include/duckdb/main/extension_entries.hpp > extension_entries.hpp.diff
@if [ -s extension_entries.hpp.diff ]; then \
cat extension_entries.hpp.diff; \
echo "error: differences found in src/include/duckdb/main/extension_entries.hpp"; \
exit 1; \
else \
rm -f extension_entries.hpp.diff; \
echo "No differences found"; \
fi
format-head: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py HEAD --fix --noconfirm $(T)
format-changes: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py HEAD --fix --noconfirm $(T)
format-main: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py main --fix --noconfirm $(T)
format-feature: $(FORMAT_SETUP_DEPS)
$(FORMAT_PYTHON) scripts/format.py feature --fix --noconfirm $(T)
format-configs:
$(foreach file, $(wildcard $(CONFIGS_DIR)/*), jq . < "$(file)" > "$(file).tmp" && mv "$(file).tmp" "$(file)" ;)
third_party/sqllogictest:
git clone --depth=1 --branch main https://github.com/duckdb/sqllogictest.git third_party/sqllogictest
sqlite: release | third_party/sqllogictest
git --git-dir third_party/sqllogictest/.git pull
./build/release/test/run "[sqlitelogic]"
sqlsmith: debug
./build/debug/third_party/sqlsmith/sqlsmith --duckdb=:memory:
# Bloaty: a size profiler for binaries, is a project backed by Google engineers, https://github.com/google/bloaty for more info
# works both on executable, libraries (-> .duckdb_extension) and on WebAssembly
bloaty/bloaty:
git clone https://github.com/google/bloaty.git
cd bloaty && git submodule update --init --recursive && cmake -Bm build -G Ninja -S . && cmake --build build
mv bloaty/build/bloaty bloaty/bloaty
bloaty: reldebug bloaty/bloaty
cd build/reldebug && dsymutil duckdb
./bloaty/bloaty build/reldebug/duckdb -d symbols -n 20 --debug-file=build/reldebug/duckdb.dSYM/Contents/Resources/DWARF/duckdb
# ./bloaty/bloaty build/reldebug/extension/parquet/parquet.duckdb_extension -d symbols -n 20 # to execute on extension
# Generate compile commands without actually building
clangd:
cmake -DCMAKE_BUILD_TYPE=Debug ${CMAKE_VARS} -B .cache/clangd/debug .
cp .cache/clangd/debug/compile_commands.json .cache/clangd/compile_commands.json
coverage-check:
./scripts/coverage_check.sh
generate-files-deps:
$(PYTHON) -m pip install -U pip
$(PYTHON) -m pip install --group api_spec/pyproject.toml:generate
.PHONY: generate-capi-v1 generate-functions generate-metrics generate-settings generate-serialization
.PHONY: generate-util generate-storage-info generate-enum-util generate-html-template generate-parser-grammar
generate-capi-v1:
CAPIGEN_PYTHON="$(abspath $(CAPIGEN_PYTHON))" ./scripts/capi_v1_regen.sh
generate-functions:
$(PYTHON) scripts/generate_functions.py
generate-metrics:
$(PYTHON) scripts/generate_metrics.py
generate-settings:
$(PYTHON) scripts/generate_settings.py
generate-serialization:
$(PYTHON) scripts/generate_serialization.py
generate-util:
$(PYTHON) scripts/generate_util.py
generate-storage-info:
$(PYTHON) scripts/generate_storage_info.py
generate-enum-util:
$(PYTHON) scripts/generate_enum_util.py
generate-html-template:
$(PYTHON) scripts/generate_html_template.py
generate-parser-grammar:
$(MAKE) parser-grammar
generate-files: $(CAPIGEN_SETUP_DEPS)
DUCKDB_FORMAT_SKIP_TYPOS=1 FORMAT_VENV="$(abspath $(CAPIGEN_VENV))" \
FORMAT_PYTHON="$(abspath $(CAPIGEN_PYTHON))" \
$(MAKE) $(if $(filter -j%,$(MAKEFLAGS)),,-j $(CI_CPU_COUNT)) \
generate-capi-v1 generate-functions generate-metrics generate-settings \
generate-serialization generate-util generate-storage-info generate-html-template generate-parser-grammar
$(MAKE) generate-enum-util
# Format files modified by the generators without walking every branch change.
mkdir -p .cache
git diff --name-only --diff-filter=ACMR > .cache/generated-format-files.txt
DUCKDB_FORMAT_SKIP_TYPOS=1 FORMAT_FILES_FROM=.cache/generated-format-files.txt $(MAKE) format-fix-files
#### Setup VCPKG to correct version 2026.06.24 tag is cd61e1e26a038e82d6550a3ebbe0fbbfe7da78e3
vcpkg/scripts/buildsystems/vcpkg.cmake:
if [ -d vcpkg/.git ]; then \
git -C vcpkg fetch --tags && \
git -C vcpkg checkout --detach 2026.06.24; \
else \
git clone --branch 2026.06.24 https://github.com/microsoft/vcpkg; \
fi
cd vcpkg && ./bootstrap-vcpkg.sh
setup-vcpkg: vcpkg/scripts/buildsystems/vcpkg.cmake
@echo 'Consider exporting VCPKG_TOOLCHAIN_PATH=$(PWD)/vcpkg/scripts/buildsystems/vcpkg.cmake'
cleanup-vcpkg:
rm -rf vcpkg
test-utils:
make release EXTENSION_CONFIGS='.github/config/extensions/httpfs.cmake;.github/config/extensions/test-utils.cmake;.github/config/extensions/inet.cmake' STATICALLY_LINK_EXTENSIONS='core_functions;parquet;json;icu;tpcds;tpch;autocomplete;httpfs;inet;test_utils' DUCKDB_EXTENSIONS='tpcds;icu;autocomplete;tpch;json'