1
- # Makefile for Python formatting in fuzzing infrastructure
2
- # This file provides standardized Python code formatting rules for Zondax Ledger applications
1
+ # Makefile for ledger-zxlib fuzzing
2
+ # This file contains both fuzzing targets and Python formatting rules
3
3
4
- # Configuration
4
+ # === FUZZING CONFIGURATION ===
5
+ # All fuzzing configuration is now managed in fuzz_local/fuzz_config.py
6
+ FUZZ_DIR = fuzz_local
7
+ FUZZ_BUILD_DIR = $(FUZZ_DIR ) /build
8
+ FUZZ_COVERAGE_DIR = $(FUZZ_DIR ) /coverage
9
+ PYTHON ?= python3
10
+
11
+ # === PYTHON FORMATTING CONFIGURATION ===
5
12
BLACK_LINE_LENGTH := 120
6
- # Only search in fuzzing-related directories (relative to this Makefile's location)
7
13
FUZZING_DIR := .
8
- PROJECT_FUZZ_DIR := $(shell cd ../../../ && pwd) /fuzz
9
-
10
- # Validate that the project fuzz directory exists
11
- validate_fuzz_dir :
12
- @if [ ! -d " $( PROJECT_FUZZ_DIR) " ]; then \
13
- echo " ⚠️ WARNING: Project fuzz directory not found: $( PROJECT_FUZZ_DIR) " ; \
14
- echo " Only formatting files in the common fuzzing library directory." ; \
15
- echo " To format project-specific files, please create the 'fuzz' directory." ; \
16
- fi
17
-
18
- # Find all Python files in fuzzing directories only
19
- PYTHON_FILES := $(shell find $(FUZZING_DIR ) -name "* .py" -type f -not -path "* /.* " 2>/dev/null) \
20
- $(shell if [ -d "$(PROJECT_FUZZ_DIR ) " ]; then find $(PROJECT_FUZZ_DIR ) -name "* .py" -type f -not -path "* /.* " 2>/dev/null; fi)
21
14
22
15
# Default target
23
16
.PHONY : help
24
17
help :
25
- @echo " Python Formatting Rules for Zondax Ledger Fuzzing "
18
+ @echo " ledger-zxlib Fuzzing & Development Tools "
26
19
@echo " "
27
- @echo " Available targets:"
28
- @echo " format Format Python files in fuzzing directories with Black"
29
- @echo " check Check if files need formatting (no changes)"
30
- @echo " install Install Black formatter"
31
- @echo " clean Remove __pycache__ directories from fuzzing dirs"
32
- @echo " list List Python files in fuzzing directories"
20
+ @echo " === FUZZING TARGETS ==="
21
+ @echo " build_fuzz Build fuzzer targets"
22
+ @echo " fuzz Run all fuzzers (uses config from fuzz_config.py)"
23
+ @echo " fuzz_crash Analyze any crashes found"
24
+ @echo " fuzz_clean Clean fuzzing artifacts"
25
+ @echo " fuzz_report Generate coverage report"
26
+ @echo " fuzz_report_html Generate HTML coverage report"
27
+ @echo " "
28
+ @echo " === PYTHON FORMATTING ==="
29
+ @echo " format Format Python files with Black"
30
+ @echo " check Check if files need formatting"
31
+ @echo " format_clean Remove Python cache files"
33
32
@echo " "
34
33
@echo " Configuration:"
35
- @echo " Line length: $( BLACK_LINE_LENGTH) "
36
- @echo " Fuzzing directories: $( FUZZING_DIR) $( PROJECT_FUZZ_DIR) "
34
+ @echo " Edit fuzz_local/fuzz_config.py to change fuzzing parameters"
35
+ @echo " "
36
+ @echo " Examples:"
37
+ @echo " make fuzz # Run with default config"
38
+ @echo " make fuzz_report # Generate coverage report"
39
+
40
+ # === FUZZING TARGETS ===
41
+
42
+ # Check if clang is available
43
+ .PHONY : check_clang
44
+ check_clang :
45
+ @command -v clang > /dev/null 2>&1 || { \
46
+ echo " ❌ Error: clang not found. Please install clang for fuzzing." ; \
47
+ echo " On macOS: brew install llvm" ; \
48
+ echo " On Ubuntu: apt install clang" ; \
49
+ exit 1; \
50
+ }
51
+ @command -v clang++ > /dev/null 2>&1 || { \
52
+ echo " ❌ Error: clang++ not found. Please install clang++ for fuzzing." ; \
53
+ echo " On macOS: brew install llvm" ; \
54
+ echo " On Ubuntu: apt install clang" ; \
55
+ exit 1; \
56
+ }
57
+ @echo " ✅ Clang found: $$ (clang --version | head -n1)"
58
+ @echo " ✅ Clang++ found: $$ (clang++ --version | head -n1)"
59
+
60
+ # Build fuzzer targets
61
+ .PHONY : build_fuzz
62
+ build_fuzz : check_clang
63
+ @echo " 🔨 Building fuzzer targets..."
64
+ @mkdir -p $(FUZZ_BUILD_DIR )
65
+ @cd $(FUZZ_BUILD_DIR ) && \
66
+ cmake -DCMAKE_C_COMPILER=clang \
67
+ -DCMAKE_CXX_COMPILER=clang++ \
68
+ -DENABLE_FUZZING=ON \
69
+ -DENABLE_SANITIZERS=ON \
70
+ -DCMAKE_BUILD_TYPE=Debug \
71
+ .. && \
72
+ make -j$$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4 )
73
+ @echo " ✅ Fuzzer build completed"
74
+
75
+ # Run fuzzers
76
+ .PHONY : fuzz
77
+ fuzz : build_fuzz
78
+ @echo " 🚀 Starting fuzzing session..."
79
+ @echo " Configuration from: $( FUZZ_DIR) /fuzz_config.py"
80
+ @$(PYTHON ) $(FUZZ_DIR ) /run_local_fuzz.py
81
+ @echo " 🏁 Fuzzing session completed"
82
+
83
+ # Analyze crashes
84
+ .PHONY : fuzz_crash
85
+ fuzz_crash : build_fuzz
86
+ @echo " 🔍 Analyzing fuzzing crashes..."
87
+ @$(PYTHON ) $(FUZZ_DIR ) /analyze_local_crashes.py
88
+
89
+ # Clean fuzzing artifacts
90
+ .PHONY : fuzz_clean
91
+ fuzz_clean :
92
+ @echo " 🧹 Cleaning fuzzing artifacts..."
93
+ @rm -rf $(FUZZ_BUILD_DIR )
94
+ @rm -rf $(FUZZ_DIR ) /corpora
95
+ @rm -rf $(FUZZ_DIR ) /logs
96
+ @rm -rf $(FUZZ_DIR ) /coverage
97
+ @echo " ✅ Fuzzing artifacts cleaned"
98
+
99
+ # Generate coverage report
100
+ .PHONY : fuzz_report
101
+ fuzz_report :
102
+ @if [ ! -d " $( FUZZ_COVERAGE_DIR) " ] || [ -z " $$ (ls -A $( FUZZ_COVERAGE_DIR) 2>/dev/null)" ]; then \
103
+ echo " Error: Coverage directory is empty. Please run the fuzzer with ENABLE_COVERAGE flag ON" ; \
104
+ exit 1; \
105
+ fi
106
+ @command -v llvm-profdata > /dev/null 2>&1 || { \
107
+ echo " ❌ Error: llvm-profdata not found. Please install LLVM tools." ; \
108
+ echo " On macOS: brew install llvm" ; \
109
+ echo " On Ubuntu: apt install llvm" ; \
110
+ exit 1; \
111
+ }
112
+ @if [ -z " $$ (ls $( FUZZ_COVERAGE_DIR) /*.profraw 2>/dev/null)" ]; then \
113
+ echo " ❌ Error: No .profraw files found in coverage directory." ; \
114
+ echo " Please run fuzzer with coverage enabled first." ; \
115
+ exit 1; \
116
+ fi
117
+ @llvm-profdata merge -sparse $(FUZZ_COVERAGE_DIR ) /* .profraw -o $(FUZZ_COVERAGE_DIR ) /coverage.profdata
118
+ @for fuzzer in $(FUZZ_BUILD_DIR ) /fuzz-* ; do \
119
+ if [ -x " $$ fuzzer" ]; then \
120
+ echo " Coverage for $$ (basename $$ fuzzer):" ; \
121
+ llvm-cov report $$ fuzzer -instr-profile=$(FUZZ_COVERAGE_DIR ) /coverage.profdata; \
122
+ fi ; \
123
+ done
124
+
125
+ # Generate unified HTML coverage report for all fuzzers
126
+ .PHONY : fuzz_report_html
127
+ fuzz_report_html :
128
+ @# Check coverage directory exists and has data
129
+ @if [ ! -d " $( FUZZ_COVERAGE_DIR) " ] || [ -z " $$ (ls -A $( FUZZ_COVERAGE_DIR) 2>/dev/null)" ]; then \
130
+ echo " Error: Coverage directory is empty. Please run the fuzzer with ENABLE_COVERAGE flag ON" ; \
131
+ exit 1; \
132
+ fi
133
+ @command -v llvm-profdata > /dev/null 2>&1 || { \
134
+ echo " ❌ Error: llvm-profdata not found. Please install LLVM tools." ; \
135
+ echo " On macOS: brew install llvm" ; \
136
+ echo " On Ubuntu: apt install llvm" ; \
137
+ exit 1; \
138
+ }
139
+ @command -v llvm-cov > /dev/null 2>&1 || { \
140
+ echo " ❌ Error: llvm-cov not found. Please install LLVM tools." ; \
141
+ echo " On macOS: brew install llvm" ; \
142
+ echo " On Ubuntu: apt install llvm" ; \
143
+ exit 1; \
144
+ }
145
+ @if [ -z " $$ (ls $( FUZZ_COVERAGE_DIR) /*.profraw 2>/dev/null)" ]; then \
146
+ echo " ❌ Error: No .profraw files found in coverage directory." ; \
147
+ echo " Please run fuzzer with coverage enabled first." ; \
148
+ exit 1; \
149
+ fi
150
+ @# Merge all profraw files into a single profdata file
151
+ @llvm-profdata merge -sparse $(FUZZ_COVERAGE_DIR ) /* .profraw -o $(FUZZ_COVERAGE_DIR ) /coverage.profdata
152
+ @echo " Generating unified coverage report for all fuzzers..."
153
+ @rm -rf $(FUZZ_COVERAGE_DIR ) /report_html_unified
154
+ @# Generate HTML report with all fuzzer binaries
155
+ @FUZZ_BINARIES=($( FUZZ_BUILD_DIR) /fuzz-* ); \
156
+ if [ -e " $$ {FUZZ_BINARIES[0]}" ]; then \
157
+ FIRST_BINARY=" $$ {FUZZ_BINARIES[0]}" ; \
158
+ OBJECT_FLAGS=" " ; \
159
+ for bin in " $$ {FUZZ_BINARIES[@]:1}" ; do \
160
+ OBJECT_FLAGS=" $$ OBJECT_FLAGS -object $$ bin" ; \
161
+ done ; \
162
+ llvm-cov show $$ FIRST_BINARY $$ OBJECT_FLAGS \
163
+ -instr-profile=$(FUZZ_COVERAGE_DIR ) /coverage.profdata \
164
+ -format=html \
165
+ -output-dir=$(FUZZ_COVERAGE_DIR ) /report_html_unified \
166
+ -show-line-counts-or-regions \
167
+ -show-instantiations \
168
+ -show-expansions; \
169
+ else \
170
+ echo " No fuzz binaries found in $( FUZZ_BUILD_DIR) " ; \
171
+ exit 1; \
172
+ fi
173
+ @echo " Unified HTML coverage report generated in $( FUZZ_COVERAGE_DIR) /report_html_unified"
174
+ @# Open report in default browser (cross-platform)
175
+ @open $(FUZZ_COVERAGE_DIR ) /report_html_unified/index.html 2> /dev/null || \
176
+ xdg-open $(FUZZ_COVERAGE_DIR ) /report_html_unified/index.html 2> /dev/null || \
177
+ echo " Please open manually: $( FUZZ_COVERAGE_DIR) /report_html_unified/index.html"
178
+
179
+ # === PYTHON FORMATTING TARGETS ===
180
+
181
+ # Find all Python files in fuzzing directories
182
+ PYTHON_FILES := $(shell find $(FUZZING_DIR ) -name "* .py" -type f -not -path "* /.* " 2>/dev/null)
37
183
38
184
# Install Black if not present
39
- .PHONY : install
40
- install :
185
+ .PHONY : format_install
186
+ format_install :
41
187
@echo " 🔧 Installing Black Python formatter..."
42
- @pip3 install black || { echo " ❌ Failed to install Black" ; exit 1; }
188
+ @command -v black > /dev/null 2>&1 || \
189
+ { echo " 🔧 Installing Black Python formatter…" ; \
190
+ $(PYTHON ) -m pip install --user black || { echo " ❌ Failed to install Black" ; exit 1; }; }
43
191
@echo " ✅ Black installed successfully"
44
192
45
- # Format all Python files (checks first, then formats only if needed)
193
+ # Format all Python files
46
194
.PHONY : format
47
- format : install validate_fuzz_dir
195
+ format : format_install
48
196
@echo " 🎨 Formatting Python files with Black..."
49
- @if $(MAKE ) check; then \
197
+ @if [ -z " $( PYTHON_FILES) " ]; then \
198
+ echo " ⚠️ No Python files found" ; \
199
+ elif black --check --quiet --line-length $(BLACK_LINE_LENGTH ) $(PYTHON_FILES ) ; then \
50
200
echo " ✅ All Python files are already properly formatted - no changes needed" ; \
51
201
else \
52
- echo " ⚙️ Files need formatting - applying changes..." ; \
53
- if [ -z " $( PYTHON_FILES) " ]; then \
54
- echo " ⚠️ No Python files found" ; \
55
- else \
56
- black --line-length $(BLACK_LINE_LENGTH ) $(PYTHON_FILES ) && \
57
- echo " ✅ All Python files formatted successfully" || \
58
- { echo " ❌ Formatting failed" ; exit 1; }; \
59
- fi ; \
202
+ echo " ⚙️ Applying formatting changes…" ; \
203
+ black --line-length $(BLACK_LINE_LENGTH ) $(PYTHON_FILES ) ; \
60
204
fi
61
205
62
206
# Check formatting without making changes
63
207
.PHONY : check
64
- check : install validate_fuzz_dir
208
+ check : format_install
65
209
@echo " 🔍 Checking Python file formatting..."
66
210
@if [ -z " $( PYTHON_FILES) " ]; then \
67
211
echo " ⚠️ No Python files found" ; \
68
212
else \
69
- echo " 📁 Checking $( shell echo $( PYTHON_FILES) | wc -w) Python files:" ; \
70
- for file in $( PYTHON_FILES) ; do \
71
- echo " • $$ (basename $$ file)" ; \
72
- done ; \
73
- echo " " ; \
213
+ echo " 📁 Checking $( shell echo $( PYTHON_FILES) | wc -w) Python files" ; \
74
214
black --check --line-length $(BLACK_LINE_LENGTH ) $(PYTHON_FILES ) && \
75
215
echo " ✅ All Python files are properly formatted" || \
76
216
{ echo " ❌ Some files need formatting - run 'make format'" ; exit 1; }; \
77
217
fi
78
218
79
- # List all Python files that would be formatted
80
- .PHONY : list
81
- list : validate_fuzz_dir
219
+ # Clean Python cache files
220
+ .PHONY : format_clean
221
+ format_clean :
222
+ @echo " 🧹 Cleaning Python cache files..."
223
+ @find $(FUZZING_DIR ) -type d -name " __pycache__" -exec rm -rf {} + 2> /dev/null || true
224
+ @find $(FUZZING_DIR ) -name " *.pyc" -delete 2> /dev/null || true
225
+ @find $(FUZZING_DIR ) -name " *.pyo" -delete 2> /dev/null || true
226
+ @echo " ✅ Python cache files cleaned"
227
+
228
+ # List Python files
229
+ .PHONY : format_list
230
+ format_list :
82
231
@echo " Python files in fuzzing directories:"
83
232
@if [ -z " $( PYTHON_FILES) " ]; then \
84
- echo " No Python files found in: $( FUZZING_DIR) $( PROJECT_FUZZ_DIR ) " ; \
233
+ echo " No Python files found in: $( FUZZING_DIR) " ; \
85
234
else \
86
235
for file in $( PYTHON_FILES) ; do \
87
236
echo " $$ file" ; \
88
237
done ; \
89
- fi
90
-
91
- # Clean Python cache files
92
- .PHONY : clean
93
- clean :
94
- @echo " 🧹 Cleaning Python cache files..."
95
- @find $(PYTHON_DIRS ) -type d -name " __pycache__" -exec rm -rf {} + 2> /dev/null || true
96
- @find $(PYTHON_DIRS ) -name " *.pyc" -delete 2> /dev/null || true
97
- @find $(PYTHON_DIRS ) -name " *.pyo" -delete 2> /dev/null || true
98
- @echo " ✅ Python cache files cleaned"
99
-
100
- # Verify Black installation
101
- .PHONY : version
102
- version :
103
- @echo " 🔧 Black version information:"
104
- @black --version 2> /dev/null || echo " ❌ Black not installed - run 'make install'"
238
+ fi
0 commit comments