GNOME Calls 50.0 builds one origin per appearance of the modem's VoiceCallManager interface and never disconnects a removed origin's CallAdded handler, so every withdraw/re-add cycle leaves a stale handler behind: calls announced twice after one cycle, a SIGBUS on freed memory after a few (measured on a Fairphone 6). Withdrawing the interface on every imsd restart or registration drop therefore cost the only incoming call path on Phosh, where Calls runs as the session's daemon. List the interface permanently. Registration is reported through the modem's Online property and enforced in Dial, which now fails with "imsd is not registered" or "imsd is not running". Only this daemon's own restart (org.ofono vanishing) still cycles the origin, and the README says to restart Calls after that. Installing the opt-in imsd-ofono subpackage now enables imsd-ofonod (a systemd preset plus the wants symlink, like imsd.service in the main package), and imsd-dialerd's autostart is limited to KDE so a Phosh session does not run the Plasma shim. Verified on the FP6 under Phosh with GNOME Calls' autostarted daemon: outgoing call, incoming call answered on the lock screen, then an imsd restart under the running Calls (Online changes only, no origin cycle) followed by another incoming call added once and answered.
157 lines
6.2 KiB
Makefile
157 lines
6.2 KiB
Makefile
# 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,imsd-ofonod}
|
|
# make check -> build + run the 7 unit-test suites
|
|
# make install -> DESTDIR/PREFIX staged install (binaries + systemd
|
|
# units, D-Bus policies, dialerd autostart, the GNOME
|
|
# Calls plugin override, 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 $(O)/imsd-ofonod
|
|
|
|
# ---- 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 $@
|
|
|
|
$(OBJ)/ofonod.o: implementations/ofonod.cpp $(PCM)/std.pcm | $(OBJ)
|
|
$(CXX) $(ALL_CXXFLAGS) $(GIO_CFLAGS) -fprebuilt-module-path=$(PCM) \
|
|
-c $< -o $@
|
|
|
|
$(O)/imsd-ofonod: $(OBJ)/ofonod.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-ofonod $(DESTDIR)$(PREFIX)/bin/imsd-ofonod
|
|
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
|
|
install -Dm644 packaging/imsd-ofonod.service \
|
|
$(DESTDIR)$(PREFIX)/lib/systemd/system/imsd-ofonod.service
|
|
install -Dm644 packaging/org.ofono.conf \
|
|
$(DESTDIR)$(PREFIX)/share/dbus-1/system.d/imsd-ofono.conf
|
|
install -Dm644 packaging/90_imsd-ofono.gschema.override \
|
|
$(DESTDIR)$(PREFIX)/share/glib-2.0/schemas/90_imsd-ofono.gschema.override
|
|
install -Dm644 packaging/80-imsd-ofono.preset \
|
|
$(DESTDIR)$(PREFIX)/lib/systemd/system-preset/80-imsd-ofono.preset
|
|
|
|
$(PCM) $(OBJ) $(O)/tests:
|
|
mkdir -p $@
|
|
|
|
clean:
|
|
rm -rf $(O)
|
|
|
|
.PHONY: all check install clean
|