Skip to content

Commit 6dab130

Browse files
committed
Add option to regenerate sysconfig in broken build environments.
Also add option to print waf's config.log on error. (cherry picked from commit a2f6c4b)
1 parent 6a4dc56 commit 6dab130

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

build.py

+54-1
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ def makeOptionParser():
447447
("pytest_timeout", ("0", "Timeout, in seconds, for stopping stuck test cases. (Currently not working as expected, so disabled by default.)")),
448448
("pytest_jobs", ("", "Number of parallel processes py.test should run")),
449449
("vagrant_vms", ("all", "Comma separated list of VM names to use for the build_vagrant command. Defaults to \"all\"")),
450+
("dump_waf_log", (False, "If the waf build tool fails then using this option will cause waf's configure log to be printed")),
451+
("regenerate_sysconfig", (False, "Waf uses Python's sysconfig and related tools to configure the build. In some cases that info can be incorrect, so this option regenerates it. Must have write access to Python's lib folder.")),
450452
]
451453

452454
parser = optparse.OptionParser("build options:")
@@ -876,6 +878,40 @@ def bash2dosPath(path):
876878
path = components[1] + ':/' + '/'.join(components[2:])
877879
return path
878880

881+
882+
def do_regenerate_sysconfig():
883+
"""
884+
If a Python environment has been relocated to a new folder then it's
885+
possible that the sysconfig can still be usign paths for the original
886+
location. Since wxPython's build uses WAF, which uses the sysconfig (via
887+
python-config, distutils.sysconfig, etc.) then we need to ensure that these
888+
paths match the current environment.
889+
890+
TODO: Can this be done in a way that doesn't require overwriting a file in
891+
the environment?
892+
"""
893+
with tempfile.TemporaryDirectory() as td:
894+
pwd = pushDir(td)
895+
896+
# generate a new sysconfig data file
897+
cmd = [PYTHON, '-m', 'sysconfig', '--generate-posix-vars']
898+
runcmd(cmd)
899+
900+
# On success the new data module will have been written to a subfolder
901+
# of the current folder, which is recorded in ./pybuilddir.tx
902+
with open('pybuilddir.txt', 'r', encoding='utf-8') as fp:
903+
pybd = fp.read()
904+
905+
# grab the file in that folder and copy it into the Python lib
906+
p = opj(td, pybd, '*')
907+
datafile = glob.glob(opj(td, pybd, '*'))[0]
908+
cmd = [PYTHON, '-c', 'import sysconfig; print(sysconfig.get_path("stdlib"))']
909+
stdlib = runcmd(cmd, getOutput=True)
910+
shutil.copy(datafile, stdlib)
911+
912+
del pwd
913+
914+
879915
#---------------------------------------------------------------------------
880916
# Command functions and helpers
881917
#---------------------------------------------------------------------------
@@ -1533,10 +1569,27 @@ def cmd_build_py(options, args):
15331569
# folder as the wxPython extension modules.
15341570
os.environ['LD_RUN_PATH'] = '$ORIGIN'
15351571

1572+
# Regenerate the _sysconfigdata module?
1573+
if options.regenerate_sysconfig:
1574+
do_regenerate_sysconfig()
1575+
15361576
# Run waf to perform the builds
15371577
pwd = pushDir(phoenixDir())
15381578
cmd = '"%s" %s %s configure build %s' % (PYTHON, waf, ' '.join(build_options), options.extra_waf)
1539-
runcmd(cmd)
1579+
1580+
def _onWafError():
1581+
if options.dump_waf_log:
1582+
logfilename = opj(wafBuildDir, 'config.log')
1583+
if not os.path.exists(logfilename):
1584+
msg('WARNING: waf log "{}" not found!'.format(logfilename))
1585+
return
1586+
1587+
msg('*-'*40)
1588+
msg('WAF config log "{}":'.format(logfilename))
1589+
with open(logfilename, 'r') as log:
1590+
msg(log.read())
1591+
msg('*-'*40)
1592+
runcmd(cmd, onError=_onWafError)
15401593

15411594
if isWindows and options.both:
15421595
build_options.remove('--debug')

buildtools/config.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ def _getGitRevision():
825825
return svnrev
826826

827827

828-
def runcmd(cmd, getOutput=False, echoCmd=True, fatal=True):
828+
def runcmd(cmd, getOutput=False, echoCmd=True, fatal=True, onError=None):
829829
"""
830830
Runs a give command-line command, optionally returning the output.
831831
"""
@@ -867,6 +867,8 @@ def runcmd(cmd, getOutput=False, echoCmd=True, fatal=True):
867867
print("Command '%s' failed with exit code %d." % (cmd, rval))
868868
if getOutput:
869869
print(output)
870+
if onError is not None:
871+
onError()
870872
if fatal:
871873
sys.exit(rval)
872874

0 commit comments

Comments
 (0)