Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
setuptools
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
setuptools
Commits
acb3d0ae
Commit
acb3d0ae
authored
Sep 09, 2015
by
Larry Hastings
Browse files
Options
Browse Files
Download
Plain Diff
Merge from 3.5.
parents
2c9d9365
465364f3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
119 additions
and
18 deletions
+119
-18
_msvccompiler.py
_msvccompiler.py
+63
-13
tests/test_msvccompiler.py
tests/test_msvccompiler.py
+56
-5
No files found.
_msvccompiler.py
View file @
acb3d0ae
...
...
@@ -14,6 +14,8 @@ for older versions in distutils.msvc9compiler and distutils.msvccompiler.
# ported to VS 2015 by Steve Dower
import
os
import
shutil
import
stat
import
subprocess
from
distutils.errors
import
DistutilsExecError
,
DistutilsPlatformError
,
\
...
...
@@ -25,7 +27,7 @@ from distutils.util import get_platform
import
winreg
from
itertools
import
count
def
_find_vcvarsall
():
def
_find_vcvarsall
(
plat_spec
):
with
winreg
.
OpenKeyEx
(
winreg
.
HKEY_LOCAL_MACHINE
,
r"Software\
Mic
rosoft\
Visu
alStudio\
SxS
\VC7"
,
...
...
@@ -33,7 +35,7 @@ def _find_vcvarsall():
)
as
key
:
if
not
key
:
log
.
debug
(
"Visual C++ is not registered"
)
return
None
return
None
,
None
best_version
=
0
best_dir
=
None
...
...
@@ -51,14 +53,23 @@ def _find_vcvarsall():
best_version
,
best_dir
=
version
,
vc_dir
if
not
best_version
:
log
.
debug
(
"No suitable Visual C++ version found"
)
return
None
return
None
,
None
vcvarsall
=
os
.
path
.
join
(
best_dir
,
"vcvarsall.bat"
)
if
not
os
.
path
.
isfile
(
vcvarsall
):
log
.
debug
(
"%s cannot be found"
,
vcvarsall
)
return
None
return
None
,
None
vcruntime
=
None
vcruntime_spec
=
_VCVARS_PLAT_TO_VCRUNTIME_REDIST
.
get
(
plat_spec
)
if
vcruntime_spec
:
vcruntime
=
os
.
path
.
join
(
best_dir
,
vcruntime_spec
.
format
(
best_version
))
if
not
os
.
path
.
isfile
(
vcruntime
):
log
.
debug
(
"%s cannot be found"
,
vcruntime
)
vcruntime
=
None
return
vcvarsall
return
vcvarsall
,
vcruntime
def
_get_vc_env
(
plat_spec
):
if
os
.
getenv
(
"DISTUTILS_USE_SDK"
):
...
...
@@ -67,7 +78,7 @@ def _get_vc_env(plat_spec):
for
key
,
value
in
os
.
environ
.
items
()
}
vcvarsall
=
_find_vcvarsall
(
)
vcvarsall
,
vcruntime
=
_find_vcvarsall
(
plat_spec
)
if
not
vcvarsall
:
raise
DistutilsPlatformError
(
"Unable to find vcvarsall.bat"
)
...
...
@@ -83,13 +94,17 @@ def _get_vc_env(plat_spec):
raise
DistutilsPlatformError
(
"Error executing {}"
.
format
(
exc
.
cmd
))
return
{
env
=
{
key
.
lower
():
value
for
key
,
_
,
value
in
(
line
.
partition
(
'='
)
for
line
in
out
.
splitlines
())
if
key
and
value
}
if
vcruntime
:
env
[
'py_vcruntime_redist'
]
=
vcruntime
return
env
def
_find_exe
(
exe
,
paths
=
None
):
"""Return path to an MSVC executable program.
...
...
@@ -115,6 +130,20 @@ PLAT_TO_VCVARS = {
'win-amd64'
:
'amd64'
,
}
# A map keyed by get_platform() return values to the file under
# the VC install directory containing the vcruntime redistributable.
_VCVARS_PLAT_TO_VCRUNTIME_REDIST
=
{
'x86'
:
'redist
\
\
x86
\
\
Microsoft.VC{0}0.CRT
\
\
vcruntime{0}0.dll'
,
'amd64'
:
'redist
\
\
x64
\
\
Microsoft.VC{0}0.CRT
\
\
vcruntime{0}0.dll'
,
'x86_amd64'
:
'redist
\
\
x64
\
\
Microsoft.VC{0}0.CRT
\
\
vcruntime{0}0.dll'
,
}
# A set containing the DLLs that are guaranteed to be available for
# all micro versions of this Python version. Known extension
# dependencies that are not in this set will be copied to the output
# path.
_BUNDLED_DLLS
=
frozenset
([
'vcruntime140.dll'
])
class
MSVCCompiler
(
CCompiler
)
:
"""Concrete class that implements an interface to Microsoft Visual C++,
as defined by the CCompiler abstract class."""
...
...
@@ -189,6 +218,7 @@ class MSVCCompiler(CCompiler) :
self
.
rc
=
_find_exe
(
"rc.exe"
,
paths
)
# resource compiler
self
.
mc
=
_find_exe
(
"mc.exe"
,
paths
)
# message compiler
self
.
mt
=
_find_exe
(
"mt.exe"
,
paths
)
# message compiler
self
.
_vcruntime_redist
=
vc_env
.
get
(
'py_vcruntime_redist'
,
''
)
for
dir
in
vc_env
.
get
(
'include'
,
''
).
split
(
os
.
pathsep
):
if
dir
:
...
...
@@ -199,20 +229,26 @@ class MSVCCompiler(CCompiler) :
self
.
add_library_dir
(
dir
)
self
.
preprocess_options
=
None
# Use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib
# If vcruntime_redist is available, link against it dynamically. Otherwise,
# use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib
# later to dynamically link to ucrtbase but not vcruntime.
self
.
compile_options
=
[
'/nologo'
,
'/Ox'
,
'/
MT'
,
'/
W3'
,
'/GL'
,
'/DNDEBUG'
'/nologo'
,
'/Ox'
,
'/W3'
,
'/GL'
,
'/DNDEBUG'
]
self
.
compile_options
.
append
(
'/MD'
if
self
.
_vcruntime_redist
else
'/MT'
)
self
.
compile_options_debug
=
[
'/nologo'
,
'/Od'
,
'/M
T
d'
,
'/Zi'
,
'/W3'
,
'/D_DEBUG'
'/nologo'
,
'/Od'
,
'/M
D
d'
,
'/Zi'
,
'/W3'
,
'/D_DEBUG'
]
ldflags
=
[
'/nologo'
,
'/INCREMENTAL:NO'
,
'/LTCG'
,
'/nodefaultlib:libucrt.lib'
,
'ucrt.lib'
,
'/nologo'
,
'/INCREMENTAL:NO'
,
'/LTCG'
]
if
not
self
.
_vcruntime_redist
:
ldflags
.
extend
((
'/nodefaultlib:libucrt.lib'
,
'ucrt.lib'
))
ldflags_debug
=
[
'/nologo'
,
'/INCREMENTAL:NO'
,
'/LTCG'
,
'/DEBUG:FULL'
,
'/nodefaultlib:libucrtd.lib'
,
'ucrtd.lib'
,
'/nologo'
,
'/INCREMENTAL:NO'
,
'/LTCG'
,
'/DEBUG:FULL'
]
self
.
ldflags_exe
=
[
*
ldflags
,
'/MANIFEST:EMBED,ID=1'
]
...
...
@@ -446,15 +482,29 @@ class MSVCCompiler(CCompiler) :
if
extra_postargs
:
ld_args
.
extend
(
extra_postargs
)
self
.
mkpath
(
os
.
path
.
dirname
(
output_filename
))
output_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
output_filename
))
self
.
mkpath
(
output_dir
)
try
:
log
.
debug
(
'Executing "%s" %s'
,
self
.
linker
,
' '
.
join
(
ld_args
))
self
.
spawn
([
self
.
linker
]
+
ld_args
)
self
.
_copy_vcruntime
(
output_dir
)
except
DistutilsExecError
as
msg
:
raise
LinkError
(
msg
)
else
:
log
.
debug
(
"skipping %s (up-to-date)"
,
output_filename
)
def
_copy_vcruntime
(
self
,
output_dir
):
vcruntime
=
self
.
_vcruntime_redist
if
not
vcruntime
or
not
os
.
path
.
isfile
(
vcruntime
):
return
if
os
.
path
.
basename
(
vcruntime
).
lower
()
in
_BUNDLED_DLLS
:
return
log
.
debug
(
'Copying "%s"'
,
vcruntime
)
vcruntime
=
shutil
.
copy
(
vcruntime
,
output_dir
)
os
.
chmod
(
vcruntime
,
stat
.
S_IWRITE
)
def
spawn
(
self
,
cmd
):
old_path
=
os
.
getenv
(
'path'
)
try
:
...
...
tests/test_msvccompiler.py
View file @
acb3d0ae
...
...
@@ -16,22 +16,73 @@ class msvccompilerTestCase(support.TempdirManager,
unittest
.
TestCase
):
def
test_no_compiler
(
self
):
import
distutils._msvccompiler
as
_msvccompiler
# makes sure query_vcvarsall raises
# a DistutilsPlatformError if the compiler
# is not found
from
distutils._msvccompiler
import
_get_vc_env
def
_find_vcvarsall
():
return
None
def
_find_vcvarsall
(
plat_spec
):
return
None
,
None
import
distutils._msvccompiler
as
_msvccompiler
old_find_vcvarsall
=
_msvccompiler
.
_find_vcvarsall
_msvccompiler
.
_find_vcvarsall
=
_find_vcvarsall
try
:
self
.
assertRaises
(
DistutilsPlatformError
,
_get_vc_env
,
self
.
assertRaises
(
DistutilsPlatformError
,
_msvccompiler
.
_get_vc_env
,
'wont find this version'
)
finally
:
_msvccompiler
.
_find_vcvarsall
=
old_find_vcvarsall
def
test_compiler_options
(
self
):
import
distutils._msvccompiler
as
_msvccompiler
# suppress path to vcruntime from _find_vcvarsall to
# check that /MT is added to compile options
old_find_vcvarsall
=
_msvccompiler
.
_find_vcvarsall
def
_find_vcvarsall
(
plat_spec
):
return
old_find_vcvarsall
(
plat_spec
)[
0
],
None
_msvccompiler
.
_find_vcvarsall
=
_find_vcvarsall
try
:
compiler
=
_msvccompiler
.
MSVCCompiler
()
compiler
.
initialize
()
self
.
assertIn
(
'/MT'
,
compiler
.
compile_options
)
self
.
assertNotIn
(
'/MD'
,
compiler
.
compile_options
)
finally
:
_msvccompiler
.
_find_vcvarsall
=
old_find_vcvarsall
def
test_vcruntime_copy
(
self
):
import
distutils._msvccompiler
as
_msvccompiler
# force path to a known file - it doesn't matter
# what we copy as long as its name is not in
# _msvccompiler._BUNDLED_DLLS
old_find_vcvarsall
=
_msvccompiler
.
_find_vcvarsall
def
_find_vcvarsall
(
plat_spec
):
return
old_find_vcvarsall
(
plat_spec
)[
0
],
__file__
_msvccompiler
.
_find_vcvarsall
=
_find_vcvarsall
try
:
tempdir
=
self
.
mkdtemp
()
compiler
=
_msvccompiler
.
MSVCCompiler
()
compiler
.
initialize
()
compiler
.
_copy_vcruntime
(
tempdir
)
self
.
assertTrue
(
os
.
path
.
isfile
(
os
.
path
.
join
(
tempdir
,
os
.
path
.
basename
(
__file__
))))
finally
:
_msvccompiler
.
_find_vcvarsall
=
old_find_vcvarsall
def
test_vcruntime_skip_copy
(
self
):
import
distutils._msvccompiler
as
_msvccompiler
tempdir
=
self
.
mkdtemp
()
compiler
=
_msvccompiler
.
MSVCCompiler
()
compiler
.
initialize
()
dll
=
compiler
.
_vcruntime_redist
self
.
assertTrue
(
os
.
path
.
isfile
(
dll
))
compiler
.
_copy_vcruntime
(
tempdir
)
self
.
assertFalse
(
os
.
path
.
isfile
(
os
.
path
.
join
(
tempdir
,
os
.
path
.
basename
(
dll
))))
def
test_suite
():
return
unittest
.
makeSuite
(
msvccompilerTestCase
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment