Skip to content

Commit 107f97a

Browse files
[ESP32] Fix compile flag parsing in create_args_gn.py for ESP-IDF v6.0 (project-chip#43668)
* [ESP32] Fix compile flag parsing in create_args_gn.py for ESP-IDF v6.0 ESP-IDF v6.0 stores compile flags in response files (e.g. @"/path/to/cflags") rather than inline in compile_commands.json. This breaks the GN args generation as the script was splitting on whitespace without expanding these references. - Add `expand_response_file()` to read and expand @file references - Use `shlex.split()` instead of `str.split()` for proper command parsing - Add `quote_for_gn()` to correctly escape embedded quotes and backslashes for GN string syntax * Restyled by autopep8 * Fix expand_response_file to raise on unreadable response files Silently returning an empty list would drop compile flags and produce a broken build that is hard to debug. Raise an exception instead so the error is immediately visible. --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 2027a83 commit 107f97a

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

config/esp32/components/chip/create_args_gn.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2021 Project CHIP Authors
2+
# Copyright (c) 2021-2026 Project CHIP Authors
33
# Copyright (c) 2018 Nest Labs, Inc.
44
# All rights reserved.
55
#
@@ -22,6 +22,7 @@
2222
import argparse
2323
import json
2424
import os
25+
import shlex
2526

2627
# Parse the build's compile_commands.json to generate
2728
# final args file for CHIP build.
@@ -40,6 +41,30 @@
4041

4142
compile_commands_path = os.path.join(args.build_dir, "compile_commands.json")
4243

44+
# From esp-idf v6.0 and onwards, compile flags are stored in files, so we need to explicitly expand them
45+
# eg: @\"/Users/esp/connectedhomeip/examples/lighting-app/esp32/build/toolchain/asmflags\"
46+
# @\"/Users/esp/connectedhomeip/examples/lighting-app/esp32/build/toolchain/cflags\"
47+
# this function reads that file and returns the flags
48+
49+
50+
def expand_response_file(flag):
51+
"""Expand response file references (flags starting with @) into their contents."""
52+
# Handle both @path and @"path" formats
53+
if flag.startswith('@"') and flag.endswith('"'):
54+
response_file_path = flag[2:-1] # Remove @" and trailing "
55+
elif flag.startswith('@'):
56+
response_file_path = flag[1:] # Remove @
57+
else:
58+
return [flag]
59+
60+
try:
61+
with open(response_file_path, 'r') as f:
62+
content = f.read()
63+
return shlex.split(content)
64+
except (IOError, OSError) as e:
65+
raise Exception(f"Failed to read response file '{response_file_path}': {e}")
66+
67+
4368
with open(compile_commands_path) as compile_commands_json:
4469
compile_commands = json.load(compile_commands_json)
4570

@@ -52,19 +77,31 @@ def get_compile_flags(src_file):
5277
raise Exception(f"Failed to resolve compile flags for {src_file}")
5378

5479
compile_command = compile_command[0]
80+
compile_parts = shlex.split(compile_command)
5581
# Trim compiler, input and output
56-
compile_flags = compile_command.split()[1:-4]
82+
compile_flags = compile_parts[1:-4]
83+
84+
# Expand any response file references
85+
expanded_flags = []
86+
for flag in compile_flags:
87+
expanded_flags.extend(expand_response_file(flag))
5788

5889
replace = "-I%s" % args.idf_path
5990
replace_with = "-isystem%s" % args.idf_path
6091

61-
compile_flags = [f'"{f}"'.replace(replace, replace_with) for f in compile_flags]
92+
# Escape any embedded double quotes for GN string syntax, then wrap in quotes
93+
def quote_for_gn(flag):
94+
# Escape backslashes first, then escape double quotes
95+
escaped = flag.replace('\\', '\\\\').replace('"', '\\"')
96+
return f'"{escaped}"'
97+
98+
expanded_flags = [quote_for_gn(f).replace(replace, replace_with) for f in expanded_flags]
6299

63100
if args.filter_out:
64101
filter_out = [f'"{f}"' for f in args.filter_out.split(';')]
65-
compile_flags = [c for c in compile_flags if c not in filter_out]
102+
expanded_flags = [c for c in expanded_flags if c not in filter_out]
66103

67-
return compile_flags
104+
return expanded_flags
68105

69106
c_flags = get_compile_flags(args.c_file)
70107
cpp_flags = get_compile_flags(args.cpp_file)

0 commit comments

Comments
 (0)