Patchwork D9362: setup: copy pythonXY.dll next to the hg.exe wrapper when building

login
register
mail settings
Submitter phabricator
Date Nov. 21, 2020, 9:22 p.m.
Message ID <differential-rev-PHID-DREV-foquf6luzfmr3mwdaeru-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47641/
State Superseded
Headers show

Comments

phabricator - Nov. 21, 2020, 9:22 p.m.
mharbison72 created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This avoids the problem of having the newly built binary complaining that it
  can't find the DLL.  There is an option in the python.org installer to add the
  python install to PATH (which defaulted to "on" with py2, and therefore was not
  an issue up to this point), but that makes switching between python versions
  harder.
  
  This shouldn't be an issue with the PyOxidizer binary, but that current has
  issues running some of the tests, and took noticeably longer to build last time
  I tried it.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9362

AFFECTED FILES
  setup.py

CHANGE DETAILS




To: mharbison72, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -782,6 +782,9 @@ 
 
         pythonlib = None
 
+        dir = os.path.dirname(self.get_ext_fullpath('dummy'))
+        self.hgtarget = os.path.join(dir, 'hg')
+
         if getattr(sys, 'dllhandle', None):
             # Different Python installs can have different Python library
             # names. e.g. the official CPython distribution uses pythonXY.dll
@@ -807,6 +810,19 @@ 
                     )
                 pythonlib = dllbasename[:-4]
 
+                # Copy the pythonXY.dll next to the binary so that it runs
+                # without tampering with PATH.
+                fsdecode = lambda x: x
+                if sys.version_info[0] >= 3:
+                    fsdecode = os.fsdecode
+                dest = os.path.join(
+                    os.path.dirname(self.hgtarget),
+                    fsdecode(dllbasename),
+                )
+
+                if not os.path.exists(dest):
+                    shutil.copy(buf.value, dest)
+
         if not pythonlib:
             log.warn(
                 'could not determine Python DLL filename; assuming pythonXY'
@@ -829,8 +845,6 @@ 
             output_dir=self.build_temp,
             macros=macros,
         )
-        dir = os.path.dirname(self.get_ext_fullpath('dummy'))
-        self.hgtarget = os.path.join(dir, 'hg')
         self.compiler.link_executable(
             objects, self.hgtarget, libraries=[], output_dir=self.build_temp
         )