Add a make build path for distro packaging
Mirror the crafter-build pipeline in a plain GNU Makefile — precompile the libc++ std module and the Imsd partitions in dependency order, archive imsd-core, link the three executables with the same clang/ libc++ flags — so distributions can build from source without packaging crafter-build first. make check runs the same 7 suites; make install stages the binaries plus the packaging/ files under DESTDIR/PREFIX. Rewrite packaging/APKBUILD from a documentation skeleton into a real source-build APKBUILD on top of it (Alpine's llvm-runtimes ships the std module sources since 22.x). project.cpp remains the canonical build description. Assisted-by: Claude:claude-fable-5
This commit is contained in:
parent
f2a404855f
commit
10379586b5
3 changed files with 173 additions and 24 deletions
140
Makefile
Normal file
140
Makefile
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||||
|
#
|
||||||
|
# Distro-packaging build path. project.cpp (crafter-build) remains the
|
||||||
|
# canonical build description; this Makefile mirrors it for environments
|
||||||
|
# where crafter-build isn't packaged — same clang module pipeline, same
|
||||||
|
# flags. Keep the two in sync when products, module partitions or link
|
||||||
|
# flags change.
|
||||||
|
#
|
||||||
|
# make -> build/make/{imsd,imsd-media,imsd-dialerd}
|
||||||
|
# make check -> build + run the 7 unit-test suites
|
||||||
|
# make install -> DESTDIR/PREFIX staged install (binaries + systemd
|
||||||
|
# unit, D-Bus policy, dialerd autostart, ims-pdn-up.sh)
|
||||||
|
#
|
||||||
|
# Requires clang++ with libc++ and the libc++ std module sources
|
||||||
|
# (std.cppm — Alpine: llvm-runtimes, Arch: libc++). Override STD_CPPM if
|
||||||
|
# yours lives elsewhere.
|
||||||
|
|
||||||
|
# make's builtin default is CXX=g++, and distro build environments (abuild)
|
||||||
|
# export CXX=c++ — both gcc, which has no --precompile. This build requires
|
||||||
|
# clang: the file assignment deliberately ignores the environment while still
|
||||||
|
# yielding to an explicit `make CXX=...`.
|
||||||
|
CXX = clang++
|
||||||
|
AR ?= ar
|
||||||
|
PKG_CONFIG ?= pkg-config
|
||||||
|
STD_CPPM ?= /usr/share/libc++/v1/std.cppm
|
||||||
|
|
||||||
|
O ?= build/make
|
||||||
|
PCM = $(O)/pcm
|
||||||
|
OBJ = $(O)/obj
|
||||||
|
|
||||||
|
OPT ?= -O3
|
||||||
|
# One flag set for every TU: BMIs are rejected on compiler-option mismatch,
|
||||||
|
# so per-target extras are limited to -I/-D (compile) and -l/-L (link).
|
||||||
|
ALL_CXXFLAGS = -std=c++26 -stdlib=libc++ $(OPT) $(CXXFLAGS)
|
||||||
|
ALL_LDFLAGS = -fuse-ld=lld $(LDFLAGS)
|
||||||
|
|
||||||
|
# pkg-config gio-2.0: only -I/-D pass through — it also emits -pthread,
|
||||||
|
# which would config-mismatch the shared std BMI (project.cpp filters
|
||||||
|
# identically). pthread lives in libc on every platform we target.
|
||||||
|
GIO_CFLAGS := $(filter -I% -D%,$(shell $(PKG_CONFIG) --cflags gio-2.0))
|
||||||
|
GIO_LIBS := $(filter -l% -L%,$(shell $(PKG_CONFIG) --libs gio-2.0))
|
||||||
|
ifeq ($(strip $(GIO_LIBS)),)
|
||||||
|
GIO_LIBS := -lgio-2.0 -lgobject-2.0 -lglib-2.0
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Imsd module partitions, plus the primary interface last. The BMI file
|
||||||
|
# names must stay <module>-<partition>.pcm — that is how clang resolves
|
||||||
|
# `import :Part;` under -fprebuilt-module-path.
|
||||||
|
PARTITIONS = Imsd-Util Imsd-Sip Imsd-Sdp Imsd-Aka Imsd-Ipsec \
|
||||||
|
Imsd-Messages Imsd-Engine
|
||||||
|
CORE_MODULES = $(PARTITIONS) Imsd
|
||||||
|
CORE_OBJS = $(CORE_MODULES:%=$(OBJ)/%.o)
|
||||||
|
|
||||||
|
TESTS = Util Aka Ipsec Messages Engine Sip Sdp
|
||||||
|
|
||||||
|
all: $(O)/imsd $(O)/imsd-media $(O)/imsd-dialerd
|
||||||
|
|
||||||
|
# ---- module BMIs ----------------------------------------------------------
|
||||||
|
|
||||||
|
$(PCM)/std.pcm: $(STD_CPPM) | $(PCM)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) -Wno-reserved-identifier \
|
||||||
|
-Wno-reserved-module-identifier --precompile $< -o $@
|
||||||
|
|
||||||
|
$(PCM)/%.pcm: interfaces/%.cppm $(PCM)/std.pcm | $(PCM)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) -fprebuilt-module-path=$(PCM) --precompile $< -o $@
|
||||||
|
|
||||||
|
# partition import graph (see the `import :X;` lines in interfaces/)
|
||||||
|
$(PCM)/Imsd-Aka.pcm $(PCM)/Imsd-Ipsec.pcm: $(PCM)/Imsd-Util.pcm
|
||||||
|
$(PCM)/Imsd-Messages.pcm: $(PCM)/Imsd-Util.pcm $(PCM)/Imsd-Aka.pcm \
|
||||||
|
$(PCM)/Imsd-Sip.pcm
|
||||||
|
$(PCM)/Imsd-Engine.pcm: $(PCM)/Imsd-Util.pcm $(PCM)/Imsd-Sip.pcm \
|
||||||
|
$(PCM)/Imsd-Sdp.pcm $(PCM)/Imsd-Messages.pcm
|
||||||
|
$(PCM)/Imsd.pcm: $(PARTITIONS:%=$(PCM)/%.pcm)
|
||||||
|
|
||||||
|
# ---- imsd-core (static lib of the pure-C++ engine modules) ----------------
|
||||||
|
|
||||||
|
$(OBJ)/%.o: $(PCM)/%.pcm | $(OBJ)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) -fprebuilt-module-path=$(PCM) -c $< -o $@
|
||||||
|
|
||||||
|
$(O)/libimsd-core.a: $(CORE_OBJS)
|
||||||
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
|
# ---- executables -----------------------------------------------------------
|
||||||
|
|
||||||
|
$(OBJ)/main.o: implementations/main.cpp $(PCM)/Imsd.pcm | $(OBJ)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(GIO_CFLAGS) -fprebuilt-module-path=$(PCM) \
|
||||||
|
-c $< -o $@
|
||||||
|
|
||||||
|
$(O)/imsd: $(OBJ)/main.o $(O)/libimsd-core.a
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(ALL_LDFLAGS) $^ $(GIO_LIBS) -lpthread -o $@
|
||||||
|
|
||||||
|
$(OBJ)/media.o: implementations/media.cpp $(PCM)/std.pcm | $(OBJ)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) -fprebuilt-module-path=$(PCM) -c $< -o $@
|
||||||
|
|
||||||
|
$(O)/imsd-media: $(OBJ)/media.o
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(ALL_LDFLAGS) $^ -ldl -lpthread -o $@
|
||||||
|
|
||||||
|
$(OBJ)/dialerd.o: implementations/dialerd.cpp $(PCM)/std.pcm | $(OBJ)
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(GIO_CFLAGS) -fprebuilt-module-path=$(PCM) \
|
||||||
|
-c $< -o $@
|
||||||
|
|
||||||
|
$(O)/imsd-dialerd: $(OBJ)/dialerd.o
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(ALL_LDFLAGS) $^ $(GIO_LIBS) -o $@
|
||||||
|
|
||||||
|
# ---- tests -----------------------------------------------------------------
|
||||||
|
|
||||||
|
$(O)/tests/%: tests/%/main.cpp $(PCM)/Imsd.pcm $(O)/libimsd-core.a | $(O)/tests
|
||||||
|
$(CXX) $(ALL_CXXFLAGS) $(ALL_LDFLAGS) -fprebuilt-module-path=$(PCM) \
|
||||||
|
$< $(O)/libimsd-core.a -lpthread -o $@
|
||||||
|
|
||||||
|
check: $(TESTS:%=$(O)/tests/%)
|
||||||
|
@fail=0; for t in $(TESTS); do \
|
||||||
|
echo "== $$t"; $(O)/tests/$$t || fail=1; \
|
||||||
|
done; exit $$fail
|
||||||
|
|
||||||
|
# ---- install ----------------------------------------------------------------
|
||||||
|
|
||||||
|
PREFIX ?= /usr
|
||||||
|
|
||||||
|
install: all
|
||||||
|
install -Dm755 $(O)/imsd $(DESTDIR)$(PREFIX)/bin/imsd
|
||||||
|
install -Dm755 $(O)/imsd-dialerd $(DESTDIR)$(PREFIX)/bin/imsd-dialerd
|
||||||
|
install -Dm755 $(O)/imsd-media $(DESTDIR)$(PREFIX)/libexec/imsd-media
|
||||||
|
install -Dm755 packaging/ims-pdn-up.sh \
|
||||||
|
$(DESTDIR)$(PREFIX)/libexec/ims-pdn-up.sh
|
||||||
|
install -Dm644 packaging/imsd.service \
|
||||||
|
$(DESTDIR)$(PREFIX)/lib/systemd/system/imsd.service
|
||||||
|
install -Dm644 packaging/imsd-dialerd.desktop \
|
||||||
|
$(DESTDIR)/etc/xdg/autostart/imsd-dialerd.desktop
|
||||||
|
install -Dm644 packaging/net.catcrafts.IMS1.conf \
|
||||||
|
$(DESTDIR)$(PREFIX)/share/dbus-1/system.d/net.catcrafts.IMS1.conf
|
||||||
|
|
||||||
|
$(PCM) $(OBJ) $(O)/tests:
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(O)
|
||||||
|
|
||||||
|
.PHONY: all check install clean
|
||||||
20
README.md
20
README.md
|
|
@ -95,6 +95,21 @@ crafter-build -- --product=dialerd # bin/imsd-dialerd-.../imsd-dialerd (dialer
|
||||||
crafter-build test # unit tests (Util, Aka, Ipsec, Messages, Engine, Sip, Sdp)
|
crafter-build test # unit tests (Util, Aka, Ipsec, Messages, Engine, Sip, Sdp)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Building with make (distro packaging)
|
||||||
|
|
||||||
|
For environments without crafter-build, the Makefile mirrors the same clang
|
||||||
|
module pipeline: GNU make, clang++ with libc++ and the libc++ std module
|
||||||
|
sources (`std.cppm` — package `llvm-runtimes` on Alpine, `libc++` on Arch),
|
||||||
|
lld, and gio-2.0 headers.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make # build/make/{imsd,imsd-media,imsd-dialerd}
|
||||||
|
make check # the same 7 unit-test suites
|
||||||
|
make install # DESTDIR/PREFIX staged install incl. the packaging/ files
|
||||||
|
```
|
||||||
|
|
||||||
|
`project.cpp` stays the canonical build description; the Makefile tracks it.
|
||||||
|
|
||||||
### Cross-compiling for a phone (aarch64 Alpine/postmarketOS)
|
### Cross-compiling for a phone (aarch64 Alpine/postmarketOS)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -121,8 +136,9 @@ after `packaging/ims-pdn-up.sh` has brought up the ims PDN through
|
||||||
ModemManager. It spawns `/usr/libexec/imsd-media` per call. Registration
|
ModemManager. It spawns `/usr/libexec/imsd-media` per call. Registration
|
||||||
resumes an in-kernel IPsec SA when one is present (avoiding the network's
|
resumes an in-kernel IPsec SA when one is present (avoiding the network's
|
||||||
fresh-SA throttle) and keeps itself alive with a re-REGISTER refresh at half
|
fresh-SA throttle) and keeps itself alive with a re-REGISTER refresh at half
|
||||||
the granted lifetime. `packaging/APKBUILD.binary` + `make-bin-tarball.sh`
|
the granted lifetime. `packaging/APKBUILD` builds the apk from source via
|
||||||
wrap a cross-compiled build into an apk.
|
the Makefile; `packaging/APKBUILD.binary` + `make-bin-tarball.sh` wrap a
|
||||||
|
cross-compiled build into an apk instead.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-only
|
# SPDX-License-Identifier: GPL-3.0-only
|
||||||
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||||
# Maintainer: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
|
# Maintainer: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
|
||||||
# APKBUILD skeleton — buildable once crafter-build is packaged for Alpine
|
|
||||||
# (or replaced here by a bootstrap invocation). Until then this documents
|
|
||||||
# the packaging shape.
|
|
||||||
pkgname=imsd
|
pkgname=imsd
|
||||||
pkgver=0.3.0
|
pkgver=0.3.0
|
||||||
pkgrel=0
|
pkgrel=0
|
||||||
|
|
@ -14,29 +11,25 @@ license="GPL-3.0-only"
|
||||||
# the media leg dlopen's the AMR-WB codecs; pw-record/pw-play drive PipeWire —
|
# the media leg dlopen's the AMR-WB codecs; pw-record/pw-play drive PipeWire —
|
||||||
# none of which abuild's .so auto-scan can see
|
# none of which abuild's .so auto-scan can see
|
||||||
depends="modemmanager opencore-amr vo-amrwbenc pipewire-tools"
|
depends="modemmanager opencore-amr vo-amrwbenc pipewire-tools"
|
||||||
# versioned provides = imsd satisfies soc-qcom-modem's 81voltd dependency AND
|
# clang/libc++ C++26 modules build (see Makefile); llvm-runtimes ships the
|
||||||
# excludes the real package: 81voltd serves the modem's own ims-PDN requests,
|
# libc++ std module sources (/usr/share/libc++/v1/std.cppm) it precompiles
|
||||||
# which races imsd for the PDN and flaps it with a new prefix every ~2.5 min
|
makedepends="clang lld libc++-dev llvm-libunwind-dev llvm-runtimes glib-dev pkgconf"
|
||||||
# (fp6 journal/ims.md s57) — the two IMS stacks cannot share one PDN
|
# the versioned provides both satisfies soc-qcom-modem's 81voltd dependency
|
||||||
|
# and excludes the real package: 81voltd serves the modem's own ims-PDN
|
||||||
|
# requests, which races imsd for the PDN and flaps it with a new prefix every
|
||||||
|
# ~2.5 min — the two IMS stacks cannot share one PDN
|
||||||
provides="81voltd=$pkgver-r$pkgrel"
|
provides="81voltd=$pkgver-r$pkgrel"
|
||||||
makedepends="clang lld libc++-dev glib-dev crafter-build"
|
source="$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
|
||||||
source=""
|
builddir="$srcdir/$pkgname"
|
||||||
options="!check" # crafter-build test needs qemu for cross; run natively in CI
|
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
crafter-build
|
make
|
||||||
crafter-build -- --product=media
|
}
|
||||||
crafter-build -- --product=dialerd
|
|
||||||
|
check() {
|
||||||
|
make check
|
||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
install -Dm755 bin/imsd-*/imsd "$pkgdir"/usr/bin/imsd
|
make install DESTDIR="$pkgdir"
|
||||||
install -Dm755 bin/imsd-media-*/imsd-media "$pkgdir"/usr/libexec/imsd-media
|
|
||||||
install -Dm755 bin/imsd-dialerd-*/imsd-dialerd "$pkgdir"/usr/bin/imsd-dialerd
|
|
||||||
install -Dm755 packaging/ims-pdn-up.sh "$pkgdir"/usr/libexec/ims-pdn-up.sh
|
|
||||||
install -Dm644 packaging/imsd.service "$pkgdir"/usr/lib/systemd/system/imsd.service
|
|
||||||
install -Dm644 packaging/imsd-dialerd.desktop \
|
|
||||||
"$pkgdir"/etc/xdg/autostart/imsd-dialerd.desktop
|
|
||||||
install -Dm644 packaging/net.catcrafts.IMS1.conf \
|
|
||||||
"$pkgdir"/usr/share/dbus-1/system.d/net.catcrafts.IMS1.conf
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue