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.
...
@@ -14,6 +14,8 @@ for older versions in distutils.msvc9compiler and distutils.msvccompiler.
# ported to VS 2015 by Steve Dower
# ported to VS 2015 by Steve Dower
import
os
import
os
import
shutil
import
stat
import
subprocess
import
subprocess
from
distutils.errors
import
DistutilsExecError
,
DistutilsPlatformError
,
\
from
distutils.errors
import
DistutilsExecError
,
DistutilsPlatformError
,
\
...
@@ -25,7 +27,7 @@ from distutils.util import get_platform
...
@@ -25,7 +27,7 @@ from distutils.util import get_platform
import
winreg
import
winreg
from
itertools
import
count
from
itertools
import
count
def
_find_vcvarsall
():
def
_find_vcvarsall
(
plat_spec
):
with
winreg
.
OpenKeyEx
(
with
winreg
.
OpenKeyEx
(
winreg
.
HKEY_LOCAL_MACHINE
,
winreg
.
HKEY_LOCAL_MACHINE
,
r"Software\
Mic
rosoft\
Visu
alStudio\
SxS
\VC7"
,
r"Software\
Mic
rosoft\
Visu
alStudio\
SxS
\VC7"
,
...
@@ -33,7 +35,7 @@ def _find_vcvarsall():
...
@@ -33,7 +35,7 @@ def _find_vcvarsall():
)
as
key
:
)
as
key
:
if
not
key
:
if
not
key
:
log
.
debug
(
"Visual C++ is not registered"
)
log
.
debug
(
"Visual C++ is not registered"
)
return
None
return
None
,
None
best_version
=
0
best_version
=
0
best_dir
=
None
best_dir
=
None
...
@@ -51,14 +53,23 @@ def _find_vcvarsall():
...
@@ -51,14 +53,23 @@ def _find_vcvarsall():
best_version
,
best_dir
=
version
,
vc_dir
best_version
,
best_dir
=
version
,
vc_dir
if
not
best_version
:
if
not
best_version
:
log
.
debug
(
"No suitable Visual C++ version found"
)
log
.
debug
(
"No suitable Visual C++ version found"
)
return
None
return
None
,
None
vcvarsall
=
os
.
path
.
join
(
best_dir
,
"vcvarsall.bat"
)
vcvarsall
=
os
.
path
.
join
(
best_dir
,
"vcvarsall.bat"
)
if
not
os
.
path
.
isfile
(
vcvarsall
):
if
not
os
.
path
.
isfile
(
vcvarsall
):
log
.
debug
(
"%s cannot be found"
,
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
):
def
_get_vc_env
(
plat_spec
):
if
os
.
getenv
(
"DISTUTILS_USE_SDK"
):
if
os
.
getenv
(
"DISTUTILS_USE_SDK"
):
...
@@ -67,7 +78,7 @@ def _get_vc_env(plat_spec):
...
@@ -67,7 +78,7 @@ def _get_vc_env(plat_spec):
for
key
,
value
in
os
.
environ
.
items
()
for
key
,
value
in
os
.
environ
.
items
()
}
}
vcvarsall
=
_find_vcvarsall
(
)
vcvarsall
,
vcruntime
=
_find_vcvarsall
(
plat_spec
)
if
not
vcvarsall
:
if
not
vcvarsall
:
raise
DistutilsPlatformError
(
"Unable to find vcvarsall.bat"
)
raise
DistutilsPlatformError
(
"Unable to find vcvarsall.bat"
)
...
@@ -83,13 +94,17 @@ def _get_vc_env(plat_spec):
...
@@ -83,13 +94,17 @@ def _get_vc_env(plat_spec):
raise
DistutilsPlatformError
(
"Error executing {}"
raise
DistutilsPlatformError
(
"Error executing {}"
.
format
(
exc
.
cmd
))
.
format
(
exc
.
cmd
))
return
{
env
=
{
key
.
lower
():
value
key
.
lower
():
value
for
key
,
_
,
value
in
for
key
,
_
,
value
in
(
line
.
partition
(
'='
)
for
line
in
out
.
splitlines
())
(
line
.
partition
(
'='
)
for
line
in
out
.
splitlines
())
if
key
and
value
if
key
and
value
}
}
if
vcruntime
:
env
[
'py_vcruntime_redist'
]
=
vcruntime
return
env
def
_find_exe
(
exe
,
paths
=
None
):
def
_find_exe
(
exe
,
paths
=
None
):
"""Return path to an MSVC executable program.
"""Return path to an MSVC executable program.
...
@@ -115,6 +130,20 @@ PLAT_TO_VCVARS = {
...
@@ -115,6 +130,20 @@ PLAT_TO_VCVARS = {
'win-amd64'
:
'amd64'
,
'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
)
:
class
MSVCCompiler
(
CCompiler
)
:
"""Concrete class that implements an interface to Microsoft Visual C++,
"""Concrete class that implements an interface to Microsoft Visual C++,
as defined by the CCompiler abstract class."""
as defined by the CCompiler abstract class."""
...
@@ -189,6 +218,7 @@ class MSVCCompiler(CCompiler) :
...
@@ -189,6 +218,7 @@ class MSVCCompiler(CCompiler) :
self
.
rc
=
_find_exe
(
"rc.exe"
,
paths
)
# resource compiler
self
.
rc
=
_find_exe
(
"rc.exe"
,
paths
)
# resource compiler
self
.
mc
=
_find_exe
(
"mc.exe"
,
paths
)
# message compiler
self
.
mc
=
_find_exe
(
"mc.exe"
,
paths
)
# message compiler
self
.
mt
=
_find_exe
(
"mt.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
):
for
dir
in
vc_env
.
get
(
'include'
,
''
).
split
(
os
.
pathsep
):
if
dir
:
if
dir
:
...
@@ -199,20 +229,26 @@ class MSVCCompiler(CCompiler) :
...
@@ -199,20 +229,26 @@ class MSVCCompiler(CCompiler) :
self
.
add_library_dir
(
dir
)
self
.
add_library_dir
(
dir
)
self
.
preprocess_options
=
None
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.
# later to dynamically link to ucrtbase but not vcruntime.
self
.
compile_options
=
[
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
=
[
self
.
compile_options_debug
=
[
'/nologo'
,
'/Od'
,
'/M
T
d'
,
'/Zi'
,
'/W3'
,
'/D_DEBUG'
'/nologo'
,
'/Od'
,
'/M
D
d'
,
'/Zi'
,
'/W3'
,
'/D_DEBUG'
]
]
ldflags
=
[
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
=
[
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'
]
self
.
ldflags_exe
=
[
*
ldflags
,
'/MANIFEST:EMBED,ID=1'
]
...
@@ -446,15 +482,29 @@ class MSVCCompiler(CCompiler) :
...
@@ -446,15 +482,29 @@ class MSVCCompiler(CCompiler) :
if
extra_postargs
:
if
extra_postargs
:
ld_args
.
extend
(
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
:
try
:
log
.
debug
(
'Executing "%s" %s'
,
self
.
linker
,
' '
.
join
(
ld_args
))
log
.
debug
(
'Executing "%s" %s'
,
self
.
linker
,
' '
.
join
(
ld_args
))
self
.
spawn
([
self
.
linker
]
+
ld_args
)
self
.
spawn
([
self
.
linker
]
+
ld_args
)
self
.
_copy_vcruntime
(
output_dir
)
except
DistutilsExecError
as
msg
:
except
DistutilsExecError
as
msg
:
raise
LinkError
(
msg
)
raise
LinkError
(
msg
)
else
:
else
:
log
.
debug
(
"skipping %s (up-to-date)"
,
output_filename
)
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
):
def
spawn
(
self
,
cmd
):
old_path
=
os
.
getenv
(
'path'
)
old_path
=
os
.
getenv
(
'path'
)
try
:
try
:
...
...
tests/test_msvccompiler.py
View file @
acb3d0ae
...
@@ -16,22 +16,73 @@ class msvccompilerTestCase(support.TempdirManager,
...
@@ -16,22 +16,73 @@ class msvccompilerTestCase(support.TempdirManager,
unittest
.
TestCase
):
unittest
.
TestCase
):
def
test_no_compiler
(
self
):
def
test_no_compiler
(
self
):
import
distutils._msvccompiler
as
_msvccompiler
# makes sure query_vcvarsall raises
# makes sure query_vcvarsall raises
# a DistutilsPlatformError if the compiler
# a DistutilsPlatformError if the compiler
# is not found
# is not found
from
distutils._msvccompiler
import
_get_vc_env
def
_find_vcvarsall
(
plat_spec
):
def
_find_vcvarsall
():
return
None
,
None
return
None
import
distutils._msvccompiler
as
_msvccompiler
old_find_vcvarsall
=
_msvccompiler
.
_find_vcvarsall
old_find_vcvarsall
=
_msvccompiler
.
_find_vcvarsall
_msvccompiler
.
_find_vcvarsall
=
_find_vcvarsall
_msvccompiler
.
_find_vcvarsall
=
_find_vcvarsall
try
:
try
:
self
.
assertRaises
(
DistutilsPlatformError
,
_get_vc_env
,
self
.
assertRaises
(
DistutilsPlatformError
,
_msvccompiler
.
_get_vc_env
,
'wont find this version'
)
'wont find this version'
)
finally
:
finally
:
_msvccompiler
.
_find_vcvarsall
=
old_find_vcvarsall
_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
():
def
test_suite
():
return
unittest
.
makeSuite
(
msvccompilerTestCase
)
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