22
22
import sys
23
23
24
24
import argparse
25
+ import contextlib
25
26
import datetime
27
+ import io
26
28
import os
27
29
import os .path
28
30
import re
31
+ import stat
29
32
import subprocess
33
+ import tempfile
30
34
31
35
32
36
CPP_GENERATOR = 'nanopb_cpp_generator.py'
@@ -104,6 +108,46 @@ def main():
104
108
ObjcProtobufGenerator (args , proto_files ).run ()
105
109
106
110
111
+ @contextlib .contextmanager
112
+ def CppGeneratorScriptTweaked (path ):
113
+ """
114
+ Set the shebang line of the CPP_GENERATOR script to use the same Python
115
+ interpreter as this process.
116
+
117
+ This is a workaround for the fact that `python` is hardcoded as the python
118
+ interpreter, which does not always exist in the new world where Python2
119
+ support has largely disappeared (e.g. macOS 12.3). Changing it to `python3`
120
+ would possibly break some builds too.
121
+ """
122
+ # Read the script into memory.
123
+ with io .open (path , 'rt' , encoding = 'utf8' ) as f :
124
+ lines = [line for line in f ]
125
+
126
+ # Verify that the read file looks like the right one.
127
+ if lines [0 ] != u'#!/usr/bin/env python\n ' :
128
+ raise RuntimeError ('unexpected first line of ' + path + ': ' + lines [0 ])
129
+
130
+ # Replace the shebang line with a custom one.
131
+ lines [0 ] = u'#!' + sys .executable + u'\n '
132
+
133
+ # Create a temporary file to which to write the tweaked script.
134
+ (handle , temp_path ) = tempfile .mkstemp ('.py' , dir = os .path .dirname (path ))
135
+ os .close (handle )
136
+
137
+ try :
138
+ # Write the lines of the tweaked script to the temporary file.
139
+ with io .open (temp_path , 'wt' , encoding = 'utf8' ) as f :
140
+ f .writelines (lines )
141
+
142
+ # Make sure that the temporary file is executable.
143
+ st = os .stat (temp_path )
144
+ os .chmod (temp_path , st .st_mode | stat .S_IEXEC )
145
+
146
+ yield temp_path
147
+ finally :
148
+ os .unlink (temp_path )
149
+
150
+
107
151
class NanopbGenerator (object ):
108
152
"""Builds and runs the nanopb plugin to protoc."""
109
153
@@ -130,9 +174,6 @@ def __run_generator(self, out_dir):
130
174
"""Invokes protoc using the nanopb plugin."""
131
175
cmd = protoc_command (self .args )
132
176
133
- gen = os .path .join (os .path .dirname (__file__ ), CPP_GENERATOR )
134
- cmd .append ('--plugin=protoc-gen-nanopb=%s' % gen )
135
-
136
177
nanopb_flags = ' ' .join ([
137
178
'--extension=.nanopb' ,
138
179
'--source-extension=.cc' ,
@@ -146,8 +187,11 @@ def __run_generator(self, out_dir):
146
187
])
147
188
cmd .append ('--nanopb_out=%s:%s' % (nanopb_flags , out_dir ))
148
189
149
- cmd .extend (self .proto_files )
150
- run_protoc (self .args , cmd )
190
+ gen = os .path .join (os .path .dirname (__file__ ), CPP_GENERATOR )
191
+ with CppGeneratorScriptTweaked (gen ) as gen_tweaked :
192
+ cmd .append ('--plugin=protoc-gen-nanopb=%s' % gen_tweaked )
193
+ cmd .extend (self .proto_files )
194
+ run_protoc (self .args , cmd )
151
195
152
196
153
197
class ObjcProtobufGenerator (object ):
0 commit comments