Makefile · 11879 bytes Raw Blame History
1 # Makefile for facsimile
2 # Detect operating system
3 UNAME_S := $(shell uname -s 2>/dev/null || echo Windows)
4 UNAME_M := $(shell uname -m 2>/dev/null || echo x86_64)
5
6 # Default compilers
7 FC = gfortran
8 CC = gcc
9
10 # Platform-specific settings
11 ifeq ($(UNAME_S),Darwin)
12 # macOS
13 ifeq ($(UNAME_M),arm64)
14 # Apple Silicon - use gfortran-15 for syntax highlighting support
15 BREW_PREFIX = /opt/homebrew
16 ifneq ($(wildcard $(BREW_PREFIX)/bin/gfortran-15),)
17 FC = $(BREW_PREFIX)/bin/gfortran-15
18 FFLAGS = -O2 -Wall -ffree-line-length-none
19 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
20 -Wimplicit-interface -fcheck=all -fbacktrace -ffree-line-length-none
21 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
22 else ifneq ($(wildcard $(BREW_PREFIX)/bin/flang-new),)
23 # Fallback to flang-new if gfortran-15 not available
24 FC = $(BREW_PREFIX)/bin/flang-new
25 # flang-new flags
26 FFLAGS = -O2
27 # Development flags (flang-new has very limited warning support)
28 # For comprehensive warnings, use gfortran instead
29 FFLAGS_DEV = -O0 -g -pedantic
30 # Debug flags with debug symbols
31 FFLAGS_DEBUG = -O0 -g
32 else
33 # Fallback to any available gfortran
34 ifneq ($(wildcard $(BREW_PREFIX)/bin/gfortran-*),)
35 FC = $(shell ls $(BREW_PREFIX)/bin/gfortran-* | head -n1)
36 endif
37 FFLAGS = -O2 -Wall -ffree-line-length-none
38 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
39 -Wimplicit-interface -fcheck=all -fbacktrace -ffree-line-length-none
40 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
41 endif
42 CFLAGS = -O2 -Wall
43 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
44 else
45 # Intel Mac
46 BREW_PREFIX = /usr/local
47 FFLAGS = -O2 -Wall -ffree-line-length-none
48 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
49 -fcheck=all -fbacktrace -ffree-line-length-none
50 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
51 CFLAGS = -O2 -Wall
52 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
53 endif
54 TARGET = fac
55 else ifneq (,$(findstring MINGW,$(UNAME_S)))
56 # Windows (MSYS2/MinGW)
57 FFLAGS = -O2 -Wall -ffree-line-length-none
58 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
59 -fcheck=all -fbacktrace -ffree-line-length-none
60 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
61 CFLAGS = -O2 -Wall
62 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
63 TARGET = fac.exe
64 else ifneq (,$(findstring MSYS,$(UNAME_S)))
65 # Windows (MSYS2)
66 FFLAGS = -O2 -Wall -ffree-line-length-none
67 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
68 -fcheck=all -fbacktrace -ffree-line-length-none
69 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
70 CFLAGS = -O2 -Wall
71 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
72 TARGET = fac.exe
73 else ifeq ($(UNAME_S),Windows)
74 # Windows (native or cross-compile)
75 FFLAGS = -O2 -Wall -ffree-line-length-none
76 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
77 -fcheck=all -fbacktrace -ffree-line-length-none
78 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace -ffree-line-length-none
79 CFLAGS = -O2 -Wall
80 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
81 TARGET = fac.exe
82 else
83 # Linux
84 FFLAGS = -O2 -Wall
85 FFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wunused-variable -Wuninitialized \
86 -fcheck=all -fbacktrace
87 FFLAGS_DEBUG = -O0 -g -fcheck=all -fbacktrace
88 CFLAGS = -O2 -Wall
89 CFLAGS_DEV = -O0 -g -Wall -Wextra -pedantic -Wconversion
90 TARGET = fac
91 endif
92
93 VERSION := $(shell cat VERSION 2>/dev/null || echo "unknown")
94
95 # Source files (order matters for dependencies)
96 SOURCES = src/version_module.f90 \
97 src/utils/platform_module.f90 \
98 src/utils/utf8_module.f90 \
99 src/utils/regex_module.f90 \
100 src/buffer/text_buffer_module.f90 \
101 src/clipboard/yank_stack_module.f90 \
102 src/clipboard/clipboard_module.f90 \
103 src/terminal/raw_mode_module.f90 \
104 src/terminal/terminal_io_module.f90 \
105 src/terminal/input_handler_module.f90 \
106 src/utils/bracket_matching_module.f90 \
107 src/navigation/jump_stack_module.f90 \
108 src/lsp/json_module.f90 \
109 src/lsp/lsp_protocol_module.f90 \
110 src/lsp/lsp_server_manager_module.f90 \
111 src/lsp/lsp_client_module.f90 \
112 src/lsp/document_sync_module.f90 \
113 src/lsp/diagnostics_module.f90 \
114 src/lsp/server_detection_module.f90 \
115 src/lsp/server_installer_module.f90 \
116 src/ui/completion_popup_module.f90 \
117 src/ui/hover_tooltip_module.f90 \
118 src/ui/diagnostics_panel_module.f90 \
119 src/ui/references_panel_module.f90 \
120 src/ui/code_actions_panel_module.f90 \
121 src/ui/symbols_panel_module.f90 \
122 src/ui/signature_tooltip_module.f90 \
123 src/ui/command_palette_module.f90 \
124 src/ui/workspace_symbols_panel_module.f90 \
125 src/ui/lsp_server_installer_panel_module.f90 \
126 src/editor_state_module.f90 \
127 src/undo/undo_stack_module.f90 \
128 src/workspace/file_tree_module.f90 \
129 src/workspace/git_ops_module.f90 \
130 src/workspace/file_tree_renderer_module.f90 \
131 src/workspace/config_module.f90 \
132 src/workspace/app_state_module.f90 \
133 src/workspace/favorites_module.f90 \
134 src/workspace/recents_module.f90 \
135 src/workspace/workspace_module.f90 \
136 src/workspace/backup_module.f90 \
137 src/syntax/syntax_highlighter_module.f90 \
138 src/ui/help_display_module.f90 \
139 src/ui/text_prompt_module.f90 \
140 src/ui/rename_prompt_module.f90 \
141 src/ui/search_prompt_module.f90 \
142 src/ui/unified_search_module.f90 \
143 src/terminal/renderer_module.f90 \
144 src/ui/replace_prompt_module.f90 \
145 src/ui/goto_prompt_module.f90 \
146 src/ui/save_prompt_module.f90 \
147 src/ui/binary_prompt_module.f90 \
148 src/fortress/filesystem/fortress_fs_module.f90 \
149 src/fortress/ui/fortress_display_module.f90 \
150 src/fortress/ui/welcome_menu_module.f90 \
151 src/fortress/fortress_navigator_module.f90 \
152 src/commands/command_handler_module.f90 \
153 app/main.f90
154
155 OBJECTS = $(SOURCES:.f90=.o)
156 C_SOURCES = src/terminal/termios_wrapper.c \
157 src/utils/regex_wrapper.c \
158 src/utils/platform_wrapper.c \
159 src/lsp/lsp_process_wrapper.c
160 C_OBJECTS = $(C_SOURCES:.c=.o)
161
162 all: $(TARGET)
163
164 # Generate version module before building
165 src/version_module.f90: VERSION
166 @echo "Generating version module..."
167 @echo "module version_module" > $@
168 @echo " implicit none" >> $@
169 @echo " character(len=*), parameter :: VERSION = '$(VERSION)'" >> $@
170 @echo "end module version_module" >> $@
171
172 $(TARGET): src/version_module.f90 $(OBJECTS) $(C_OBJECTS)
173 $(FC) $(FFLAGS) -o $(TARGET) $(OBJECTS) $(C_OBJECTS)
174
175 # Disable parallel builds to ensure correct module compilation order
176 .NOTPARALLEL:
177
178 %.o: %.f90
179 $(FC) $(FFLAGS) -c $< -o $@
180
181 %.o: %.c
182 $(CC) $(CFLAGS) -c $< -o $@
183
184 clean:
185 rm -f $(OBJECTS) $(C_OBJECTS) $(TARGET) fac fac.exe *.mod src/*/*.mod src/workspace/*.o src/utils/*.o
186
187 # Development build with comprehensive warnings
188 dev: clean
189 @echo "Building with development flags (warnings + checks)..."
190 @echo "Fortran flags: $(FFLAGS_DEV)"
191 @echo "C flags: $(CFLAGS_DEV)"
192 @echo ""
193 @$(MAKE) all FFLAGS="$(FFLAGS_DEV)" CFLAGS="$(CFLAGS_DEV)"
194
195 # Debug build with runtime checks and symbols
196 debug: clean
197 @echo "Building with debug flags (runtime checks + symbols)..."
198 @echo "Fortran flags: $(FFLAGS_DEBUG)"
199 @echo ""
200 @$(MAKE) all FFLAGS="$(FFLAGS_DEBUG)"
201
202 # Show current compiler and flags
203 info:
204 @echo "Platform: $(UNAME_S)"
205 @echo "Architecture: $(UNAME_M)"
206 @echo "Target: $(TARGET)"
207 @echo ""
208 @echo "Fortran Compiler: $(FC)"
209 @echo "Default FFLAGS: $(FFLAGS)"
210 @echo "Dev FFLAGS: $(FFLAGS_DEV)"
211 @echo "Debug FFLAGS: $(FFLAGS_DEBUG)"
212 @echo ""
213 @echo "C Compiler: $(CC)"
214 @echo "Default CFLAGS: $(CFLAGS)"
215 @echo "Dev CFLAGS: $(CFLAGS_DEV)"
216
217 # Version management targets
218 bump-patch:
219 @echo "Current version: $(VERSION)"
220 @NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1"."$$2"."$$3+1}'); \
221 echo "Bumping to: $$NEW_VERSION"; \
222 echo $$NEW_VERSION > VERSION; \
223 echo "Updated VERSION file to $$NEW_VERSION"; \
224 $(MAKE) src/version_module.f90; \
225 echo "Updated src/version_module.f90"
226 @echo "Now run: make clean && make"
227
228 bump-minor:
229 @echo "Current version: $(VERSION)"
230 @NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1"."$$2+1".0"}'); \
231 echo "Bumping to: $$NEW_VERSION"; \
232 echo $$NEW_VERSION > VERSION; \
233 echo "Updated VERSION file to $$NEW_VERSION"; \
234 $(MAKE) src/version_module.f90; \
235 echo "Updated src/version_module.f90"
236 @echo "Now run: make clean && make"
237
238 bump-major:
239 @echo "Current version: $(VERSION)"
240 @NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1+1".0.0"}'); \
241 echo "Bumping to: $$NEW_VERSION"; \
242 echo $$NEW_VERSION > VERSION; \
243 echo "Updated VERSION file to $$NEW_VERSION"; \
244 $(MAKE) src/version_module.f90; \
245 echo "Updated src/version_module.f90"
246 @echo "Now run: make clean && make"
247
248 # Show current version
249 version:
250 @echo "$(VERSION)"
251
252 # Release checklist
253 release: clean all
254 @echo ""
255 @echo "========================================"
256 @echo "Release Build Complete: v$(VERSION)"
257 @echo "========================================"
258 @echo ""
259 @./$(TARGET) --version
260 @echo ""
261 @echo "Next steps:"
262 @echo "1. Test the binary: ./$(TARGET)"
263 @echo "2. Commit changes: git add VERSION src/version_module.f90"
264 @echo "3. Commit: git commit -m 'Release v$(VERSION)'"
265 @echo "4. Tag: git tag v$(VERSION)"
266 @echo "5. Push: git push && git push --tags"
267 @echo ""
268
269 # LSP development targets
270 lsp-modules: src/lsp/json_module.o src/lsp/lsp_protocol_module.o src/lsp/lsp_server_manager_module.o src/lsp/lsp_client_module.o src/lsp/lsp_process_wrapper.o
271 @echo "LSP modules built successfully"
272
273 test-lsp: lsp-modules
274 @echo "Testing LSP JSON parser..."
275 @$(FC) $(FFLAGS_DEBUG) tests/lsp/test_json.f90 src/lsp/json_module.o -o tests/lsp/test_json 2>/dev/null && tests/lsp/test_json || true
276 @echo ""
277 @echo "Testing LSP initialization..."
278 @$(FC) $(FFLAGS_DEBUG) tests/lsp/test_lsp_init.f90 src/lsp/json_module.o src/lsp/lsp_protocol_module.o src/lsp/lsp_process_wrapper.o src/lsp/lsp_client_module.o src/lsp/lsp_server_manager_module.o -o tests/lsp/test_lsp_init 2>/dev/null && tests/lsp/test_lsp_init || true
279
280 test-lsp-editor: all
281 @echo "Testing LSP in editor with sample C file..."
282 @echo "Opening tests/lsp/sample.c - check for LSP server initialization"
283 @timeout 2 ./fac tests/lsp/sample.c < /dev/null 2>&1 | grep -q "LSP server initialized" && \
284 echo "✓ LSP server initialized for C file" || \
285 echo "✗ LSP server did not initialize (check if clangd is installed)"
286
287 clean-lsp:
288 rm -f src/lsp/*.o src/lsp/*.mod /tmp/test_json /tmp/test_lsp_init /tmp/test_lsp_raw
289
290 # Build LSP modules with debug flags for development
291 lsp-dev: clean-lsp
292 @echo "Building LSP modules with debug flags..."
293 @$(MAKE) lsp-modules FFLAGS="$(FFLAGS_DEBUG)" CFLAGS="$(CFLAGS_DEV)"
294
295 .PHONY: all clean dev debug info bump-patch bump-minor bump-major version release lsp-modules test-lsp test-lsp-editor clean-lsp lsp-dev