Index: Lib/distutils/msvc9compiler.py =================================================================== --- Lib/distutils/msvc9compiler.py (revision 83863) +++ Lib/distutils/msvc9compiler.py (working copy) @@ -24,6 +24,7 @@ from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log from distutils.util import get_platform +from distutils.spawn import find_executable import _winreg @@ -320,11 +321,13 @@ _cpp_extensions = ['.cc', '.cpp', '.cxx'] _rc_extensions = ['.rc'] _mc_extensions = ['.mc'] + _asm_extensions = ['.asm'] # Needed for the filename generation methods provided by the # base class, CCompiler. src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) + _rc_extensions + _mc_extensions + + _asm_extensions) res_extension = '.res' obj_extension = '.obj' static_lib_extension = '.lib' @@ -354,6 +357,13 @@ raise DistutilsPlatformError("--plat-name must be one of %s" % (ok_plats,)) + # Will succeed if the user has already executed vcvarsall. + self.ml = None + if find_executable("ml64.exe"): + self.ml = "ml64.exe" + elif find_executable("ml.exe"): + self.ml = "ml.exe" + if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): # Assume that the SDK set up everything alright; don't try to be # smarter @@ -406,6 +416,13 @@ self.__paths = normalize_and_reduce_paths(self.__paths) os.environ['path'] = ";".join(self.__paths) + # Try again with new path: + if not self.ml: + if self.find_exe("ml64.exe"): + self.ml = "ml64.exe" + elif self.find_exe("ml.exe"): + self.ml = "ml.exe" + self.preprocess_options = None if self.__arch == "x86": self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', @@ -530,6 +547,13 @@ except DistutilsExecError, msg: raise CompileError(msg) continue + elif ext in self._asm_extensions: + try: + output_obj = '/Fo' + obj + self.spawn([self.ml] + ['/c', '/Cx', output_obj] + [src]) + except DistutilsExecError as msg: + raise CompileError(msg) + continue else: # how to handle this file? raise CompileError("Don't know how to compile %s to %s" Index: Lib/distutils/tests/test_msvc9compiler.py =================================================================== --- Lib/distutils/tests/test_msvc9compiler.py (revision 83863) +++ Lib/distutils/tests/test_msvc9compiler.py (working copy) @@ -60,6 +60,51 @@ """ +_DIVMOD128_ASM = """\ +PUBLIC _mpd_div_words +_TEXT SEGMENT +q$ = 8 +r$ = 16 +hi$ = 24 +lo$ = 32 +d$ = 40 +_mpd_div_words PROC + mov r10, rdx + mov rdx, r8 + mov rax, r9 + div QWORD PTR d$[rsp] + mov QWORD PTR [r10], rdx + mov QWORD PTR [rcx], rax + ret 0 +_mpd_div_words ENDP +_TEXT ENDS +END +""" + +_DIVMOD64_ASM = """\ +.686P +.model flat +PUBLIC divmod64 +_TEXT SEGMENT +q$ = 8 +r$ = 12 +hi$ = 16 +lo$ = 20 +d$ = 24 +divmod64 PROC + mov eax, DWORD PTR lo$[esp-4] + mov edx, DWORD PTR hi$[esp-4] + div DWORD PTR d$[esp-4] + mov ecx, DWORD PTR q$[esp-4] + mov DWORD PTR [ecx], eax + mov ecx, DWORD PTR r$[esp-4] + mov DWORD PTR [ecx], edx + ret 0 +divmod64 ENDP +_TEXT ENDS +END +""" + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") class msvc9compilerTestCase(support.TempdirManager, unittest.TestCase): @@ -128,7 +173,26 @@ # makes sure the manifest was properly cleaned self.assertEquals(content, _CLEANED_MANIFEST) + def test_asm_extension(self): + from distutils.msvc9compiler import MSVCCompiler + import time + tempdir = self.mkdtemp() + cwd = os.getcwd() + os.chdir(tempdir) + cc = MSVCCompiler() + + f = open('divmod.asm', 'w') + if cc.find_exe('ml64.exe'): + f.write(_DIVMOD128_ASM) + else: + f.write(_DIVMOD64_ASM) + f.close() + + cc.compile(['divmod.asm']) + self.assertTrue(os.path.isfile('divmod.obj')) + os.chdir(cwd) + def test_suite(): return unittest.makeSuite(msvc9compilerTestCase)