Makefile · 7896 bytes Raw Blame History
1 # Makefile for gitswitch-c
2 # Safe git identity switching with SSH/GPG isolation
3
4 # Project configuration
5 PROJECT_NAME = gitswitch-c
6 VERSION = 1.0.0-dev
7 TARGET = gitswitch
8
9 # Directories
10 SRCDIR = src
11 BUILDDIR = build
12 OBJDIR = $(BUILDDIR)/obj
13 BINDIR = $(BUILDDIR)/bin
14 TESTDIR = tests
15 DOCDIR = docs
16
17 # Compiler and flags
18 CC = gcc
19 CFLAGS = -std=c11 -Wall -Wextra -Wpedantic -Wstrict-prototypes \
20 -Wmissing-prototypes -Wold-style-definition -Wredundant-decls \
21 -Wbad-function-cast -Wnested-externs -Winit-self -Wlogical-op \
22 -Wshadow -Wwrite-strings -Wcast-align -Wstrict-aliasing=2 \
23 -Wmissing-include-dirs -Wdate-time -Wformat=2 -Winit-self \
24 -Wswitch-default -Wunused -Werror-implicit-function-declaration
25
26 # Security hardening flags
27 SECURITY_FLAGS_DEBUG = -fstack-protector-strong -fstack-clash-protection -fcf-protection \
28 -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack
29 SECURITY_FLAGS_RELEASE = -D_FORTIFY_SOURCE=2 -fstack-protector-strong \
30 -fstack-clash-protection -fcf-protection \
31 -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack
32
33 # Debug/Release configurations
34 DEBUG_FLAGS = -g -O0 -DDEBUG -fsanitize=address -fsanitize=undefined \
35 -fno-omit-frame-pointer -Wno-pedantic $(SECURITY_FLAGS_DEBUG)
36 RELEASE_FLAGS = -O2 -DNDEBUG -s $(SECURITY_FLAGS_RELEASE)
37
38 # Default to debug build
39 BUILD_TYPE ?= debug
40 ifeq ($(BUILD_TYPE),release)
41 CFLAGS += $(RELEASE_FLAGS)
42 else
43 CFLAGS += $(DEBUG_FLAGS)
44 endif
45
46 # Include directories
47 INCLUDES = -I$(SRCDIR)
48
49 # Libraries
50 LIBS = -lssl -lcrypto
51 # Note: TOML parsing library will be added (e.g., -ltoml or embedded parser)
52
53 # Source files (Phase 2 - Configuration Management)
54 PHASE2_SOURCES = $(SRCDIR)/main.c $(SRCDIR)/error.c $(SRCDIR)/utils.c \
55 $(SRCDIR)/display.c $(SRCDIR)/toml_parser.c $(SRCDIR)/config.c \
56 $(SRCDIR)/accounts.c
57
58 # Source files (Phase 3 - Git Operations)
59 PHASE3_SOURCES = $(PHASE2_SOURCES) $(SRCDIR)/git_ops.c
60
61 # Source files (Phase 4 - SSH Security Framework)
62 PHASE4_SOURCES = $(PHASE3_SOURCES) $(SRCDIR)/ssh_manager.c
63
64 # Source files (Phase 5 - GPG Environment Isolation)
65 PHASE5_SOURCES = $(PHASE4_SOURCES) $(SRCDIR)/gpg_manager.c
66
67 SOURCES = $(PHASE5_SOURCES)
68 OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
69 HEADERS = $(wildcard $(SRCDIR)/*.h)
70
71 # Test files
72 TEST_SOURCES = $(wildcard $(TESTDIR)/*.c)
73 TEST_OBJECTS = $(TEST_SOURCES:$(TESTDIR)/%.c=$(OBJDIR)/test_%.o)
74 TEST_TARGETS = $(TEST_SOURCES:$(TESTDIR)/%.c=$(BINDIR)/test_%)
75
76 # Default target
77 .PHONY: all
78 all: $(BINDIR)/$(TARGET)
79
80 # Create directories
81 $(OBJDIR):
82 @mkdir -p $(OBJDIR)
83
84 $(BINDIR):
85 @mkdir -p $(BINDIR)
86
87 # Compile source files
88 $(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS) | $(OBJDIR)
89 @echo "Compiling $<..."
90 $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
91
92 # Link main executable
93 $(BINDIR)/$(TARGET): $(OBJECTS) | $(BINDIR)
94 @echo "Linking $@..."
95 $(CC) $(CFLAGS) $(OBJECTS) -o $@ $(LIBS)
96 @echo "Build complete: $@"
97
98 # Install target
99 .PHONY: install
100 install: $(BINDIR)/$(TARGET)
101 @echo "Installing $(TARGET)..."
102 install -d $(DESTDIR)/usr/local/bin
103 install -m 755 $(BINDIR)/$(TARGET) $(DESTDIR)/usr/local/bin/$(TARGET)
104 @echo "Installation complete"
105
106 # Uninstall target
107 .PHONY: uninstall
108 uninstall:
109 @echo "Uninstalling $(TARGET)..."
110 rm -f $(DESTDIR)/usr/local/bin/$(TARGET)
111 @echo "Uninstall complete"
112
113 # Test compilation
114 $(OBJDIR)/test_%.o: $(TESTDIR)/%.c $(HEADERS) | $(OBJDIR)
115 @echo "Compiling test $<..."
116 $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
117
118 # Test executables (exclude main.o to avoid multiple main functions)
119 $(BINDIR)/test_%: $(OBJDIR)/test_%.o $(filter-out $(OBJDIR)/main.o,$(OBJECTS)) | $(BINDIR)
120 @echo "Linking test $@..."
121 $(CC) $(CFLAGS) $^ -o $@ $(LIBS)
122
123 # Build and run tests
124 .PHONY: test
125 test: $(TEST_TARGETS)
126 @echo "Running tests..."
127 @for test in $(TEST_TARGETS); do \
128 echo "Running $$test..."; \
129 $$test || exit 1; \
130 done
131 @echo "All tests passed!"
132
133 # Static analysis
134 .PHONY: analyze
135 analyze:
136 @echo "Running static analysis..."
137 @command -v cppcheck >/dev/null 2>&1 && \
138 cppcheck --enable=all --std=c11 --suppress=missingIncludeSystem $(SRCDIR) || \
139 echo "cppcheck not found - skipping static analysis"
140
141 # Code formatting
142 .PHONY: format
143 format:
144 @echo "Formatting code..."
145 @command -v clang-format >/dev/null 2>&1 && \
146 clang-format -i $(SOURCES) $(HEADERS) || \
147 echo "clang-format not found - skipping formatting"
148
149 # Security scan
150 .PHONY: security-scan
151 security-scan:
152 @echo "Running security scan..."
153 @command -v flawfinder >/dev/null 2>&1 && \
154 flawfinder $(SRCDIR) || \
155 echo "flawfinder not found - skipping security scan"
156
157 # Memory check (requires valgrind)
158 .PHONY: memcheck
159 memcheck: $(BINDIR)/$(TARGET)
160 @echo "Running memory check..."
161 @command -v valgrind >/dev/null 2>&1 && \
162 valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all \
163 --track-origins=yes --verbose --log-file=valgrind.log \
164 $(BINDIR)/$(TARGET) --help || \
165 echo "valgrind not found - skipping memory check"
166
167 # Documentation generation
168 .PHONY: docs
169 docs:
170 @echo "Generating documentation..."
171 @mkdir -p $(DOCDIR)
172 @command -v doxygen >/dev/null 2>&1 && \
173 doxygen Doxyfile || \
174 echo "doxygen not found - skipping documentation generation"
175
176 # Clean targets
177 .PHONY: clean
178 clean:
179 @echo "Cleaning build files..."
180 rm -rf $(BUILDDIR)
181 rm -f valgrind.log
182 rm -f *.core core.*
183
184 .PHONY: distclean
185 distclean: clean
186 @echo "Cleaning all generated files..."
187 rm -rf $(DOCDIR)
188
189 # Development helpers
190 .PHONY: debug
191 debug: BUILD_TYPE=debug
192 debug: all
193
194 .PHONY: release
195 release: BUILD_TYPE=release
196 release: all
197
198 # Quick development cycle
199 .PHONY: dev
200 dev: clean debug test
201
202 # Show build information
203 .PHONY: info
204 info:
205 @echo "Project: $(PROJECT_NAME) v$(VERSION)"
206 @echo "Target: $(TARGET)"
207 @echo "Build type: $(BUILD_TYPE)"
208 @echo "Compiler: $(CC)"
209 @echo "CFLAGS: $(CFLAGS)"
210 @echo "Sources: $(SOURCES)"
211 @echo "Objects: $(OBJECTS)"
212
213 # Dependencies check
214 .PHONY: deps
215 deps:
216 @echo "Checking dependencies..."
217 @echo "Required tools:"
218 @command -v $(CC) >/dev/null 2>&1 && echo " $(CC)" || echo " $(CC) - REQUIRED"
219 @command -v make >/dev/null 2>&1 && echo " make" || echo " make - REQUIRED"
220 @echo "Optional tools:"
221 @command -v cppcheck >/dev/null 2>&1 && echo " cppcheck" || echo " cppcheck - for static analysis"
222 @command -v clang-format >/dev/null 2>&1 && echo " clang-format" || echo " clang-format - for formatting"
223 @command -v valgrind >/dev/null 2>&1 && echo " valgrind" || echo " valgrind - for memory checking"
224 @command -v flawfinder >/dev/null 2>&1 && echo " flawfinder" || echo " flawfinder - for security scanning"
225 @command -v doxygen >/dev/null 2>&1 && echo " doxygen" || echo " doxygen - for documentation"
226
227 # Help target
228 .PHONY: help
229 help:
230 @echo "$(PROJECT_NAME) Makefile"
231 @echo ""
232 @echo "Targets:"
233 @echo " all Build the project (default)"
234 @echo " debug Build debug version"
235 @echo " release Build release version"
236 @echo " test Build and run tests"
237 @echo " install Install to system"
238 @echo " uninstall Remove from system"
239 @echo " clean Remove build files"
240 @echo " distclean Remove all generated files"
241 @echo " format Format source code"
242 @echo " analyze Run static analysis"
243 @echo " security-scan Run security scan"
244 @echo " memcheck Run memory checker"
245 @echo " docs Generate documentation"
246 @echo " deps Check dependencies"
247 @echo " info Show build information"
248 @echo " dev Quick development cycle (clean + debug + test)"
249 @echo " help Show this help"
250 @echo ""
251 @echo "Variables:"
252 @echo " BUILD_TYPE debug (default) or release"
253 @echo " CC Compiler (default: gcc)"
254 @echo " DESTDIR Installation prefix"
255
256 # Prevent make from removing intermediate files
257 .SECONDARY: $(OBJECTS) $(TEST_OBJECTS)