Ver código fonte

Fix cmake build for macOS 12.3 where `python` no longer exists. (#9477)

Denver Coneybeare 4 anos atrás
pai
commit
bffb108542

+ 4 - 2
Firestore/Protos/CMakeLists.txt

@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+include(FindPythonInterp)
+
 # Generate output in-place. So long as the build is idempotent this helps
 # verify that the protoc-generated output isn't changing.
 set(OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
@@ -197,7 +199,7 @@ if(FIREBASE_IOS_PROTOC_GENERATE_SOURCES)
     COMMENT "Generating nanopb sources"
     OUTPUT ${NANOPB_GENERATED_SOURCES}
     COMMAND
-      python
+      ${PYTHON_EXECUTABLE}
         ${CMAKE_CURRENT_SOURCE_DIR}/build_protos.py
         --nanopb
         --protoc=$<TARGET_FILE:protoc>
@@ -229,7 +231,7 @@ if(FIREBASE_IOS_PROTOC_GENERATE_SOURCES)
     COMMENT "Generating C++ protobuf sources"
     OUTPUT ${PROTOBUF_CPP_GENERATED_SOURCES}
     COMMAND
-      python
+      ${PYTHON_EXECUTABLE}
         ${CMAKE_CURRENT_SOURCE_DIR}/build_protos.py
         --cpp
         --protoc=$<TARGET_FILE:protoc>

+ 49 - 5
Firestore/Protos/build_protos.py

@@ -22,11 +22,15 @@ from __future__ import print_function
 import sys
 
 import argparse
+import contextlib
 import datetime
+import io
 import os
 import os.path
 import re
+import stat
 import subprocess
+import tempfile
 
 
 CPP_GENERATOR = 'nanopb_cpp_generator.py'
@@ -104,6 +108,46 @@ def main():
     ObjcProtobufGenerator(args, proto_files).run()
 
 
+@contextlib.contextmanager
+def CppGeneratorScriptTweaked(path):
+  """
+  Set the shebang line of the CPP_GENERATOR script to use the same Python
+  interpreter as this process.
+
+  This is a workaround for the fact that `python` is hardcoded as the python
+  interpreter, which does not always exist in the new world where Python2
+  support has largely disappeared (e.g. macOS 12.3). Changing it to `python3`
+  would possibly break some builds too.
+  """
+  # Read the script into memory.
+  with io.open(path, 'rt', encoding='utf8') as f:
+    lines = [line for line in f]
+
+  # Verify that the read file looks like the right one.
+  if lines[0] != u'#!/usr/bin/env python\n':
+    raise RuntimeError('unexpected first line of ' + path + ': ' + lines[0])
+
+  # Replace the shebang line with a custom one.
+  lines[0] = u'#!' + sys.executable + u'\n'
+
+  # Create a temporary file to which to write the tweaked script.
+  (handle, temp_path) = tempfile.mkstemp('.py', dir=os.path.dirname(path))
+  os.close(handle)
+
+  try:
+    # Write the lines of the tweaked script to the temporary file.
+    with io.open(temp_path, 'wt', encoding='utf8') as f:
+      f.writelines(lines)
+
+    # Make sure that the temporary file is executable.
+    st = os.stat(temp_path)
+    os.chmod(temp_path, st.st_mode | stat.S_IEXEC)
+
+    yield temp_path
+  finally:
+    os.unlink(temp_path)
+
+
 class NanopbGenerator(object):
   """Builds and runs the nanopb plugin to protoc."""
 
@@ -130,9 +174,6 @@ class NanopbGenerator(object):
     """Invokes protoc using the nanopb plugin."""
     cmd = protoc_command(self.args)
 
-    gen = os.path.join(os.path.dirname(__file__), CPP_GENERATOR)
-    cmd.append('--plugin=protoc-gen-nanopb=%s' % gen)
-
     nanopb_flags = ' '.join([
         '--extension=.nanopb',
         '--source-extension=.cc',
@@ -146,8 +187,11 @@ class NanopbGenerator(object):
     ])
     cmd.append('--nanopb_out=%s:%s' % (nanopb_flags, out_dir))
 
-    cmd.extend(self.proto_files)
-    run_protoc(self.args, cmd)
+    gen = os.path.join(os.path.dirname(__file__), CPP_GENERATOR)
+    with CppGeneratorScriptTweaked(gen) as gen_tweaked:
+      cmd.append('--plugin=protoc-gen-nanopb=%s' % gen_tweaked)
+      cmd.extend(self.proto_files)
+      run_protoc(self.args, cmd)
 
 
 class ObjcProtobufGenerator(object):

+ 2 - 1
Firestore/core/CMakeLists.txt

@@ -14,6 +14,7 @@
 
 include(CheckSymbolExists)
 include(CheckIncludeFiles)
+include(FindPythonInterp)
 
 
 ## firestore_util
@@ -285,7 +286,7 @@ add_custom_command(
   OUTPUT
   ${GRPC_ROOT_CERTIFICATE_SOURCES}
   COMMAND
-  python ${FIREBASE_SOURCE_DIR}/scripts/binary_to_array.py
+  ${PYTHON_EXECUTABLE} ${FIREBASE_SOURCE_DIR}/scripts/binary_to_array.py
   --output_header=${OUTPUT_DIR}/grpc_root_certificates_generated.h
   --output_source=${OUTPUT_DIR}/grpc_root_certificates_generated.cc
   --cpp_namespace=firebase::firestore::remote