Patchwork setup: avoid linker warnings on Windows about multiple export specifications

login
register
mail settings
Submitter Matt Harbison
Date June 10, 2017, 5:43 a.m.
Message ID <b8fb7b6aee991827664f.1497073380@Envy>
Download mbox | patch
Permalink /patch/21303/
State Accepted
Headers show

Comments

Matt Harbison - June 10, 2017, 5:43 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1497060953 14400
#      Fri Jun 09 22:15:53 2017 -0400
# Node ID b8fb7b6aee991827664f15ae5fe1c7064ce883d6
# Parent  776d077eb4ef815e08631fb1e7b33375adca3ef1
setup: avoid linker warnings on Windows about multiple export specifications

The PyMODINIT_FUNC macro contains __declspec(dllexport), and then the build
process adds an "/EXPORT func" to the command line.  The 64-bit linker flags
this [1].

Everything except zstd.c and bser.c are covered by redefining the macro in
util.h [2].  These modules aren't built with util.h in the #include path, so the
redefining hack would have to be open coded two more times.

After seeing that extra_linker_flags didn't work, I couldn't find anything
authoritative indicating why, though I did see an offhand comment on SO that
CFLAGS is also ignored on Windows.  I also don't fully understand the
interaction between msvccompiler and msvc9compiler- I first subclassed the
latter, but it isn't used when building with VS2008.

I know the camelcase naming isn't the standard, but the HackedMingw32CCompiler
class above it was introduced 5 years ago (and I think the current style was
in place by then), so I assume that there's some reason for it.

[1] https://support.microsoft.com/en-us/help/835326/you-receive-an-lnk4197-error-in-the-64-bit-version-of-the-visual-c-compiler
[2] https://bugs.python.org/issue9709#msg120859
Matt Harbison - June 10, 2017, 5:51 a.m.
On Sat, 10 Jun 2017 01:43:00 -0400, Matt Harbison <mharbison72@gmail.com>  
wrote:

> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1497060953 14400
> #      Fri Jun 09 22:15:53 2017 -0400
> # Node ID b8fb7b6aee991827664f15ae5fe1c7064ce883d6
> # Parent  776d077eb4ef815e08631fb1e7b33375adca3ef1
> setup: avoid linker warnings on Windows about multiple export  
> specifications

The remaining warnings are:

mercurial/cext/revlog.c(282) : warning C4244: '+=' : conversion from  
'Py_ssize_t' to 'int', possible loss of data
mercurial/cext/revlog.c(317) : warning C4090: 'function' : different  
'const' qualifiers
mercurial/cext/revlog.c(452) : warning C4244: '=' : conversion from  
'Py_ssize_t' to 'char', possible loss of data
mercurial/cext/revlog.c(604) : warning C4244: 'function' : conversion from  
'Py_ssize_t' to 'long', possible loss of data
mercurial/cext/revlog.c(697) : warning C4244: 'function' : conversion from  
'Py_ssize_t' to 'long', possible loss of data

I don't see them on either Linux or Mac.

It seems like distutils redirects the compiler's stderr to stdout.  Is  
there any easy way to convince it not to?  They would be easier to spot  
then with `make local > /dev/null`, but I suppose grep works too.
Yuya Nishihara - June 12, 2017, 1:05 p.m.
On Sat, 10 Jun 2017 01:43:00 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1497060953 14400
> #      Fri Jun 09 22:15:53 2017 -0400
> # Node ID b8fb7b6aee991827664f15ae5fe1c7064ce883d6
> # Parent  776d077eb4ef815e08631fb1e7b33375adca3ef1
> setup: avoid linker warnings on Windows about multiple export specifications

Seems fine. Queued, thanks.

Patch

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -704,6 +704,23 @@ 
     class HackedMingw32CCompiler(object):
         pass
 
+if os.name == 'nt':
+    # Allow compiler/linker flags to be added to Visual Studio builds.  Passing
+    # extra_link_args to distutils.extensions.Extension() doesn't have any
+    # effect.
+    from distutils import msvccompiler
+
+    compiler = msvccompiler.MSVCCompiler
+
+    class HackedMSVCCompiler(msvccompiler.MSVCCompiler):
+        def initialize(self):
+            compiler.initialize(self)
+            # "warning LNK4197: export 'func' specified multiple times"
+            self.ldflags_shared.append('/ignore:4197')
+            self.ldflags_shared_debug.append('/ignore:4197')
+
+    msvccompiler.MSVCCompiler = HackedMSVCCompiler
+
 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
                              'help/*.txt',
                              'help/internals/*.txt',