Skip to content

MinGW enhancements for datetime functionality. #156

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

Closed
wants to merge 11 commits into from
90 changes: 84 additions & 6 deletions numpy/distutils/mingw32ccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ def __init__ (self,

build_import_library()

# Check for custom msvc runtime library on Windows. Build if it doesn't exist.
msvcr_success = build_msvcr_library()
msvcr_dbg_success = build_msvcr_library(debug=True)
if msvcr_success or msvcr_dbg_success:
# add preprocessor statement for using customized msvcr lib
self.define_macro('NPY_MINGW_USE_CUSTOM_MSVCR')

# Define the MSVC version as hint for MinGW
msvcr_version = '0x%03i0' % int(msvc_runtime_library().lstrip('msvcr'))
self.define_macro('__MSVCRT_VERSION__', msvcr_version)

# **changes: eric jones 4/11/01
# 2. increased optimization and turned off all warnings
# 3. also added --driver-name g++
Expand All @@ -104,7 +115,7 @@ def __init__ (self,
# bad consequences, like using Py_ModuleInit4 instead of
# Py_ModuleInit4_64, etc... So we add it here
if get_build_architecture() == 'AMD64':
if self.gcc_version < "4.":
if self.gcc_version < "4.0":
self.set_executables(
compiler='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall',
compiler_so='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall -Wstrict-prototypes',
Expand All @@ -124,7 +135,7 @@ def __init__ (self,
linker_exe='g++ -mno-cygwin',
linker_so='%s -mno-cygwin -mdll -static %s'
% (self.linker, entry_point))
elif self.gcc_version < "4.":
elif self.gcc_version < "4.0":
self.set_executables(compiler='gcc -mno-cygwin -O2 -Wall',
compiler_so='gcc -mno-cygwin -O2 -Wall -Wstrict-prototypes',
linker_exe='g++ -mno-cygwin',
Expand Down Expand Up @@ -263,15 +274,14 @@ def generate_def(dll, dfile):
The .def file will be overwritten"""
dump = dump_table(dll)
for i in range(len(dump)):
if _START.match(dump[i]):
if _START.match(dump[i].decode()):
break

if i == len(dump):
else:
raise ValueError("Symbol table not found")

syms = []
for j in range(i+1, len(dump)):
m = _TABLE.match(dump[j])
m = _TABLE.match(dump[j].decode())
if m:
syms.append((int(m.group(1).strip()), m.group(2)))
else:
Expand All @@ -290,6 +300,74 @@ def generate_def(dll, dfile):
d.write('%s\n' % s[1])
d.close()

def find_dll(dll_name):

def _find_dll_in_winsxs(dll_name):
# Walk through the WinSxS directory to find the dll.
winsxs_path = os.path.join(os.environ['WINDIR'], 'winsxs')
if not os.path.exists(winsxs_path):
return None
for root, dirs, files in os.walk(winsxs_path):
if dll_name in files:
return os.path.join(root, dll_name)
return None

def _find_dll_in_path(dll_name):
# First, look in the Python directory, then scan PATH for
# the given dll name.
for path in [sys.prefix] + os.environ['PATH'].split(';'):
filepath = os.path.join(path, dll_name)
if os.path.exists(filepath):
return os.path.abspath(filepath)

return _find_dll_in_winsxs(dll_name) or _find_dll_in_path(dll_name)

def build_msvcr_library(debug=False):
if os.name != 'nt':
return False

msvcr_name = msvc_runtime_library()

# Skip using a custom library for versions < MSVC 8.0
if int(msvcr_name.lstrip('msvcr')) < 80:
log.debug('Skip building msvcr library: custom functionality not present')
return False

if debug:
msvcr_name += 'd'

# Skip if custom library already exists
out_name = "lib%s.a" % msvcr_name
out_file = os.path.join(sys.prefix, 'libs', out_name)
if os.path.isfile(out_file):
log.debug('Skip building msvcr library: "%s" exists' % (out_file))
return True

# Find the msvcr dll
msvcr_dll_name = msvcr_name + '.dll'
dll_file = find_dll(msvcr_dll_name)
if not dll_file:
log.warn('Cannot build msvcr library: "%s" not found' % msvcr_dll_name)
return False

def_name = "lib%s.def" % msvcr_name
def_file = os.path.join(sys.prefix, 'libs', def_name)

log.info('Building msvcr library: "%s" (from %s)' \
% (out_file, dll_file))

# Generate a symbol definition file from the msvcr dll
generate_def(dll_file, def_file)

# Create a custom mingw library for the given symbol definitions
cmd = ['dlltool', '-d', def_file, '-l', out_file]
retcode = subprocess.call(cmd)

# Clean up symbol definitions
os.remove(def_file)

return (not retcode)

def build_import_library():
if os.name != 'nt':
return
Expand Down