Makefile · 35870 bytes Raw Blame History
1 # Fortran Shell (Fortsh) Makefile
2 # ====================================
3
4 # Compiler settings
5 # Use LLVM Flang on macOS ARM64 for better stability
6 UNAME_S := $(shell uname -s)
7 UNAME_M := $(shell uname -m)
8
9 ifeq ($(UNAME_S),Darwin)
10 ifeq ($(UNAME_M),arm64)
11 # macOS ARM64: Use LLVM Flang for better stability
12 FC = flang-new
13 PLATFORM_FLAGS = -D__APPLE__ -cpp
14 $(info Using flang-new on macOS ARM64)
15 else
16 # macOS Intel: Use gfortran with fixes
17 FC = gfortran
18 PLATFORM_FLAGS = -D__APPLE__ -cpp -frecursive
19 $(info Using gfortran on macOS Intel)
20 endif
21 else
22 # Linux: Use gfortran
23 FC = gfortran
24 ifeq ($(UNAME_M),aarch64)
25 PLATFORM_FLAGS = -cpp -DUSE_C_STAT
26 $(info Using gfortran on Linux aarch64 — C stat helpers enabled)
27 else
28 PLATFORM_FLAGS = -cpp
29 $(info Using gfortran on Linux)
30 endif
31 endif
32
33 # Memory pooling (enabled by default, set NO_MEMPOOL=1 to disable)
34 ifeq ($(NO_MEMPOOL),1)
35 POOL_FLAGS =
36 $(info Memory pooling DISABLED - using standard allocation)
37 else
38 POOL_FLAGS = -DUSE_MEMORY_POOL
39 ifeq ($(MEMPOOL_DEBUG),1)
40 POOL_FLAGS += -DMEMPOOL_DEBUG
41 $(info Memory pooling ENABLED with DEBUG output - using zero-copy string pool)
42 else
43 $(info Memory pooling ENABLED - using zero-copy string pool [DEFAULT])
44 endif
45 endif
46
47 # C compiler for string operations library
48 CC = gcc
49 # Note: Don't use $(PLATFORM_FLAGS) here - it contains Fortran flags like -cpp
50 ifeq ($(UNAME_S),Darwin)
51 CFLAGS = -Wall -Wextra -fPIC -g -O2 -D__APPLE__
52 else
53 CFLAGS = -Wall -Wextra -fPIC -g -O2
54 endif
55
56 # Warning flags and intrinsics (flang-new doesn't support -Wall/-Wextra/-fall-intrinsics)
57 ifeq ($(FC),flang-new)
58 WARN_FLAGS =
59 WARN_FLAGS_RELEASE =
60 # flang-new supports F2018 flush() natively; -fall-intrinsics is gfortran-only
61 INTRINSICS_FLAG =
62 else
63 WARN_FLAGS = -Wall -Wextra
64 WARN_FLAGS_RELEASE = -Wall -Wno-unused-variable -Wno-unused-dummy-argument -Wno-maybe-uninitialized -Wno-function-elimination -Wno-surprising -Wno-character-truncation
65 # -fall-intrinsics allows GNU extensions like flush() with -std=f2018
66 INTRINSICS_FLAG = -fall-intrinsics
67 endif
68
69 # Development flags (verbose warnings, debug symbols)
70 FCFLAGS = $(WARN_FLAGS) -std=f2018 $(INTRINSICS_FLAG) -fPIC -g -O0 $(PLATFORM_FLAGS) $(POOL_FLAGS)
71 # Production flags (minimal warnings, optimized, no debug symbols)
72 FCFLAGS_RELEASE = $(WARN_FLAGS_RELEASE) -std=f2018 $(INTRINSICS_FLAG) -fPIC -O2 $(PLATFORM_FLAGS) $(POOL_FLAGS)
73
74 # C string library (flang-new workaround for allocatable heap corruption)
75 # Auto-enable when using flang-new on any platform (macOS ARM64, Asahi Linux, etc.)
76 # Force override: USE_C_STRINGS=1 make or NO_C_STRINGS=1 make
77 ifeq ($(NO_C_STRINGS),1)
78 USE_C_STRINGS = 0
79 else ifeq ($(FC),flang-new)
80 USE_C_STRINGS = 1
81 else ifeq ($(UNAME_S),Darwin)
82 ifeq ($(UNAME_M),arm64)
83 USE_C_STRINGS = 1
84 endif
85 endif
86
87 # Core C objects needed on all platforms (fd operations, terminal size, string ops)
88 CORE_C_OBJS = $(BUILDDIR)/c_interop/fd_wrapper.o $(BUILDDIR)/c_interop/terminal_size.o $(BUILDDIR)/c_interop/fortsh_strings.o
89
90 ifeq ($(USE_C_STRINGS),1)
91 C_STRING_LIB = $(BUILDDIR)/c_interop/libfortsh_strings.a
92 C_STRING_OBJ = $(BUILDDIR)/c_interop/fortsh_c_strings.o
93 C_STRING_FLAGS = -DUSE_C_STRINGS
94 LDFLAGS = $(C_STRING_LIB)
95 FCFLAGS += $(C_STRING_FLAGS)
96 FCFLAGS_RELEASE += $(C_STRING_FLAGS)
97 $(info C string library ENABLED - workaround for flang-new >128 byte bug)
98 else
99 C_STRING_LIB =
100 C_STRING_OBJ =
101 C_STRING_FLAGS =
102 LDFLAGS =
103 $(info C string library DISABLED - using native Fortran strings)
104 endif
105
106 # Directory structure
107 SRCDIR = src
108 BUILDDIR = build
109 BINDIR = bin
110
111 # Conditionally add string pool and memory dashboard (included by default)
112 ifeq ($(NO_MEMPOOL),1)
113 POOL_OBJECTS =
114 else
115 POOL_OBJECTS = $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o
116 endif
117
118 # Object files with explicit dependencies
119 # All module dependencies are properly declared in the rules below,
120 # so parallel builds work correctly
121 OBJECTS = $(BUILDDIR)/common/types.o \
122 $(BUILDDIR)/common/version.o \
123 $(BUILDDIR)/common/error_handling.o \
124 $(BUILDDIR)/common/performance.o \
125 $(POOL_OBJECTS) \
126 $(BUILDDIR)/common/buffer_ops.o \
127 $(BUILDDIR)/system/interface.o \
128 $(BUILDDIR)/common/io_helpers.o \
129 $(BUILDDIR)/system/signals.o \
130 $(BUILDDIR)/system/signal_handling.o \
131 $(BUILDDIR)/parsing/glob.o \
132 $(BUILDDIR)/scripting/variables.o \
133 $(BUILDDIR)/execution/jobs.o \
134 $(BUILDDIR)/scripting/test_builtin.o \
135 $(BUILDDIR)/scripting/advanced_test.o \
136 $(BUILDDIR)/scripting/printf_builtin.o \
137 $(BUILDDIR)/scripting/read_builtin.o \
138 $(BUILDDIR)/scripting/getopts_builtin.o \
139 $(BUILDDIR)/scripting/directory_builtin.o \
140 $(BUILDDIR)/scripting/command_builtin.o \
141 $(BUILDDIR)/scripting/prompt_formatting.o \
142 $(BUILDDIR)/scripting/config.o \
143 $(BUILDDIR)/scripting/aliases.o \
144 $(BUILDDIR)/scripting/abbreviations.o \
145 $(BUILDDIR)/io/syntax_highlight.o \
146 $(BUILDDIR)/execution/coprocess.o \
147 $(BUILDDIR)/execution/better_errors.o \
148 $(BUILDDIR)/io/heredoc.o \
149 $(BUILDDIR)/io/fd_redirection.o \
150 $(BUILDDIR)/scripting/control_flow.o \
151 $(BUILDDIR)/parsing/lexer.o \
152 $(BUILDDIR)/parsing/command_tree.o \
153 $(BUILDDIR)/parsing/grammar_parser.o \
154 $(BUILDDIR)/parsing/parser.o \
155 $(BUILDDIR)/scripting/completion.o \
156 $(BUILDDIR)/execution/builtin_help_texts.o \
157 $(BUILDDIR)/execution/builtin_interface.o \
158 $(BUILDDIR)/execution/trap_dispatch.o \
159 $(BUILDDIR)/execution/pipeline_helpers.o \
160 $(BUILDDIR)/execution/executor.o \
161 $(BUILDDIR)/execution/ast_executor.o \
162 $(BUILDDIR)/execution/eval_builtin.o \
163 $(BUILDDIR)/execution/builtins.o \
164 $(BUILDDIR)/execution/command_capture.o \
165 $(BUILDDIR)/execution/command_capture_callback.o \
166 $(BUILDDIR)/scripting/expansion.o \
167 $(BUILDDIR)/scripting/substitution.o \
168 $(BUILDDIR)/io/suggestions.o \
169 $(BUILDDIR)/io/readline.o \
170 $(BUILDDIR)/scripting/shell_options.o \
171 $(BUILDDIR)/fortsh.o
172
173 # Target executable
174 TARGET = $(BINDIR)/fortsh
175
176 # Default target
177 all: $(TARGET)
178
179 # Create directories
180 $(BUILDDIR) $(BINDIR):
181 mkdir -p $@
182
183 $(BUILDDIR)/common $(BUILDDIR)/system $(BUILDDIR)/parsing $(BUILDDIR)/execution $(BUILDDIR)/scripting $(BUILDDIR)/io $(BUILDDIR)/c_interop: | $(BUILDDIR)
184 mkdir -p $@
185
186 # Build target
187 $(TARGET): $(OBJECTS) $(CORE_C_OBJS) $(C_STRING_OBJ) $(C_STRING_LIB) | $(BINDIR)
188 $(FC) $(C_STRING_OBJ) $(CORE_C_OBJS) $(OBJECTS) -o $@ $(LDFLAGS)
189 @echo "Fortsh built successfully!"
190
191 # Individual compilation rules with proper dependencies
192 $(BUILDDIR)/common/types.o: src/common/types.f90 | $(BUILDDIR)/common
193 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
194
195 $(BUILDDIR)/common/version.o: src/common/version.f90 | $(BUILDDIR)/common
196 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
197
198 $(BUILDDIR)/common/error_handling.o: src/common/error_handling.f90 | $(BUILDDIR)/common
199 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
200
201 $(BUILDDIR)/common/performance.o: src/common/performance.f90 | $(BUILDDIR)/common
202 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
203
204 # String pool (included by default unless NO_MEMPOOL=1)
205 $(BUILDDIR)/common/string_pool.o: src/common/string_pool.f90 | $(BUILDDIR)/common
206 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
207
208 # Memory dashboard (included by default unless NO_MEMPOOL=1)
209 $(BUILDDIR)/common/memory_dashboard.o: src/common/memory_dashboard.f90 $(BUILDDIR)/common/string_pool.o | $(BUILDDIR)/common
210 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
211
212 # Buffer operations abstraction (depends on C strings if enabled)
213 $(BUILDDIR)/common/buffer_ops.o: src/common/buffer_ops.f90 $(C_STRING_OBJ) | $(BUILDDIR)/common
214 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
215
216 $(BUILDDIR)/system/interface.o: src/system/interface.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/system
217 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
218
219 $(BUILDDIR)/common/io_helpers.o: src/common/io_helpers.f90 $(BUILDDIR)/system/interface.o | $(BUILDDIR)/common
220 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
221
222 $(BUILDDIR)/system/signals.o: src/system/signals.f90 $(BUILDDIR)/system/interface.o | $(BUILDDIR)/system
223 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
224
225 $(BUILDDIR)/system/signal_handling.o: src/system/signal_handling.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/system
226 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
227
228 $(BUILDDIR)/parsing/glob.o: src/parsing/glob.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/performance.o $(BUILDDIR)/system/interface.o | $(BUILDDIR)/parsing
229 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
230
231 $(BUILDDIR)/parsing/parser.o: src/parsing/parser.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/error_handling.o $(BUILDDIR)/common/performance.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/parsing/glob.o $(BUILDDIR)/scripting/substitution.o $(BUILDDIR)/scripting/expansion.o $(BUILDDIR)/parsing/lexer.o | $(BUILDDIR)/parsing
232 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
233
234 $(BUILDDIR)/parsing/lexer.o: src/parsing/lexer.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/parsing
235 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
236
237 $(BUILDDIR)/parsing/command_tree.o: src/parsing/command_tree.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/parsing
238 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
239
240 $(BUILDDIR)/parsing/grammar_parser.o: src/parsing/grammar_parser.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/parsing/lexer.o $(BUILDDIR)/parsing/parser.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/parsing
241 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
242
243 $(BUILDDIR)/execution/jobs.o: src/execution/jobs.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o | $(BUILDDIR)/execution
244 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
245
246 $(BUILDDIR)/scripting/control_flow.o: src/scripting/control_flow.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/expansion.o $(BUILDDIR)/scripting/advanced_test.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/scripting/test_builtin.o $(BUILDDIR)/scripting/substitution.o | $(BUILDDIR)/scripting
247 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
248
249 $(BUILDDIR)/execution/builtin_help_texts.o: src/execution/builtin_help_texts.f90 | $(BUILDDIR)/execution
250 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
251
252 $(BUILDDIR)/execution/builtin_interface.o: src/execution/builtin_interface.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/execution
253 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
254
255 $(BUILDDIR)/execution/builtins.o: src/execution/builtins.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/performance.o $(BUILDDIR)/common/io_helpers.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/system/signal_handling.o $(BUILDDIR)/execution/jobs.o $(BUILDDIR)/scripting/test_builtin.o $(BUILDDIR)/io/readline.o $(BUILDDIR)/scripting/config.o $(BUILDDIR)/scripting/aliases.o $(BUILDDIR)/scripting/shell_options.o $(BUILDDIR)/execution/coprocess.o $(BUILDDIR)/scripting/command_builtin.o $(BUILDDIR)/scripting/directory_builtin.o $(BUILDDIR)/scripting/getopts_builtin.o $(BUILDDIR)/scripting/printf_builtin.o $(BUILDDIR)/scripting/read_builtin.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/execution/builtin_interface.o $(BUILDDIR)/execution/builtin_help_texts.o $(BUILDDIR)/execution/eval_builtin.o $(BUILDDIR)/parsing/parser.o $(BUILDDIR)/system/signal_handling.o | $(BUILDDIR)/execution
256 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
257
258 $(BUILDDIR)/execution/trap_dispatch.o: src/execution/trap_dispatch.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/execution
259 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
260
261 $(BUILDDIR)/execution/pipeline_helpers.o: src/execution/pipeline_helpers.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/parsing/parser.o $(BUILDDIR)/parsing/glob.o $(BUILDDIR)/scripting/expansion.o | $(BUILDDIR)/execution
262 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
263
264 $(BUILDDIR)/execution/executor.o: src/execution/executor.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/error_handling.o $(BUILDDIR)/common/performance.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/execution/jobs.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/scripting/control_flow.o $(BUILDDIR)/execution/builtin_interface.o $(BUILDDIR)/parsing/parser.o $(BUILDDIR)/parsing/grammar_parser.o $(BUILDDIR)/parsing/command_tree.o $(BUILDDIR)/execution/trap_dispatch.o $(BUILDDIR)/scripting/shell_options.o $(BUILDDIR)/scripting/aliases.o $(BUILDDIR)/execution/better_errors.o $(BUILDDIR)/system/signal_handling.o $(BUILDDIR)/execution/pipeline_helpers.o | $(BUILDDIR)/execution
265 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
266
267 $(BUILDDIR)/execution/ast_executor.o: src/execution/ast_executor.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/parsing/command_tree.o $(BUILDDIR)/execution/executor.o $(BUILDDIR)/execution/pipeline_helpers.o $(BUILDDIR)/execution/trap_dispatch.o $(BUILDDIR)/io/fd_redirection.o $(BUILDDIR)/parsing/grammar_parser.o $(BUILDDIR)/execution/coprocess.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/execution
268 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
269
270 $(BUILDDIR)/execution/eval_builtin.o: src/execution/eval_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/parsing/grammar_parser.o $(BUILDDIR)/parsing/command_tree.o $(BUILDDIR)/execution/ast_executor.o | $(BUILDDIR)/execution
271 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
272
273 $(BUILDDIR)/execution/command_capture.o: src/execution/command_capture.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o | $(BUILDDIR)/execution
274 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
275
276 $(BUILDDIR)/execution/command_capture_callback.o: src/execution/command_capture_callback.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/parsing/grammar_parser.o $(BUILDDIR)/execution/ast_executor.o $(BUILDDIR)/parsing/command_tree.o $(BUILDDIR)/execution/command_capture.o | $(BUILDDIR)/execution
277 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
278
279 $(BUILDDIR)/scripting/test_builtin.o: src/scripting/test_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/scripting/advanced_test.o | $(BUILDDIR)/scripting
280 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
281
282 $(BUILDDIR)/scripting/advanced_test.o: src/scripting/advanced_test.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/system/interface.o | $(BUILDDIR)/scripting
283 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
284
285 $(BUILDDIR)/scripting/printf_builtin.o: src/scripting/printf_builtin.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/scripting
286 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
287
288 $(BUILDDIR)/scripting/read_builtin.o: src/scripting/read_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o | $(BUILDDIR)/scripting
289 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
290
291 $(BUILDDIR)/scripting/getopts_builtin.o: src/scripting/getopts_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o | $(BUILDDIR)/scripting
292 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
293
294 $(BUILDDIR)/scripting/directory_builtin.o: src/scripting/directory_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o | $(BUILDDIR)/scripting
295 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
296
297 $(BUILDDIR)/scripting/command_builtin.o: src/scripting/command_builtin.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/execution/ast_executor.o | $(BUILDDIR)/scripting
298 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
299
300 $(BUILDDIR)/scripting/variables.o: src/scripting/variables.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/scripting
301 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
302
303 $(BUILDDIR)/scripting/prompt_formatting.o: src/scripting/prompt_formatting.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/substitution.o | $(BUILDDIR)/scripting
304 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
305
306 $(BUILDDIR)/scripting/expansion.o: src/scripting/expansion.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/execution/command_capture.o $(BUILDDIR)/parsing/glob.o | $(BUILDDIR)/scripting
307 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
308
309 $(BUILDDIR)/scripting/substitution.o: src/scripting/substitution.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/execution/command_capture.o | $(BUILDDIR)/scripting
310 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
311
312 $(BUILDDIR)/execution/coprocess.o: src/execution/coprocess.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o | $(BUILDDIR)/execution
313 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
314
315 $(BUILDDIR)/execution/better_errors.o: src/execution/better_errors.f90 $(BUILDDIR)/system/interface.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/execution
316 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
317
318 $(BUILDDIR)/scripting/config.o: src/scripting/config.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/variables.o | $(BUILDDIR)/scripting
319 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
320
321 $(BUILDDIR)/scripting/aliases.o: src/scripting/aliases.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/scripting
322 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
323
324 $(BUILDDIR)/scripting/abbreviations.o: src/scripting/abbreviations.f90 $(BUILDDIR)/common/types.o | $(BUILDDIR)/scripting
325 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
326
327 $(BUILDDIR)/scripting/shell_options.o: src/scripting/shell_options.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/io/readline.o $(BUILDDIR)/scripting/prompt_formatting.o | $(BUILDDIR)/scripting
328 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
329
330 $(BUILDDIR)/scripting/completion.o: src/scripting/completion.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o $(BUILDDIR)/parsing/parser.o | $(BUILDDIR)/scripting
331 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
332
333 $(BUILDDIR)/io/syntax_highlight.o: src/io/syntax_highlight.f90 $(BUILDDIR)/system/interface.o | $(BUILDDIR)/io
334 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
335
336 $(BUILDDIR)/io/suggestions.o: src/io/suggestions.f90 | $(BUILDDIR)/io
337 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
338
339 $(BUILDDIR)/io/readline.o: src/io/readline.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/buffer_ops.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/io/syntax_highlight.o $(BUILDDIR)/io/suggestions.o $(BUILDDIR)/scripting/abbreviations.o $(BUILDDIR)/parsing/glob.o $(BUILDDIR)/scripting/completion.o $(C_STRING_OBJ) | $(BUILDDIR)/io
340 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
341
342 $(BUILDDIR)/io/heredoc.o: src/io/heredoc.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/scripting/variables.o | $(BUILDDIR)/io
343 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
344
345 $(BUILDDIR)/io/fd_redirection.o: src/io/fd_redirection.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/common/io_helpers.o | $(BUILDDIR)/io
346 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
347
348 $(BUILDDIR)/fortsh.o: src/fortsh.f90 $(BUILDDIR)/common/types.o $(BUILDDIR)/common/version.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/system/signals.o $(BUILDDIR)/system/signal_handling.o $(BUILDDIR)/parsing/parser.o $(BUILDDIR)/parsing/lexer.o $(BUILDDIR)/parsing/grammar_parser.o $(BUILDDIR)/parsing/command_tree.o $(BUILDDIR)/execution/executor.o $(BUILDDIR)/execution/ast_executor.o $(BUILDDIR)/execution/jobs.o $(BUILDDIR)/io/readline.o $(BUILDDIR)/scripting/config.o $(BUILDDIR)/scripting/aliases.o $(BUILDDIR)/scripting/shell_options.o $(BUILDDIR)/scripting/prompt_formatting.o $(BUILDDIR)/execution/command_capture_callback.o $(BUILDDIR)/execution/builtins.o $(BUILDDIR)/common/performance.o | $(BUILDDIR)
349 $(FC) $(FCFLAGS) -J$(BUILDDIR) -c $< -o $@
350
351 # ============================================================================
352 # C string library (flang-new workaround for macOS ARM64)
353 # ============================================================================
354
355 # Compile C string operations library
356 $(BUILDDIR)/c_interop/fortsh_strings.o: src/c_interop/fortsh_strings.c src/c_interop/fortsh_strings.h | $(BUILDDIR)/c_interop
357 $(CC) $(CFLAGS) -c $< -o $@
358
359 # Compile C file descriptor wrapper (workaround for Fortran C binding mode_t bug)
360 $(BUILDDIR)/c_interop/fd_wrapper.o: src/c_interop/fd_wrapper.c | $(BUILDDIR)/c_interop
361 $(CC) $(CFLAGS) -c $< -o $@
362
363 # Compile C terminal size wrapper
364 $(BUILDDIR)/c_interop/terminal_size.o: src/c_interop/terminal_size.c | $(BUILDDIR)/c_interop
365 $(CC) $(CFLAGS) -c $< -o $@
366
367 # Create static library from C objects
368 $(BUILDDIR)/c_interop/libfortsh_strings.a: $(BUILDDIR)/c_interop/fortsh_strings.o $(BUILDDIR)/c_interop/fd_wrapper.o $(BUILDDIR)/c_interop/terminal_size.o
369 ar rcs $@ $^
370
371 # Compile Fortran wrapper module (depends on C library for testing)
372 $(BUILDDIR)/c_interop/fortsh_c_strings.o: src/c_interop/fortsh_c_strings.f90 | $(BUILDDIR)/c_interop
373 $(FC) $(FCFLAGS) $(C_STRING_FLAGS) -J$(BUILDDIR) -c $< -o $@
374
375 # Standalone test program for C string library
376 $(BUILDDIR)/test_c_strings: tests/test_c_strings.f90 $(BUILDDIR)/c_interop/fortsh_c_strings.o $(BUILDDIR)/c_interop/libfortsh_strings.a | $(BUILDDIR)
377 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/c_interop/fortsh_c_strings.o $(BUILDDIR)/c_interop/libfortsh_strings.a -o $@
378
379 # ============================================================================
380
381 # Clean targets
382 clean:
383 rm -rf $(BUILDDIR) $(BINDIR)
384 @echo "Clean completed!"
385
386 distclean: clean
387 rm -f *.mod
388
389 # Install target (optional)
390 install: $(TARGET)
391 cp $(TARGET) /usr/local/bin/
392 @echo "Fortsh installed to /usr/local/bin/"
393
394 # Development targets
395 test: $(TARGET)
396 @echo "Running basic functionality test..."
397 @echo "echo 'Hello from Fortsh!'" | $(TARGET)
398
399 ifeq ($(FC),flang-new)
400 debug: FCFLAGS += -g
401 else
402 debug: FCFLAGS += -g -fbacktrace -fcheck=bounds
403 endif
404 debug: $(TARGET)
405
406 release: FCFLAGS = $(FCFLAGS_RELEASE)
407 release: clean $(TARGET)
408 @echo "Building release version..."
409 strip $(TARGET)
410 @echo "Release build complete! Binary size: $$(du -h $(TARGET) | cut -f1)"
411
412 # Test suite targets
413 FORTSH_ABS = $(CURDIR)/$(TARGET)
414
415 # POSIX compliance: single canonical test script (fastest)
416 test-posix: $(TARGET)
417 @echo "Running POSIX compliance tests..."
418 FORTSH_BIN=$(FORTSH_ABS) ./tests/posix_compliance_test.sh
419
420 # Full POSIX suite: all shell-based POSIX test scripts via the comprehensive runner
421 test-posix-full: $(TARGET)
422 @echo "Running full POSIX compliance test suite..."
423 FORTSH_BIN=$(FORTSH_ABS) ./tests/run_all_tests.sh --posix-only
424
425 # Quick POSIX suite: skip slow coverage/untested suites
426 test-posix-quick: $(TARGET)
427 @echo "Running quick POSIX compliance tests..."
428 FORTSH_BIN=$(FORTSH_ABS) ./tests/run_all_tests.sh --posix-only --quick
429
430 # Interactive PTY tests (requires Python venv with pexpect)
431 test-interactive: $(TARGET)
432 @echo "Running interactive PTY tests..."
433 @if [ ! -d tests/interactive/.venv ] && [ ! -d tests/interactive/venv ]; then \
434 echo "Setting up Python virtual environment..."; \
435 python3 -m venv tests/interactive/.venv; \
436 . tests/interactive/.venv/bin/activate && pip install -r tests/interactive/requirements.txt; \
437 fi
438 @if [ -f tests/interactive/.venv/bin/activate ]; then \
439 . tests/interactive/.venv/bin/activate && cd tests/interactive && python run_tests.py; \
440 elif [ -f tests/interactive/venv/bin/activate ]; then \
441 . tests/interactive/venv/bin/activate && cd tests/interactive && python run_tests.py; \
442 else \
443 echo "Error: Python venv not found. Run: cd tests/interactive && python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt"; \
444 exit 1; \
445 fi
446
447 # Full test run: POSIX + interactive (no memory rebuild)
448 test-full: $(TARGET)
449 @echo "Running full test suite (POSIX + interactive)..."
450 FORTSH_BIN=$(FORTSH_ABS) ./tests/run_all_tests.sh --full
451
452 # Everything including memory pool tests (SLOW: rebuilds fortsh)
453 test-all: $(TARGET)
454 @echo "Running all test suites..."
455 FORTSH_BIN=$(FORTSH_ABS) ./tests/run_all_tests.sh --all
456
457 # Help target
458 help:
459 @echo "Fortran Shell (Fortsh) Build System"
460 @echo "==================================="
461 @echo ""
462 @echo "Build targets:"
463 @echo " all - Build fortsh (default, with memory pooling)"
464 @echo " release - Build optimized production binary"
465 @echo " debug - Build with extra debug flags and checks"
466 @echo " clean - Remove build artifacts"
467 @echo " distclean - Remove all generated files"
468 @echo ""
469 @echo "Memory pooling options:"
470 @echo " make - Build with memory pooling (DEFAULT)"
471 @echo " NO_MEMPOOL=1 make - Build without memory pooling"
472 @echo " MEMPOOL_DEBUG=1 make - Build with memory pool debug output"
473 @echo ""
474 @echo "C string library (flang-new workaround):"
475 @echo " c-strings - Build C string library test"
476 @echo " test-c-strings - Test C string library (>128 byte strings)"
477 @echo " USE_C_STRINGS=1 make - Enable C strings in fortsh (experimental)"
478 @echo ""
479 @echo "Test targets:"
480 @echo " test - Run basic functionality test"
481 @echo " test-posix - Run core POSIX compliance tests (~1 min)"
482 @echo " test-posix-full - Run all POSIX test suites (~3 min)"
483 @echo " test-posix-quick- Run fast POSIX tests, skip coverage (~30s)"
484 @echo " test-interactive- Run interactive PTY tests (~2 min)"
485 @echo " test-full - Run POSIX + interactive tests (~5 min)"
486 @echo " test-all - Run everything incl. memory tests (SLOW)"
487 @echo " test-stress - Run stress tests for large values/deep nesting"
488 @echo " check - Run comprehensive checks"
489 @echo ""
490 @echo "Installation targets:"
491 @echo " install - Install fortsh to /usr/local/bin"
492 @echo " dev-install - Install fortsh to ~/.local/bin"
493 @echo " uninstall - Remove fortsh from system"
494 @echo ""
495 @echo "Package targets:"
496 @echo " dist - Create distribution package"
497 @echo " rpm - Build RPM package"
498 @echo ""
499 @echo "Other targets:"
500 @echo " help - Show this help"
501
502 # Package information
503 PACKAGE = fortsh
504 VERSION = 1.0.1
505 # Legacy version (pre-semver reset): 6.0.6
506
507 # Distribution and packaging targets
508 dist: clean
509 @echo "Creating distribution package..."
510 tar czf $(PACKAGE)-$(VERSION).tar.gz \
511 --exclude='.git*' \
512 --exclude='*.o' \
513 --exclude='*.mod' \
514 --exclude='build' \
515 --exclude='bin' \
516 --transform 's,^,$(PACKAGE)-$(VERSION)/,' \
517 src/ tests/ Makefile README.md fortsh.spec
518
519 rpm: dist
520 @echo "Building RPM package..."
521 @command -v rpmbuild >/dev/null 2>&1 || (echo "rpmbuild not available - install rpm-build package" && exit 1)
522 mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
523 cp $(PACKAGE)-$(VERSION).tar.gz ~/rpmbuild/SOURCES/
524 cp $(PACKAGE).spec ~/rpmbuild/SPECS/
525 rpmbuild -ba ~/rpmbuild/SPECS/$(PACKAGE).spec
526 @echo "RPM packages created in ~/rpmbuild/RPMS/"
527
528 dev-install: $(TARGET)
529 @echo "Installing fortsh for development..."
530 mkdir -p ~/.local/bin
531 cp $(TARGET) ~/.local/bin/
532 @echo "fortsh installed to ~/.local/bin/fortsh"
533 @echo "Make sure ~/.local/bin is in your PATH"
534
535 uninstall:
536 @echo "Uninstalling fortsh..."
537 @rm -f ~/.local/bin/fortsh 2>/dev/null || true
538 @rm -f /usr/local/bin/fortsh 2>/dev/null || sudo rm -f /usr/local/bin/fortsh 2>/dev/null || true
539 @echo "Uninstall complete!"
540
541 check: $(TARGET)
542 @echo "Running comprehensive checks..."
543 @echo "✓ Build system works"
544 ./tests/integration_test.sh
545 @echo "✓ Integration tests completed"
546
547 smoke-test: $(TARGET)
548 @echo "Running smoke tests..."
549 @echo "echo 'Hello from Fortsh!'" | $(TARGET) && echo "✓ Basic execution works"
550 @printf 'help\nexit\n' | $(TARGET) >/dev/null && echo "✓ Help command works"
551 @printf 'echo *.txt\nexit\n' | $(TARGET) >/dev/null && echo "✓ Glob expansion works"
552 @printf 'perf on\necho test\nperf\nexit\n' | $(TARGET) >/dev/null && echo "✓ Performance monitoring works"
553 @echo "All smoke tests passed!"
554
555 # macOS ARM64 specific tests - only run on Darwin arm64
556 test-macos-pool: $(TARGET)
557 ifeq ($(UNAME_S),Darwin)
558 ifeq ($(UNAME_M),arm64)
559 @echo "=========================================="
560 @echo "macOS ARM64 Memory Pool Validation"
561 @echo "Testing string pool with flang-new limits"
562 @echo "=========================================="
563 @if [ -f tests/macos_arm64_pool_checks.sh ]; then \
564 chmod +x tests/macos_arm64_pool_checks.sh && \
565 ./tests/macos_arm64_pool_checks.sh; \
566 else \
567 echo "⚠️ macOS ARM64 pool checks not found"; \
568 fi
569 @if [ -f tests/memory_pool_validation.sh ]; then \
570 echo "" && \
571 echo "Running general pool validation..." && \
572 chmod +x tests/memory_pool_validation.sh && \
573 ./tests/memory_pool_validation.sh; \
574 fi
575 @echo "✓ macOS ARM64 pool tests complete"
576 else
577 @echo "⚠️ Skipping macOS ARM64 tests (not on arm64 platform)"
578 endif
579 else
580 @echo "⚠️ Skipping macOS tests (not on Darwin)"
581 endif
582
583 # macOS build verification - ensures no flang-new regressions
584 test-macos-compiler: $(TARGET)
585 ifeq ($(UNAME_S),Darwin)
586 ifeq ($(UNAME_M),arm64)
587 @echo "=========================================="
588 @echo "macOS ARM64 Compiler Compatibility Check"
589 @echo "Verifying flang-new workarounds"
590 @echo "=========================================="
591 @echo "Testing 127-byte command limit..."
592 @echo 'echo "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"' | $(TARGET) 2>&1 | grep -q "123456" && echo "✓ Long command handling works"
593 @echo "Testing fixed-length string buffers..."
594 @echo "echo test" | $(TARGET) >/dev/null && echo "✓ Fixed-length buffers work"
595 @echo "✓ macOS compiler compatibility verified"
596 else
597 @echo "⚠️ Skipping macOS ARM64 compiler tests (not on arm64)"
598 endif
599 else
600 @echo "⚠️ Skipping macOS compiler tests (not on Darwin)"
601 endif
602
603 # Combined macOS test suite
604 test-macos: test-macos-pool test-macos-compiler
605 @echo ""
606 @echo "=========================================="
607 @echo "All macOS ARM64 Tests Complete"
608 @echo "=========================================="
609
610 # ============================================================================
611 # Unit Test Bench Files
612 # ============================================================================
613
614 # Build rules for unit tests
615 $(BUILDDIR)/test_memory_pool: tests/test_memory_pool.f90 $(BUILDDIR)/common/string_pool.o | $(BUILDDIR)
616 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o -o $@
617
618 $(BUILDDIR)/test_lexer_simple: tests/test_lexer_simple.f90 $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o | $(BUILDDIR)
619 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o -o $@
620
621 $(BUILDDIR)/test_parser_simple: tests/test_parser_simple.f90 $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o | $(BUILDDIR)
622 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o -o $@
623
624 $(BUILDDIR)/test_executor_simple: tests/test_executor_simple.f90 $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o | $(BUILDDIR)
625 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o -o $@
626
627 $(BUILDDIR)/test_expansion_simple: tests/test_expansion_simple.f90 $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o | $(BUILDDIR)
628 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o -o $@
629
630 $(BUILDDIR)/test_variables_simple: tests/test_variables_simple.f90 $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o | $(BUILDDIR)
631 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(BUILDDIR)/common/types.o -o $@
632
633 $(BUILDDIR)/test_suggestions: tests/test_suggestions.f90 $(BUILDDIR)/io/suggestions.o | $(BUILDDIR)
634 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/io/suggestions.o -o $@
635
636 $(BUILDDIR)/test_syntax_highlight: tests/test_syntax_highlight.f90 $(BUILDDIR)/io/syntax_highlight.o $(CORE_C_OBJS) | $(BUILDDIR)
637 $(FC) $(FCFLAGS) -J$(BUILDDIR) $< $(BUILDDIR)/io/syntax_highlight.o $(BUILDDIR)/system/interface.o $(BUILDDIR)/common/types.o $(BUILDDIR)/common/string_pool.o $(BUILDDIR)/common/memory_dashboard.o $(CORE_C_OBJS) -o $@
638
639 # Individual test targets
640 test-memory-pool: $(BUILDDIR)/test_memory_pool
641 @echo "=========================================="
642 @echo "Testing Memory Pool (String Pool)"
643 @echo "=========================================="
644 @$(BUILDDIR)/test_memory_pool
645
646 test-lexer: $(BUILDDIR)/test_lexer_simple
647 @echo "=========================================="
648 @echo "Testing Lexer"
649 @echo "=========================================="
650 @$(BUILDDIR)/test_lexer_simple
651
652 test-parser: $(BUILDDIR)/test_parser_simple
653 @echo "=========================================="
654 @echo "Testing Parser"
655 @echo "=========================================="
656 @$(BUILDDIR)/test_parser_simple
657
658 test-executor: $(BUILDDIR)/test_executor_simple
659 @echo "=========================================="
660 @echo "Testing Executor"
661 @echo "=========================================="
662 @$(BUILDDIR)/test_executor_simple
663
664 test-expansion: $(BUILDDIR)/test_expansion_simple
665 @echo "=========================================="
666 @echo "Testing Expansion"
667 @echo "=========================================="
668 @$(BUILDDIR)/test_expansion_simple
669
670 test-variables: $(BUILDDIR)/test_variables_simple
671 @echo "=========================================="
672 @echo "Testing Variables"
673 @echo "=========================================="
674 @$(BUILDDIR)/test_variables_simple
675
676 test-suggestions: $(BUILDDIR)/test_suggestions
677 @echo "=========================================="
678 @echo "Testing Suggestions"
679 @echo "=========================================="
680 @$(BUILDDIR)/test_suggestions
681
682 test-highlight: $(BUILDDIR)/test_syntax_highlight
683 @echo "=========================================="
684 @echo "Testing Syntax Highlight v2"
685 @echo "=========================================="
686 @$(BUILDDIR)/test_syntax_highlight
687
688 # Run all unit bench tests (working tests only)
689 test-stress: $(TARGET)
690 @echo "Running stress tests..."
691 FORTSH_BIN=$(FORTSH_ABS) ./tests/builtins/test_stress.sh
692
693 test-bench: test-memory-pool test-lexer test-executor test-suggestions test-highlight test-c-strings test-stress
694 @echo ""
695 @echo "=========================================="
696 @echo "All bench tests passed!"
697 @echo "=========================================="
698
699 # Test C string library (flang-new workaround)
700 test-c-strings: $(BUILDDIR)/test_c_strings
701 @echo "=========================================="
702 @echo "Testing C String Library"
703 @echo "=========================================="
704 @$(BUILDDIR)/test_c_strings
705 @echo ""
706 @echo "✓ C string library test passed!"
707 @echo "This proves we can handle >128 byte strings"
708 @echo "without triggering flang-new heap corruption!"
709 @echo "=========================================="
710
711 # Build just the C string library and test
712 c-strings: $(BUILDDIR)/test_c_strings
713 @echo "C string library built successfully!"
714 @echo "Run 'make test-c-strings' to test it"
715
716 .PHONY: all clean distclean install test debug release help dist rpm dev-install uninstall check smoke-test test-integration test-parity test-posix test-features test-all test-macos-pool test-macos-compiler test-macos test-c-strings c-strings test-memory-pool test-lexer test-parser test-executor test-expansion test-variables test-suggestions test-highlight test-stress test-bench