8000 Backport 7963, BUG: MSVCCompiler grows 'lib' & 'include' env strings exponentially. by charris · Pull Request #7972 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

Backport 7963, BUG: MSVCCompiler grows 'lib' & 'include' env strings exponentially. #7972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
BUG: MSVCCompiler grows 'lib' & 'include' env strings exponentially.
Each time an MSVCCompiler was instantiated the old values of
os.environ['lib'] and os.environ['include'] were concatenated to the new
values set by initializing the distutils.msvc{,9}compiler.MSVCCompiler
base class.  Consequently when the  the old and new values of those
variables were the same, they doubled in size with each instantiation,
leading to quickly hitting the 32,768 character limit.
  • Loading branch information
charris committed Aug 25, 2016
commit 78eba2f368f11a9c6e9a10cdd213df4bba050c70
62 changes: 50 additions & 12 deletions numpy/distutils/msvc9compiler.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,63 @@
from __future__ import division, absolute_import, print_function

import os
import distutils.msvc9compiler
from distutils.msvc9compiler import *
from distutils.msvc9compiler import MSVCCompiler as _MSVCCompiler


class MSVCCompiler(distutils.msvc9compiler.MSVCCompiler):
def _merge(old, new):
"""Concatenate two environment paths avoiding repeats.

Here `old` is the environment string before the base class initialize
function is called and `new` is the string after the call. The new string
will be a fixed string if it is not obtained from the current enviroment,
or the same as the old string if obtained from the same enviroment. The aim
here is not to append the new string if it is already contained in the old
string so as to limit the growth of the environment string.

Parameters
----------
old : string
Previous enviroment string.
new : string
New environment string.

Returns
-------
ret : string
Updated environment string.

"""
if new in old:
return old
if not old:
return new

# Neither new nor old is empty. Give old priority.
return ';'.join([old, new])


class MSVCCompiler(_MSVCCompiler):
def __init__(self, verbose=0, dry_run=0, force=0):
distutils.msvc9compiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
_MSVCCompiler.__init__(self, verbose, dry_run, force)

def initialize(self, plat_name=None):
# The 'lib' and 'include' variables may be overwritten
# by MSVCCompiler.initialize, so save them for later merge.
environ_lib = os.getenv('lib')
environ_include = os.getenv('include')
distutils.msvc9compiler.MSVCCompiler.initialize(self, plat_name)
if environ_lib is not None:
os.environ['lib'] = environ_lib + os.environ['lib']
if environ_include is not None:
os.environ['include'] = environ_include + os.environ['include']
_MSVCCompiler.initialize(self, plat_name)

# Merge current and previous values of 'lib' and 'include'
os.environ['lib'] = _merge(environ_lib, os.environ['lib'])
os.environ['include'] = _merge(environ_include, os.environ['include'])

# msvc9 building for 32 bits requires SSE2 to work around a
# compiler bug.
if platform_bits == 32:
self.compile_options += ['/arch:SSE2']
self.compile_options_debug += ['/arch:SSE2']

def manifest_setup_ldargs(self, output_filename, build_temp, ld_args):
ld_args.append('/MANIFEST')
distutils.msvc9compiler.MSVCCompiler.manifest_setup_ldargs(self,
output_filename,
build_temp, ld_args)
_MSVCCompiler.manifest_setup_ldargs(self, output_filename,
build_temp, ld_args)
60 changes: 47 additions & 13 deletions numpy/distutils/msvccompiler.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,60 @@
from __future__ import division, absolute_import, print_function

import os
import distutils.msvccompiler
from distutils.msvccompiler import *
from distutils.msvccompiler import MSVCCompiler as _MSVCCompiler

from .system_info import platform_bits


class MSVCCompiler(distutils.msvccompiler.MSVCCompiler):
def _merge(old, new):
"""Concatenate two environment paths avoiding repeats.

Here `old` is the environment string before the base class initialize
function is called and `new` is the string after the call. The new string
will be a fixed string if it is not obtained from the current enviroment,
or the same as the old string if obtained from the same enviroment. The aim
here is not to append the new string if it is already contained in the old
string so as to limit the growth of the environment string.

Parameters
----------
old : string
Previous enviroment string.
new : string
New environment string.

Returns
-------
ret : string
Updated environment string.

"""
if new in old:
return old
if not old:
return new

# Neither new nor old is empty. Give old priority.
return ';'.join([old, new])


class MSVCCompiler(_MSVCCompiler):
def __init__(self, verbose=0, dry_run=0, force=0):
distutils.msvccompiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
_MSVCCompiler.__init__(self, verbose, dry_run, force)

def initialize(self, plat_name=None):
environ_lib = os.getenv('lib')
environ_include = os.getenv('include')
distutils.msvccompiler.MSVCCompiler.initialize(self, plat_name)
if environ_lib is not None:
os.environ['lib'] = environ_lib + os.environ['lib']
if environ_include is not None:
os.environ['include'] = environ_include + os.environ['include']
# The 'lib' and 'include' variables may be overwritten
# by MSVCCompiler.initialize, so save them for later merge.
environ_lib = os.getenv('lib', '')
environ_include = os.getenv('include', '')
_MSVCCompiler.initialize(self, plat_name)

# Merge current and previous values of 'lib' and 'include'
os.environ['lib'] = _merge(environ_lib, os.environ['lib'])
os.environ['include'] = _merge(environ_include, os.environ['include'])

# msvc9 building for 32 bits requires SSE2 to work around a
# compiler bug.
if platform_bits == 32:
# msvc9 building for 32 bits requires SSE2 to work around a
# compiler bug.
self.compile_options += ['/arch:SSE2']
self.compile_options_debug += ['/arch:SSE2']
0