makefile: pick Python that is more likely to build with setup.py

Summary:
The `python` in `PATH` might be the fbcode Python that has `-nostdinc` in its
`CFLAGS`. That Python is problematic because it cannot compile C extensions.

Reviewed By: DurhamG, markbt

Differential Revision: D27661488

fbshipit-source-id: 243205522fcaf53d5af6a3c9afc4d28160072de5
This commit is contained in:
Jun Wu 2021-04-08 14:19:18 -07:00 committed by Facebook GitHub Bot
parent 09fb4128a5
commit db8f90ea76
2 changed files with 54 additions and 2 deletions

View File

@ -65,7 +65,7 @@ help:
all: build
local:
$(PYTHON) setup.py $(PURE) \
$(shell $(PYTHON) contrib/pick_python.py $(PYTHON)) setup.py $(PURE) \
build_py -c -d . \
build_clib $(COMPILERFLAG) \
build_ext $(COMPILERFLAG) -i \
@ -80,7 +80,7 @@ else
endif
local3:
HGNAME=$(HGNAME3) $(PYTHON3) setup3.py $(PURE) \
HGNAME=$(HGNAME3) $(shell $(PYTHON3) contrib/pick_python.py $(PYTHON3)) setup3.py $(PURE) \
build_py -c -d . \
build_clib $(COMPILERFLAG) \
build_ext $(COMPILERFLAG) -i \

View File

@ -0,0 +1,52 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2.
"""
Pick a Python that is more likely to be able to build with setup.py.
Arguments: Binary name (ex. python2, or python3).
Stdout: Full path to a system python, or the first argument of the input.
This script does not need to be executed using a system Python.
"""
import os
import subprocess
import sys
def main(args):
dirs = os.environ.get("PATH").split(os.pathsep)
names = args or ["python3"]
for dir in dirs:
for name in names:
path = os.path.join(dir, name)
if does_python_look_good(path):
sys.stdout.write(path)
return
# Fallback
sys.stdout.write(names[0])
def does_python_look_good(path):
if not os.path.isfile(path):
return False
try:
cflags = subprocess.check_output(
[path, "-c", "import sysconfig;print(sysconfig.get_config_var('CFLAGS'))"]
)
if b"-nostdinc" in cflags.split():
sys.stderr.write("%s: ignored, lack of C stdlib\n" % path)
return False
return True
except Exception:
return False
if __name__ == "__main__":
code = main(sys.argv[1:]) or 0
sys.stderr.flush()
sys.stdout.flush()
sys.exit(code)