# Makefile for ft_ping # Uses build.mk generated by ./configure script # Configuration # Include generated configuration (must run ./configure first) -include build.mk # Check if build.mk exists ifeq ($(wildcard build.mk),) $(error build.mk not found. Please run './configure' first) endif # Project Configuration NAME = ft_ping TEST_BIN = ft_ping.test VERSION := 0.0.1 BUILD_DATE := $(shell git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' 2>/dev/null || date -u '+%Y-%m-%d %H:%M:%S') GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "nogit") ifeq ($(GIT_COMMIT),nogit) HAS_GIT_COMMIT=0 else HAS_GIT_COMMIT=1 endif .DEFAULT_GOAL := all MAKEFLAGS += --no-print-directory BINARIES = ft_ping # Future: BINARIES = ft_ping ft_traceroute # Include source files include sources/ping.mk SRCS = $(PING_SRCS) TESTS = $(PING_TESTS) # Get libicmp sources for dependency tracking if building locally ifeq ($(BUILD_LOCAL_LIBICMP),yes) LIBICMP_SRCS = $(shell find $(LIBICMP_DIR)/src -type f -name '*.c' 2>/dev/null) LIBICMP_HEADERS = $(wildcard $(LIBICMP_DIR)/includes/*.h) endif # Build Directories OBJ_DIR = build OBJS = $(SRCS:src/%.c=$(OBJ_DIR)/%.o) DEPS = $(OBJS:.o=.d) # Build Rules VERSION_HEADER = includes/version_gen.h $(VERSION_HEADER): FORCE @$(MAKE) --no-print-directory update-version-header .PHONY: update-version-header update-version-header: @NEW_HEADER=$$(mktemp); \ echo "/* Auto-generated - DO NOT EDIT */" > $$NEW_HEADER; \ echo "#ifndef PING_VERSION_GEN_H" >> $$NEW_HEADER; \ echo "#define PING_VERSION_GEN_H" >> $$NEW_HEADER; \ echo "#define PING_VERSION \"$(VERSION)\"" >> $$NEW_HEADER; \ echo "#define PING_BUILD_DATE \"$(BUILD_DATE)\"" >> $$NEW_HEADER; \ echo "#define PING_GIT_COMMIT \"$(GIT_COMMIT)\"" >> $$NEW_HEADER; \ echo "#define PING_HAS_GIT_COMMIT $(HAS_GIT_COMMIT)" >> $$NEW_HEADER; \ echo "" >> $$NEW_HEADER; \ echo "typedef struct s_prog_name" >> $$NEW_HEADER; \ echo "{" >> $$NEW_HEADER; \ echo " char *alloc;" >> $$NEW_HEADER; \ echo " const char *name;" >> $$NEW_HEADER; \ echo "} t_prog_name;" >> $$NEW_HEADER; \ echo "" >> $$NEW_HEADER; \ echo "extern t_prog_name g_prog_name;" >> $$NEW_HEADER; \ echo "" >> $$NEW_HEADER; \ echo "#endif" >> $$NEW_HEADER; \ if [ ! -f $(VERSION_HEADER) ] || ! cmp -s $$NEW_HEADER $(VERSION_HEADER); then \ mv $$NEW_HEADER $(VERSION_HEADER); \ echo "[OK] Version header generated"; \ else \ rm -f $$NEW_HEADER; \ fi FORCE: .PHONY: FORCE .PHONY: all all: $(LIBICMP_DEP) $(VERSION_HEADER) $(NAME) # Build local libicmp if needed ifeq ($(BUILD_LOCAL_LIBICMP),yes) $(LIBICMP_DEP): $(LIBICMP_SRCS) $(LIBICMP_HEADERS) @echo "[BUILD] Building local libicmp..." $(MAKE) -C $(LIBICMP_DIR) -f $(LIBICMP_MAKEFILE) $(LIBICMP_BUILD_FLAGS) @echo "[OK] libicmp built successfully" endif # Link ft_ping $(NAME): $(OBJS) $(LIBICMP_DEP) $(CC) -o $@ $(OBJS) $(LDFLAGS) @echo "[OK] $(NAME) built successfully" # Compile object files $(OBJ_DIR)/%.o: src/%.c @mkdir -p $(dir $@) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ # Include dependencies -include $(DEPS) # Test Rules .PHONY: test ifeq ($(ENABLE_TESTS),yes) test: $(TEST_BIN) @echo "[TEST] Running tests..." ifeq ($(SUDO_TESTS),yes) @if [ "$$(id -u)" -ne 0 ]; then \ echo "[WARN] Tests require root privileges, using sudo..."; \ sudo ./$(TEST_BIN); \ else \ ./$(TEST_BIN); \ fi else ./$(TEST_BIN) endif @echo "[OK] All tests passed" $(TEST_BIN): $(VERSION_HEADER) $(TESTS) $(filter-out $(OBJ_DIR)/ping/main.o,$(OBJS)) $(LIBICMP_DEP) @mkdir -p $(dir $@) @echo "[BUILD] Building test binary..." $(CC) $(CPPFLAGS) $(CFLAGS) $(filter-out $(VERSION_HEADER),$^) $(LDFLAGS) $(TEST_LDFLAGS) -o $@ else test: @echo "[SKIP] Tests are disabled" @echo "Run './configure --enable-tests' to enable tests" endif # Installation Rules .PHONY: install install: all @echo "[INSTALL] Installing $(NAME)..." ifeq ($(BUILD_LOCAL_LIBICMP),yes) ifeq ($(INSTALL_LIBICMP),yes) @echo "[INSTALL] Installing libicmp to $(LIBICMP_PREFIX)..." $(MAKE) -C $(LIBICMP_DIR) -f $(LIBICMP_MAKEFILE) install PREFIX=$(LIBICMP_PREFIX) @echo "[OK] libicmp installed" endif endif @echo "[INSTALL] Installing binary to $(BINDIR)..." install -d $(DESTDIR)$(BINDIR) install -m 755 $(NAME) $(DESTDIR)$(BINDIR)/$(NAME) @echo "[OK] $(NAME) installed to $(BINDIR)/$(NAME)" @echo "" @echo "Installation complete!" @echo "Run: $(BINDIR)/$(NAME)" .PHONY: uninstall uninstall: @echo "[UNINSTALL] Removing $(NAME)..." $(RM) $(DESTDIR)$(BINDIR)/$(NAME) @echo "[OK] $(NAME) removed" ifeq ($(BUILD_LOCAL_LIBICMP),yes) ifeq ($(INSTALL_LIBICMP),yes) @echo "[UNINSTALL] Removing libicmp..." $(MAKE) -C $(LIBICMP_DIR) -f $(LIBICMP_MAKEFILE) uninstall PREFIX=$(LIBICMP_PREFIX) @echo "[OK] libicmp removed" endif endif # Clean Rules .PHONY: clean clean: @echo "[CLEAN] Cleaning object files..." $(RM) $(VERSION_HEADER) $(RM) -r $(OBJ_DIR) ifeq ($(BUILD_LOCAL_LIBICMP),yes) @echo "[CLEAN] Cleaning libicmp..." $(MAKE) -C $(LIBICMP_DIR) -f $(LIBICMP_MAKEFILE) clean endif @echo "[OK] Clean complete" .PHONY: fclean fclean: clean @echo "[FCLEAN] Removing binaries..." $(RM) $(NAME) $(RM) $(TEST_BIN) ifeq ($(BUILD_LOCAL_LIBICMP),yes) @echo "[FCLEAN] Cleaning libicmp binaries..." $(MAKE) -C $(LIBICMP_DIR) -f $(LIBICMP_MAKEFILE) fclean endif @echo "[OK] Full clean complete" .PHONY: re re: fclean $(MAKE) all # Configuration Management .PHONY: reconfigure reconfigure: @echo "[INFO] Removing build.mk..." $(RM) build.mk @echo "[INFO] Please run './configure' again" .PHONY: distclean distclean: fclean @echo "[DISTCLEAN] Removing generated configuration..." $(RM) build.mk @echo "[OK] Distribution clean complete" # Information Rules .PHONY: info info: @echo "======================================" @echo "Build Configuration for $(NAME)" @echo "======================================" @echo "" @echo "libicmp:" @echo " Source: $(if $(filter yes,$(USE_SYSTEM_LIBICMP)),system,local)" @echo " Type: $(LIBICMP_TYPE)" @echo " Path: $(LIBICMP_PATH)" @echo " Build local: $(BUILD_LOCAL_LIBICMP)" @echo " Install to system: $(INSTALL_LIBICMP)" @echo "" @echo "Compiler:" @echo " CC: $(CC)" @echo " CPPFLAGS: $(CPPFLAGS)" @echo " CFLAGS: $(CFLAGS)" @echo " LDFLAGS: $(LDFLAGS)" @echo "" @echo "Build Options:" @echo " Debug: $(ENABLE_DEBUG)" @echo " Sanitizers: $(ENABLE_SANITIZERS)" @echo " LTO: $(ENABLE_LTO)" @echo " Strict: $(ENABLE_STRICT)" @echo " Tests: $(ENABLE_TESTS)" @echo "" @echo "Installation:" @echo " PREFIX: $(PREFIX)" @echo " BINDIR: $(BINDIR)" @echo " LIBDIR: $(LIBDIR)" @echo " INCLUDEDIR: $(INCLUDEDIR)" @echo "" @echo "Run './configure --help' to reconfigure" .PHONY: help help: @echo "Available targets:" @echo "" @echo " make or make all Build ft_ping" @echo " make test Run tests (if enabled)" @echo " make install Install to PREFIX ($(PREFIX))" @echo " make uninstall Uninstall from system" @echo " make clean Remove object files" @echo " make fclean Remove all built files" @echo " make re Rebuild everything" @echo " make reconfigure Remove build.mk (run ./configure again)" @echo " make distclean Full clean including build.mk" @echo " make info Show build configuration" @echo " make help Show this help" @echo "" @echo "Note: Run './configure' first to generate build.mk" # vim: tabstop=8 shiftwidth=8 noexpandtab