PROJECT_NAME = chroma VERSION = 1.0.1 # Directories SRCDIR = src INCDIR = include OBJDIR = obj BINDIR = bin SYSTEMD_DIR = systemd PROTOCOLDIR = protocols # Install directories PREFIX ?= /usr/local BINDIR_INSTALL = $(PREFIX)/bin SYSTEMD_INSTALL = $(HOME)/.config/systemd/user # Compiler and flags CC = gcc CFLAGS = -std=c11 -Wall -Wextra -Werror -pedantic -O2 -g CFLAGS += -D_GNU_SOURCE -DCHROMA_VERSION=\"$(VERSION)\" CPPFLAGS = -I$(INCDIR) # Debug build flags DEBUG_CFLAGS = -std=c11 -Wall -Wextra -Werror -pedantic -Og -g3 -DDEBUG DEBUG_CFLAGS += -D_GNU_SOURCE -DCHROMA_VERSION=\"$(VERSION)-debug\" DEBUG_CFLAGS += -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer # Libraries using pkg-config PKG_DEPS = wayland-client wayland-egl egl glesv2 wayland-protocols CFLAGS += $(shell pkg-config --cflags $(PKG_DEPS)) LDFLAGS += $(shell pkg-config --libs $(PKG_DEPS)) # Protocol files PROTOCOL_XML = $(PROTOCOLDIR)/xdg-shell.xml $(PROTOCOLDIR)/wlr-layer-shell-unstable-v1.xml PROTOCOL_HEADERS = $(PROTOCOL_XML:$(PROTOCOLDIR)/%.xml=$(INCDIR)/%.h) PROTOCOL_SOURCES = $(PROTOCOL_XML:$(PROTOCOLDIR)/%.xml=$(SRCDIR)/%.c) PROTOCOL_OBJECTS = $(PROTOCOL_SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) # Additional libraries LDFLAGS += -lm -ldl # Source files (excluding generated protocol files) SOURCES = $(filter-out $(PROTOCOL_SOURCES), $(wildcard $(SRCDIR)/*.c)) OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(PROTOCOL_OBJECTS) DEPENDS = $(OBJECTS:.o=.d) # Default target TARGET = $(BINDIR)/$(PROJECT_NAME) all: $(TARGET) # Create directories $(OBJDIR): @mkdir -p $(OBJDIR) $(BINDIR): @mkdir -p $(BINDIR) # Protocol generation $(INCDIR)/%.h: $(PROTOCOLDIR)/%.xml | $(INCDIR) @echo " PROTO $<" @wayland-scanner client-header $< $@ $(SRCDIR)/%.c: $(PROTOCOLDIR)/%.xml @echo " PROTO $<" @wayland-scanner private-code $< $@ # Make sure include directory exists $(INCDIR): @mkdir -p $(INCDIR) # Build main executable $(TARGET): version-header $(PROTOCOL_HEADERS) $(OBJECTS) | $(BINDIR) @echo " LINK $@" @$(CC) $(OBJECTS) -o $@ $(LDFLAGS) # Compile source files $(OBJDIR)/%.o: $(SRCDIR)/%.c $(PROTOCOL_HEADERS) | $(OBJDIR) @echo " CC $<" @$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ # Debug build debug: CFLAGS = $(DEBUG_CFLAGS) debug: $(TARGET) # Static build (for distribution) static: LDFLAGS += -static static: $(TARGET) # Check if required dependencies are available check-deps: @echo "Checking dependencies..." @pkg-config --exists $(PKG_DEPS) || (echo "Missing dependencies. Install: wayland-protocols libwayland-dev libegl1-mesa-dev libgl1-mesa-dev wayland-scanner" && exit 1) @which wayland-scanner >/dev/null || (echo "wayland-scanner not found. Please install wayland-scanner." && exit 1) @echo "All dependencies found." # Install install: $(TARGET) @echo "Installing $(PROJECT_NAME)..." install -Dm755 $(TARGET) $(DESTDIR)$(BINDIR_INSTALL)/$(PROJECT_NAME) @if [ -f $(SYSTEMD_DIR)/$(PROJECT_NAME).service ]; then \ echo "Installing systemd service..."; \ install -Dm644 $(SYSTEMD_DIR)/$(PROJECT_NAME).service $(DESTDIR)$(SYSTEMD_INSTALL)/$(PROJECT_NAME).service; \ fi @echo "Installation complete." # Uninstall uninstall: @echo "Uninstalling $(PROJECT_NAME)..." rm -f $(DESTDIR)$(BINDIR_INSTALL)/$(PROJECT_NAME) rm -f $(DESTDIR)$(SYSTEMD_INSTALL)/$(PROJECT_NAME).service @echo "Uninstall complete." # Create version header version-header: @echo "Generating version header..." @echo "#ifndef CHROMA_VERSION_H" > $(INCDIR)/chroma_version.h @echo "#define CHROMA_VERSION_H" >> $(INCDIR)/chroma_version.h @echo "" >> $(INCDIR)/chroma_version.h @echo "#define CHROMA_VERSION \"$(VERSION)\"" >> $(INCDIR)/chroma_version.h @echo "" >> $(INCDIR)/chroma_version.h @echo "#endif // CHROMA_VERSION_H" >> $(INCDIR)/chroma_version.h # Create systemd service file systemd-service: $(SYSTEMD_DIR)/$(PROJECT_NAME).service # Clean build artifacts clean: @echo "Cleaning build artifacts..." rm -rf $(OBJDIR) $(BINDIR) rm -f $(PROTOCOL_HEADERS) $(PROTOCOL_SOURCES) # Format source code (requires clang-format) format: @echo "Formatting source code..." @find $(SRCDIR) $(INCDIR) -name "*.c" -o -name "*.h" | xargs clang-format -i # Static analysis (requires cppcheck) analyze: @echo "Running static analysis..." @cppcheck --enable=all --std=c11 --language=c \ --include=$(INCDIR) \ --suppress=missingIncludeSystem \ --quiet \ $(SRCDIR) # Run tests # FIXME: add tests test: $(TARGET) @echo "Running tests..." @echo "Tests not implemented yet." # Version management targets bump-patch: @echo "Bumping patch version..." @$(eval NEW_VERSION := $(shell echo $(VERSION) | awk -F. '{print $$1"."$$2"."$$3+1}')) @sed -i 's/^VERSION = .*/VERSION = $(NEW_VERSION)/' Makefile @echo "Version bumped to $(NEW_VERSION)" bump-minor: @echo "Bumping minor version..." @$(eval NEW_VERSION := $(shell echo $(VERSION) | awk -F. '{print $$1"."$$2+1".0"}')) @sed -i 's/^VERSION = .*/VERSION = $(NEW_VERSION)/' Makefile @echo "Version bumped to $(NEW_VERSION)" bump-major: @echo "Bumping major version..." @$(eval NEW_VERSION := $(shell echo $(VERSION) | awk -F. '{print $$1+1".0.0"}')) @sed -i 's/^VERSION = .*/VERSION = $(NEW_VERSION)/' Makefile @echo "Version bumped to $(NEW_VERSION)" set-version: @if [ -z "$(NEW_VER)" ]; then \ echo "Usage: make set-version NEW_VER=X.Y.Z"; \ exit 1; \ fi @echo "Setting version to $(NEW_VER)..." @sed -i 's/^VERSION = .*/VERSION = $(NEW_VER)/' Makefile @echo "Version set to $(NEW_VER)" # Help target help: @echo "Available targets:" @echo " all - Build main executable (default)" @echo " debug - Build with debug symbols and sanitizers" @echo " static - Build statically linked executable" @echo " check-deps - Check if all dependencies are available" @echo " install - Install executable and systemd service" @echo " uninstall - Remove installed files" @echo " clean - Remove build artifacts" @echo " distclean - Remove all generated files" @echo " format - Format source code (requires clang-format)" @echo " analyze - Run static analysis (requires cppcheck)" @echo " test - Run tests" @echo " version-header - Generate version header from Makefile" @echo " bump-patch - Increment patch version (X.Y.Z+1)" @echo " bump-minor - Increment minor version (X.Y+1.0)" @echo " bump-major - Increment major version (X+1.0.0)" @echo " set-version - Set specific version (use NEW_VER=X.Y.Z)" @echo " help - Show this help message" @echo "" @echo "Examples:" @echo " make # Build with default settings" @echo " make debug # Build debug version" @echo " make PREFIX=/usr install # Install to /usr instead of /usr/local" @echo " make CC=clang # Use clang instead of gcc" @echo " make bump-patch # Bump to 1.0.2" @echo " make set-version NEW_VER=2.0.0 # Set to 2.0.0" # Include dependency files -include $(DEPENDS) # Phony targets .PHONY: all debug static check-deps install uninstall systemd-service version-header sample-config clean distclean format analyze test help bump-patch bump-minor bump-major set-version # Print variables print-%: @echo '$*=$($*)'