Skip to content

Commit 14279a6

Browse files
committed
Small compile_flags helper script
1 parent 85ddfca commit 14279a6

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate compile_commands.json and analyze compile flags for duplicates.
4+
"""
5+
6+
import argparse
7+
import json
8+
import subprocess
9+
import sys
10+
from collections import Counter
11+
12+
13+
def main():
14+
# Parse command line arguments
15+
parser = argparse.ArgumentParser(
16+
description="Generate compile_commands.json and analyze compile flags"
17+
)
18+
parser.add_argument(
19+
"filename",
20+
nargs="?",
21+
default="src/base_math/base_math.cc",
22+
help="Source file to analyze (default: src/base_math/base_math.cc)"
23+
)
24+
args = parser.parse_args()
25+
26+
print("Running: bazel run @hedron_compile_commands//:refresh_all")
27+
print("-" * 60)
28+
29+
# Execute the bazel command
30+
try:
31+
result = subprocess.run(
32+
["bazel", "run", "@hedron_compile_commands//:refresh_all"],
33+
capture_output=True,
34+
text=True,
35+
check=True
36+
)
37+
print(result.stdout)
38+
if result.stderr:
39+
print(result.stderr, file=sys.stderr)
40+
except subprocess.CalledProcessError as e:
41+
print(f"Error running bazel command: {e}", file=sys.stderr)
42+
print(e.stderr, file=sys.stderr)
43+
sys.exit(1)
44+
45+
print("\n" + "=" * 60)
46+
print("Reading compile_commands.json...")
47+
print("=" * 60 + "\n")
48+
49+
# Read the generated compile_commands.json
50+
try:
51+
with open("compile_commands.json", "r") as f:
52+
compile_commands = json.load(f)
53+
except FileNotFoundError:
54+
print("Error: compile_commands.json not found", file=sys.stderr)
55+
sys.exit(1)
56+
except json.JSONDecodeError as e:
57+
print(f"Error parsing compile_commands.json: {e}", file=sys.stderr)
58+
sys.exit(1)
59+
60+
if not compile_commands:
61+
print("Error: compile_commands.json is empty", file=sys.stderr)
62+
sys.exit(1)
63+
64+
# Find the entry for the specified file
65+
target_entry = None
66+
for entry in compile_commands:
67+
if entry.get("file", "").endswith(args.filename):
68+
target_entry = entry
69+
break
70+
71+
if not target_entry:
72+
print(f"Error: No entry found for file '{args.filename}'", file=sys.stderr)
73+
print(f"\nAvailable files:", file=sys.stderr)
74+
for entry in compile_commands[:5]:
75+
print(f" - {entry.get('file', 'N/A')}", file=sys.stderr)
76+
if len(compile_commands) > 5:
77+
print(f" ... and {len(compile_commands) - 5} more", file=sys.stderr)
78+
sys.exit(1)
79+
80+
print(f"Target file: {target_entry.get('file', 'N/A')}")
81+
print(f"Directory: {target_entry.get('directory', 'N/A')}")
82+
print("\n" + "-" * 60)
83+
print("Compile options from target entry:")
84+
print("-" * 60 + "\n")
85+
86+
# Parse the command to extract compile options
87+
command = target_entry.get("command", "")
88+
if not command:
89+
# Try 'arguments' field if 'command' is not present
90+
arguments = target_entry.get("arguments", [])
91+
if arguments:
92+
compile_options = [arg for arg in arguments if arg.startswith("-")]
93+
else:
94+
print("Error: No command or arguments found in target entry", file=sys.stderr)
95+
sys.exit(1)
96+
else:
97+
# Split command string and extract options starting with '-'
98+
import shlex
99+
parts = shlex.split(command)
100+
compile_options = [part for part in parts if part.startswith("-")]
101+
102+
# Display all compile options
103+
for i, option in enumerate(compile_options, 1):
104+
print(f"{i:3d}. {option}")
105+
106+
print(f"\nTotal compile options: {len(compile_options)}")
107+
108+
# Check for duplicates
109+
print("\n" + "=" * 60)
110+
print("Checking for duplicate compile options...")
111+
print("=" * 60 + "\n")
112+
113+
option_counts = Counter(compile_options)
114+
duplicates = {opt: count for opt, count in option_counts.items() if count > 1}
115+
116+
if duplicates:
117+
print(f"Found {len(duplicates)} duplicate compile option(s):\n")
118+
for option, count in sorted(duplicates.items(), key=lambda x: x[1], reverse=True):
119+
print(f" '{option}' appears {count} times")
120+
else:
121+
print("No duplicate compile options found.")
122+
123+
return 0
124+
125+
126+
if __name__ == "__main__":
127+
sys.exit(main())

0 commit comments

Comments
 (0)