1
0
Fork 0
forked from hanez/xtc
xtc/Makefile

259 lines
11 KiB
Makefile

.DEFAULT_GOAL := all
CC ?= cc
CXX ?= c++
PKG_CONFIG ?= pkg-config
FLTK_CONFIG ?= fltk-config
BUILD_DIR ?= build
PREFIX ?= /usr/local
PYTHON ?= python3
VERSION := $(shell sed -n 's/^\#define XTC_VERSION_STRING "\([^"]*\)"/\1/p' include/xtc/xtc_version.h)
CFLAGS ?= -O2 -g
CFLAGS += -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude
CXXFLAGS ?= -O2 -g
CXXFLAGS += -std=c++17 -Wall -Wextra -Wpedantic -Iinclude
LDFLAGS ?=
CORE_SOURCES := src/native/native.c src/mixer/model.c src/mixer/render.c src/project/history.c src/midi/model.c src/midi/instrument.c src/audio/wave.c src/audio/arrangement.c src/audio/recorder.c src/core/xtc.c src/project/project.c src/persistence/project_file.c src/graph/graph.c src/dsp/gain.c src/engine/offline_engine.c src/engine/realtime.c src/backend/jack_backend.c
JACK_AVAILABLE := $(shell $(PKG_CONFIG) --exists jack 2>/dev/null && echo yes)
ifeq ($(JACK_AVAILABLE),yes)
JACK_CFLAGS := $(shell $(PKG_CONFIG) --cflags jack)
JACK_LIBS := $(shell $(PKG_CONFIG) --libs jack)
BACKEND_TEST := $(BUILD_DIR)/test_backend
$(BUILD_DIR)/tests/unit/test_backend.o: CPPFLAGS += $(JACK_CFLAGS)
$(BUILD_DIR)/src/backend/jack_backend.o: CPPFLAGS += -DXTC_HAVE_JACK $(JACK_CFLAGS)
endif
CORE_OBJECTS := $(CORE_SOURCES:%.c=$(BUILD_DIR)/%.o)
TEST_OBJECT := $(BUILD_DIR)/tests/unit/test_core.o
ifeq ($(shell $(PKG_CONFIG) --exists fltk 2>/dev/null && echo yes),yes)
FLTK_CXXFLAGS := $(shell $(PKG_CONFIG) --cflags fltk)
FLTK_LIBS := $(shell $(PKG_CONFIG) --libs fltk)
GUI_AVAILABLE := yes
else ifeq ($(shell $(FLTK_CONFIG) --version >/dev/null 2>&1 && echo yes),yes)
FLTK_CXXFLAGS := $(shell $(FLTK_CONFIG) --cxxflags)
FLTK_LIBS := $(shell $(FLTK_CONFIG) --ldflags)
GUI_AVAILABLE := yes
endif
.PHONY: all clean test test-jack-midi test-jack-audio test-jack test-gui test-gui-jack debug gui install
all: $(BUILD_DIR)/libxtc.a $(BUILD_DIR)/xtc-check
$(BUILD_DIR)/xtc-check: $(BUILD_DIR)/src/main.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/libxtc.a: $(CORE_OBJECTS)
@mkdir -p $(@D)
$(AR) rcsD $@ $^
$(BUILD_DIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
$(BUILD_DIR)/%.o: %.cpp
@mkdir -p $(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(FLTK_CXXFLAGS) -MMD -MP -c $< -o $@
$(TEST_OBJECT): tests/unit/test_core.c
@mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
$(BUILD_DIR)/test_core: $(TEST_OBJECT) $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $(TEST_OBJECT) $(BUILD_DIR)/libxtc.a -lm
$(BUILD_DIR)/test_offline: $(BUILD_DIR)/tests/unit/test_offline.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_realtime: $(BUILD_DIR)/tests/unit/test_realtime.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm -pthread
$(BUILD_DIR)/test_backend: $(BUILD_DIR)/tests/unit/test_backend.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_graph_edits: $(BUILD_DIR)/tests/unit/test_graph_edits.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_project: $(BUILD_DIR)/tests/unit/test_project.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_audio: $(BUILD_DIR)/tests/unit/test_audio.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm -pthread
$(BUILD_DIR)/test_midi: $(BUILD_DIR)/tests/unit/test_midi.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_mixer: $(BUILD_DIR)/tests/unit/test_mixer.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_native: $(BUILD_DIR)/tests/unit/test_native.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/native-gain: $(BUILD_DIR)/examples/native_gain.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
test: $(BUILD_DIR)/test_native $(BUILD_DIR)/native-gain $(BUILD_DIR)/test_mixer $(BUILD_DIR)/test_midi $(BUILD_DIR)/test_audio $(BUILD_DIR)/test_project $(BUILD_DIR)/test_graph_edits $(BACKEND_TEST) $(BUILD_DIR)/test_realtime $(BUILD_DIR)/test_core $(BUILD_DIR)/test_offline $(BUILD_DIR)/xtc-check
$(if $(BACKEND_TEST),./$(BACKEND_TEST),@echo "JACK fault tests skipped: JACK development files unavailable")
./$(BUILD_DIR)/test_native
./$(BUILD_DIR)/native-gain
./$(BUILD_DIR)/test_mixer
./$(BUILD_DIR)/test_midi
./$(BUILD_DIR)/test_audio
./$(BUILD_DIR)/test_project
./$(BUILD_DIR)/test_graph_edits
./$(BUILD_DIR)/test_realtime
./$(BUILD_DIR)/test_core
./$(BUILD_DIR)/test_offline
./$(BUILD_DIR)/xtc-check
debug:
$(MAKE) BUILD_DIR="$(BUILD_DIR)/debug" CFLAGS="$(CFLAGS) -O0 -g3" CXXFLAGS="$(CXXFLAGS) -O0 -g3" all test
ifeq ($(JACK_AVAILABLE),yes)
$(BUILD_DIR)/tests/integration/test_jack_midi.o: CPPFLAGS += $(JACK_CFLAGS)
$(BUILD_DIR)/test_jack_midi: $(BUILD_DIR)/tests/integration/test_jack_midi.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm
test-jack-midi: $(BUILD_DIR)/test_jack_midi
./$(BUILD_DIR)/test_jack_midi
$(BUILD_DIR)/tests/integration/test_jack_audio.o: CPPFLAGS += $(JACK_CFLAGS)
$(BUILD_DIR)/test_jack_audio: $(BUILD_DIR)/tests/integration/test_jack_audio.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm
test-jack-audio: $(BUILD_DIR)/test_jack_audio
./$(BUILD_DIR)/test_jack_audio
$(BUILD_DIR)/tests/integration/test_jack.o: CPPFLAGS += $(JACK_CFLAGS)
$(BUILD_DIR)/test_jack: $(BUILD_DIR)/tests/integration/test_jack.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm
test-jack: $(BUILD_DIR)/test_jack
./$(BUILD_DIR)/test_jack
else
test-jack-midi test-jack-audio test-jack:
@echo "JACK development files are required for the live integration test."
@exit 1
endif
ifeq ($(GUI_AVAILABLE),yes)
gui: $(BUILD_DIR)/xtc
$(BUILD_DIR)/test_gui: $(BUILD_DIR)/tests/integration/test_gui.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/libxtc.a
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) -lm
test-gui: $(BUILD_DIR)/test_gui
xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
ifeq ($(JACK_AVAILABLE),yes)
$(BUILD_DIR)/test_gui_jack: $(BUILD_DIR)/tests/integration/test_gui_jack.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/libxtc.a
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm
test-gui-jack: $(BUILD_DIR)/test_gui_jack
xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui_jack
else
test-gui-jack:
@echo "JACK development files are required for the live GUI test."
@exit 1
endif
$(BUILD_DIR)/xtc: $(BUILD_DIR)/src/gui/main.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/libxtc.a
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm
else
test-gui-jack test-gui:
@echo "FLTK development files are required for GUI tests."
@exit 1
gui:
@echo "FLTK was not found by pkg-config or fltk-config. GUI requires FLTK development files."
@exit 1
endif
# install retains the core-only behavior; install-gui adds the application.
.PHONY: install uninstall install-gui dist release test-install test-release test-performance
$(BUILD_DIR)/xtc.pc: packaging/xtc.pc.in tools/pkgconfig.py tools/dist.py include/xtc/xtc_version.h FORCE
$(PYTHON) tools/pkgconfig.py --prefix "$(PREFIX)" --jack "$(if $(JACK_AVAILABLE),jack)" --output "$@"
.PHONY: FORCE
FORCE:
install: all $(BUILD_DIR)/xtc.pc
install -d "$(DESTDIR)$(PREFIX)/include/xtc" "$(DESTDIR)$(PREFIX)/lib/pkgconfig" "$(DESTDIR)$(PREFIX)/bin" "$(DESTDIR)$(PREFIX)/share/doc/xtc/decisions" "$(DESTDIR)$(PREFIX)/share/licenses/xtc"
install -m 0644 include/xtc/*.h "$(DESTDIR)$(PREFIX)/include/xtc/"
install -m 0644 "$(BUILD_DIR)/libxtc.a" "$(DESTDIR)$(PREFIX)/lib/"
install -m 0644 "$(BUILD_DIR)/xtc.pc" "$(DESTDIR)$(PREFIX)/lib/pkgconfig/"
install -m 0755 "$(BUILD_DIR)/xtc-check" "$(DESTDIR)$(PREFIX)/bin/"
install -m 0644 README.md docs/*.md "$(DESTDIR)$(PREFIX)/share/doc/xtc/"
install -m 0644 docs/decisions/*.md "$(DESTDIR)$(PREFIX)/share/doc/xtc/decisions/"
install -m 0644 LICENSE "$(DESTDIR)$(PREFIX)/share/licenses/xtc/"
install-gui: install gui
install -d "$(DESTDIR)$(PREFIX)/share/applications"
install -m 0755 "$(BUILD_DIR)/xtc" "$(DESTDIR)$(PREFIX)/bin/"
install -m 0644 packaging/xtc.desktop "$(DESTDIR)$(PREFIX)/share/applications/"
uninstall:
$(PYTHON) tools/uninstall.py --root "$(DESTDIR)$(PREFIX)"
dist:
$(PYTHON) tools/dist.py --output "$(BUILD_DIR)/xtc-$(VERSION).tar.gz"
release:
$(MAKE) BUILD_DIR="$(BUILD_DIR)/release" CFLAGS="-O2 -g0 -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -ffile-prefix-map=$(CURDIR)=." CXXFLAGS="-O2 -g0 -std=c++17 -Wall -Wextra -Wpedantic -Iinclude -ffile-prefix-map=$(CURDIR)=." FLTK_CXXFLAGS="$(filter -I% -D% -pthread,$(FLTK_CXXFLAGS))" all test $(if $(GUI_AVAILABLE),gui)
test-install: all $(if $(GUI_AVAILABLE),gui)
$(PYTHON) tests/integration/test_install.py --build-dir "$(abspath $(BUILD_DIR))" $(if $(GUI_AVAILABLE),--gui)
test-release: dist
$(PYTHON) tests/integration/test_release.py "$(BUILD_DIR)/xtc-$(VERSION).tar.gz" $(if $(GUI_AVAILABLE),--gui)
clean:
rm -rf "$(BUILD_DIR)"
-include $(CORE_OBJECTS:.o=.d) $(TEST_OBJECT:.o=.d) $(BUILD_DIR)/src/main.d $(BUILD_DIR)/tests/unit/test_offline.d $(BUILD_DIR)/tests/unit/test_realtime.d $(BUILD_DIR)/tests/unit/test_backend.d $(BUILD_DIR)/tests/unit/test_graph_edits.d \
$(BUILD_DIR)/src/gui/main.d $(BUILD_DIR)/src/gui/main_window.d $(BUILD_DIR)/src/gui/graph_widget.d $(BUILD_DIR)/src/gui/sequencer_widget.d $(BUILD_DIR)/src/gui/piano_roll.d $(BUILD_DIR)/tests/integration/test_jack.d $(BUILD_DIR)/tests/integration/test_gui.d $(BUILD_DIR)/tests/integration/test_gui_jack.d
-include $(BUILD_DIR)/tests/unit/test_project.d
-include $(BUILD_DIR)/tests/unit/test_audio.d
-include $(BUILD_DIR)/tests/integration/test_jack_audio.d
-include $(BUILD_DIR)/tests/unit/test_midi.d
-include $(BUILD_DIR)/tests/integration/test_jack_midi.d
-include $(BUILD_DIR)/src/gui/mixer_widget.d
-include $(BUILD_DIR)/tests/unit/test_mixer.d
-include $(BUILD_DIR)/tests/unit/test_native.d $(BUILD_DIR)/examples/native_gain.d
$(BUILD_DIR)/test_performance: $(BUILD_DIR)/tests/integration/test_performance.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
$(BUILD_DIR)/test_recovery: $(BUILD_DIR)/tests/integration/test_recovery.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm
.PHONY: test-recovery
test-performance: $(BUILD_DIR)/test_performance
./$(BUILD_DIR)/test_performance
test-recovery: $(BUILD_DIR)/test_recovery
./$(BUILD_DIR)/test_recovery
-include $(BUILD_DIR)/tests/integration/test_performance.d $(BUILD_DIR)/tests/integration/test_recovery.d
# Linux/GNU-compatible linker test; no instrumentation in production objects.
$(BUILD_DIR)/test_reliability: $(BUILD_DIR)/tests/integration/test_reliability.o $(BUILD_DIR)/libxtc.a
$(CC) $(LDFLAGS) -o $@ $^ -lm -Wl,--wrap=malloc,--wrap=calloc,--wrap=realloc,--wrap=free
.PHONY: test-reliability test-sanitize analyze
test-reliability: test $(BUILD_DIR)/test_reliability
./$(BUILD_DIR)/test_reliability
test-sanitize:
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 UBSAN_OPTIONS=halt_on_error=1 $(MAKE) BUILD_DIR="$(BUILD_DIR)/sanitize" CC=clang CFLAGS="-O1 -g -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -fsanitize=address,undefined -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address,undefined" test-reliability test-recovery
analyze:
$(PYTHON) tools/analyze.py $(CORE_SOURCES)
-include $(BUILD_DIR)/tests/integration/test_reliability.d