Projects

cxx-modgraph

cxx-modgraph is a small C++20 tool that turns compiler-generated C++ module dependency information into a deterministic build graph. It imports P1689 dependency scans, validates and orders them as a DAG, and emits build-system friendly formats such as includable GNU Make fragments and canonical JSON.

Description

C++ modules introduce an additional build-ordering problem: before compiling a translation unit, the build system must know which modules it imports, where those modules are provided, and which binary module interfaces must already exist. Compilers can discover this information, but integrating their output into simple or bespoke build systems remains awkward.

cxx-modgraph bridges this gap. It combines a compiler's P1689 dependency scan with its compilation database, normalizes the result into a compiler-neutral model, validates providers and imports, detects cycles, and processes the graph deterministically using Kahn’s algorithm. It can then emit canonical JSON or a recipe-free Make fragment containing BMI and object prerequisites.

The project deliberately separates dependency facts from compiler commands. cxx-modgraph describes what must be built and in what dependency order; adapters or consuming build systems decide how to invoke the compiler. The included Clang/GNU Make adapter demonstrates the complete workflow: it discovers local module-interface candidates from explicit module directories, runs clang-scan-deps, imports the resulting P1689 graph, builds libc++'s std module, and compiles a custom module and its consumer incrementally.

The longer-term goal is to provide a small interoperability layer for plain Makefiles, bespoke CMake or Meson integrations, and other build systems while native C++ module support continues to mature.

Example Makefile

Here is an example GNU Makefile from the project, showing the gains in simplicity:

CXX := clang++

.DEFAULT_GOAL := all

CXX_MODGRAPH := ../../build/cxx-modgraph
CXX_MODGRAPH_SOURCES := src/main.cpp
CXX_MODGRAPH_MODULE_PATHS := modules
CXX_MODGRAPH_USE_LIBCXX_STD := 1

include ../../adapters/make/clang.mk

.PHONY: all clean
all: hello

hello: $(CXX_MODGRAPH_LINK_OBJECTS)
 $(CXX) $(CXX_MODGRAPH_CXXFLAGS) $^ -o $@

clean:
 rm -rf build hello

Anyone who has worked with C++ modules will appreciate the amount of ceremony reduced by using this. The nice thing about this approach is that it scales to even larger Makefile-based projects.