Build System Migration - Meson + Autotools + CMake = PkgConfig!

Build System Migration - Meson + Autotools + CMake = PkgConfig!


The Problem

Potential Ways to Fix it

The Migration Process

Data & Code Separation

# scripts/make/exports.mk
EXTERNALS = $(shell realpath ./external)
EXTERNALS_CONFIG = $(shell realpath ./config/external)
INSTALL_DIRECTORY = $(shell realpath ./install)
BUILD_DIRECTORY = $(shell realpath ./build)
CLANGD_CONFIG = $(shell realpath ./.clangd)
PLATFORM = $(shell uname -s)
MESON_BUILD_TYPE = debug
CMAKE_BUILD_TYPE = Debug
SHELL := /bin/bash

ifeq ($(PLATFORM),Linux)
	PLATFORM_CONFIG_EXTENSION = linux
else ifeq ($(PLATFORM),Darwin)
	PLATFORM_CONFIG_EXTENSION = apple
else ifeq ($(PLATFORM),MINGW64*)
	PLATFORM_CONFIG_EXTENSION = windows
else
	PLATFORM_CONFIG_EXTENSION = unknown
endif
# scripts/make/build_wrappers.mk
define build_wrapper_cmake
$(1)_CONFIGURE_FLAGS=$$(shell cat $$(EXTERNALS_CONFIG)/$(1)/{flags.common,flags.$$(PLATFORM_CONFIG_EXTENSION)} | xargs)

$(1): $(1).configure $(1).build $(1).install $(1).clangd

$(1).configure:
	cmake \
		-DCMAKE_BUILD_TYPE=$$(CMAKE_BUILD_TYPE) \
		-DCMAKE_INSTALL_PREFIX=$$(INSTALL_DIRECTORY) \
		-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
		$$($(1)_CONFIGURE_FLAGS) \
		-B "$$(BUILD_DIRECTORY)/$(1)" \
		-S "$$(EXTERNALS)/$(1)"

$(1).build:
	cmake --build "$$(BUILD_DIRECTORY)/$(1)"

$(1).clangd:
	$$(call clangd_config_string,$(1),$$(BUILD_DIRECTORY)/$(1))

$(1).install:
	cmake --install "$$(BUILD_DIRECTORY)/$(1)" --prefix "$$(INSTALL_DIRECTORY)"

$(1).clean:
	rm -rf "$$(BUILD_DIRECTORY)/$(1)"
endef
...
# Makefile
$(eval $(call build_wrapper_meson,fontconfig))
$(eval $(call build_wrapper_cmake,cglm))
$(eval $(call build_wrapper_cmake,freetype))
$(eval $(call build_wrapper_meson,harfbuzz))
$(eval $(call build_wrapper_cmake,glfw))
$(eval $(call build_wrapper_cmake,glad))
$(eval $(call build_wrapper_autotools,ffmpeg))

A Note on Clangd integration

# scripts/make/build_wrappers.mk
define clangd_config_string
	@touch $(CLANGD_CONFIG)
	@if ! grep -q $(1) $(CLANGD_CONFIG); then \
		{ echo "---"; \
		  echo "If:"; \
		  echo "  PathMatch: .*$(1).*"; \
		  echo "CompileFlags:"; \
		  echo "  CompilationDatabase: $(2)"; \
		} | tee -a $(CLANGD_CONFIG); \
endef

# Makefile
clangd:
	$(call clangd_config_string,engine,$(BUILD_DIRECTORY))
	$(call clangd_config_string,projects,$(BUILD_DIRECTORY))

Advantages