[PATCH 2 of 2 STABLE] setup: search for proper library name on MinGW/msys2

Gregory Szorc gregory.szorc at gmail.com
Tue Apr 26 19:25:56 EDT 2016

# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1461712815 25200
#      Tue Apr 26 16:20:15 2016 -0700
# Branch stable
# Node ID a42a7f71b89a026572f8ce798fa2c2bbaf6dea3a
# Parent  ba89075c616d56c3f1ce02c97103c6d0ff8aa006
setup: search for proper library name on MinGW/msys2

Attempting to build Mercurial from source using MinGW from
msys2 on Windows produces a hg.exe that attempts to load e.g.
python27.dll. MinGW prefixes its library name with "lib" and
adds a period between the major and minor versions. e.g.

Before this patch, hg.exe files in a MinGW environment would
either fail to find a Python DLL or would attempt to load a
non-MinGW DLL, which would summarily explode. Either way,
hg.exe wouldn't work.

This patch changes builds so hg.exe produced by MinGW will
search for "libpythonX.Y" instead of "pythonXY" in hopes that
MinGW will find a matching library.

It is certainly possible to build Mercurial in a MinGW environment
but want to load against a non-MinGW Python. This patch will
likely break that configuration. I build the Mercurial wheels in
cmd.exe (not MinGW) so this doesn't impact me. I'm not sure what
other packagers do on Windows. If we need the ability to build under
MinGW but targeting the traditional library name, we can likely
make that configurable.

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -364,18 +364,24 @@ class buildhgexe(build_ext):
     description = 'compile hg.exe from mercurial/exewrapper.c'
     def build_extensions(self):
         if os.name != 'nt':
         if isinstance(self.compiler, HackedMingw32CCompiler):
             self.compiler.compiler_so = self.compiler.compiler # no -mdll
             self.compiler.dll_libraries = [] # no -lmsrvc90
+        # The official CPython distribution on Windows uses e.g. python27 as
+        # the library name. MinGW uses e.g. libpython2.7.
+        if os.environ.get('MSYSTEM') in ('MINGW32', 'MINGW64'):
+            libpattern = 'libpython%d.%d.dll'
+        else:
+            libpattern = 'python%d%d.dll'
         hv = sys.hexversion
-        pythonlib = 'python%d%d.dll' % (hv >> 24, (hv >> 16) & 0xff)
+        pythonlib = libpattern % (hv >> 24, (hv >> 16) & 0xff)
         with open('mercurial/hgpythonlib.h', 'wb') as f:
             f.write('/* this file is autogenerated by setup.py */\n')
             f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
         objects = self.compiler.compile(['mercurial/exewrapper.c'],
         dir = os.path.dirname(self.get_ext_fullpath('dummy'))
         target = os.path.join(dir, 'hg')
         self.compiler.link_executable(objects, target,

More information about the Mercurial-devel mailing list