@@ -117,6 +117,15 @@ def download_protoc_29_1(project_root: Path) -> str:
117
117
shutil .copy2 (source_protoc , protoc_bin )
118
118
protoc_bin .chmod (0o755 ) # Make executable
119
119
120
+ # Also copy the include directory with Google protobuf standard library files
121
+ source_include = unzip_dir / "include"
122
+ if source_include .exists ():
123
+ target_include = project_root / ".bin" / "include"
124
+ if target_include .exists ():
125
+ shutil .rmtree (target_include )
126
+ shutil .copytree (source_include , target_include )
127
+ print (f"✓ Copied protobuf include files to { target_include } " )
128
+
120
129
# Clean up
121
130
shutil .rmtree (unzip_dir )
122
131
zip_path .unlink ()
@@ -231,59 +240,82 @@ def generate_init_file(output_dir: Path) -> None:
231
240
print (f" ✓ Generated { init_file } with { len (pb2_files )} modules" )
232
241
233
242
234
- def find_brew_protobuf_include (project_root : Path ) -> str :
235
- """Find the protobuf include directory, preferring downloaded protoc 29.1, then brew installations."""
243
+ def find_protobuf_include (project_root : Path ) -> str :
244
+ """Find the protobuf include directory, preferring downloaded protoc 29.1, then system installations."""
236
245
# First, check if we have downloaded protoc 29.1 and use its include directory
237
- protoc_29_1_bin = project_root / "bin" / "protoc-29.1"
246
+ protoc_29_1_bin = project_root / ". bin" / "protoc-29.1"
238
247
if protoc_29_1_bin .exists ():
239
248
# The downloaded protoc includes the well-known types in the zip
240
- # We'll use the local include directory as fallback
249
+ # Check for the include directory in .bin first
250
+ bin_include = project_root / ".bin" / "include"
251
+ if bin_include .exists ():
252
+ print (f"Using .bin protobuf include directory: { bin_include } " )
253
+ return str (bin_include )
254
+
255
+ # Fallback to local include directory
241
256
local_include = project_root / "include"
242
257
if local_include .exists ():
243
258
print (f"Using local include directory: { local_include } " )
244
259
return str (local_include )
245
260
246
- try :
247
- # Try to find main brew protobuf installation (version 29.3)
248
- result = subprocess .run (["brew" , "--prefix" , "protobuf" ],
249
- capture_output = True , text = True , timeout = 5 )
250
- if result .returncode == 0 :
251
- brew_prefix = result .stdout .strip ()
252
- include_path = f"{ brew_prefix } /include"
253
- if os .path .exists (include_path ):
254
- print (f"Using main protobuf include: { include_path } " )
255
- return include_path
256
- except (subprocess .TimeoutExpired , FileNotFoundError ):
257
- pass
261
+ # Check if we're on macOS (using brew)
262
+ if platform .system ().lower () == 'darwin' :
263
+ try :
264
+ # Try to find main brew protobuf installation (version 29.3)
265
+ result = subprocess .run (["brew" , "--prefix" , "protobuf" ],
266
+ capture_output = True , text = True , timeout = 5 )
267
+ if result .returncode == 0 :
268
+ brew_prefix = result .stdout .strip ()
269
+ include_path = f"{ brew_prefix } /include"
270
+ if os .path .exists (include_path ):
271
+ print (f"Using main protobuf include: { include_path } " )
272
+ return include_path
273
+ except (subprocess .TimeoutExpired , FileNotFoundError ):
274
+ pass
258
275
259
- # Check protobuf@29 second (version 29.4)
260
- protobuf_29_include = "/opt/homebrew/opt/protobuf@29/include"
261
- if os .path .exists (protobuf_29_include ):
262
- print (f"Using protobuf@29 include: { protobuf_29_include } " )
263
- return protobuf_29_include
264
-
265
- # Fallback to common brew location
266
- common_paths = [
267
- "/opt/homebrew/include" ,
268
- "/usr/local/include" ,
269
- "/opt/homebrew/Cellar/protobuf/*/include"
270
- ]
271
-
272
- for path_pattern in common_paths :
273
- if "*" in path_pattern :
274
- # Handle wildcard pattern
275
- import glob
276
- matches = glob .glob (path_pattern )
277
- if matches :
278
- # Use the latest version
279
- latest = sorted (matches )[- 1 ]
280
- if os .path .exists (latest ):
281
- print (f"Using brew protobuf include: { latest } " )
282
- return latest
283
- else :
284
- if os .path .exists (path_pattern ):
285
- print (f"Using brew protobuf include: { path_pattern } " )
286
- return path_pattern
276
+ # Check protobuf@29 second (version 29.4)
277
+ protobuf_29_include = "/opt/homebrew/opt/protobuf@29/include"
278
+ if os .path .exists (protobuf_29_include ):
279
+ print (f"Using protobuf@29 include: { protobuf_29_include } " )
280
+ return protobuf_29_include
281
+
282
+ # Fallback to common brew location
283
+ common_paths = [
284
+ "/opt/homebrew/include" ,
285
+ "/usr/local/include" ,
286
+ "/opt/homebrew/Cellar/protobuf/*/include"
287
+ ]
288
+
289
+ for path_pattern in common_paths :
290
+ if "*" in path_pattern :
291
+ # Handle wildcard pattern
292
+ import glob
293
+ matches = glob .glob (path_pattern )
294
+ if matches :
295
+ # Use the latest version
296
+ latest = sorted (matches )[- 1 ]
297
+ if os .path .exists (latest ):
298
+ print (f"Using brew protobuf include: { latest } " )
299
+ return latest
300
+ else :
301
+ if os .path .exists (path_pattern ):
302
+ print (f"Using brew protobuf include: { path_pattern } " )
303
+ return path_pattern
304
+
305
+ # Linux paths
306
+ elif platform .system ().lower () == 'linux' :
307
+ # Common Linux protobuf include paths
308
+ linux_paths = [
309
+ "/usr/include" ,
310
+ "/usr/local/include" ,
311
+ "/opt/protobuf/include" ,
312
+ "/usr/share/protobuf/include"
313
+ ]
314
+
315
+ for path in linux_paths :
316
+ if os .path .exists (path ):
317
+ print (f"Using Linux protobuf include: { path } " )
318
+ return path
287
319
288
320
return None
289
321
@@ -362,9 +394,6 @@ def generate_protobuf_files(temp_proto_dir: Path, output_dir: Path, project_root
362
394
else :
363
395
print ("Warning: grpc_python_plugin not found, skipping gRPC code generation" )
364
396
365
- # Find brew protobuf include directory
366
- brew_include = find_brew_protobuf_include (project_root )
367
-
368
397
# Generate Python files for each proto file
369
398
for proto_file in proto_files :
370
399
# Get relative path from temp proto directory
@@ -378,12 +407,7 @@ def generate_protobuf_files(temp_proto_dir: Path, output_dir: Path, project_root
378
407
f"--proto_path={ temp_proto_dir } " ,
379
408
]
380
409
381
- # Add brew protobuf include path if available
382
- if brew_include :
383
- cmd .append (f"--proto_path={ brew_include } " )
384
- else :
385
- # Fallback to local include directory
386
- cmd .append (f"--proto_path={ project_root } /include" )
410
+ cmd .append (f"--proto_path={ project_root } /include" )
387
411
388
412
cmd .append (str (proto_file ))
389
413
@@ -404,12 +428,7 @@ def generate_protobuf_files(temp_proto_dir: Path, output_dir: Path, project_root
404
428
f"--proto_path={ temp_proto_dir } " ,
405
429
]
406
430
407
- # Add brew protobuf include path if available
408
- if brew_include :
409
- grpc_cmd .append (f"--proto_path={ brew_include } " )
410
- else :
411
- # Fallback to local include directory
412
- grpc_cmd .append (f"--proto_path={ project_root } /include" )
431
+ grpc_cmd .append (f"--proto_path={ project_root } /include" )
413
432
414
433
grpc_cmd .append (str (proto_file ))
415
434
@@ -428,12 +447,7 @@ def generate_protobuf_files(temp_proto_dir: Path, output_dir: Path, project_root
428
447
f"--proto_path={ temp_proto_dir } " ,
429
448
]
430
449
431
- # Add brew protobuf include path if available
432
- if brew_include :
433
- grpc_cmd .append (f"--proto_path={ brew_include } " )
434
- else :
435
- # Fallback to local include directory
436
- grpc_cmd .append (f"--proto_path={ project_root } /include" )
450
+ grpc_cmd .append (f"--proto_path={ project_root } /include" )
437
451
438
452
grpc_cmd .append (str (proto_file ))
439
453
0 commit comments