使用VS2010编译python2.7.3 - Python - 服务器之家

服务器之家

专注于服务器技术!
当前位置:首页 > 脚本编程 > Python

使用VS2010编译python2.7.3

发布时间:2013-12-22 来源:服务器之家

Compiling Python with Visual Studio 2010

This is a draft related to http://bugs.python.org/issue13210.

Issues

List of issues related to Visual Studio 2010:

* issue 13210: parent issue

* issue 10469: test_asyncore blocks forever

* issue 4431: manifest handling

* issue7833: patch to avoid the use of manifests

* issue6807: problem with msi for installer creation

* issue2286: crash on test_marshal

* patch wininst

Prepare environment

* grab Python 2.7.2 sources from python.org

* Define compilation environment:

For 32 bits:

"C:Program Files (x86)Microsoft Visual Studio 10.0Common7Toolsvsvars32.bat"

For 64 bits:

"C:Program Files (x86)Microsoft Visual Studio 10.0VCvcvarsall.bat" amd64

It is necessary to have svn in the PATH

Compile additional libraries

* Download the dependencies:

cd Python-2.7.2

Toolsbuildbotexternal-common.bat

* Correct the dependencies for VS 2010:

diff -r 97fbe6d3b5aa -r 87ac4519efd8 tcl-8.5.2.1/generic/tclPosixStr.c

--- a/tcl-8.5.2.1/generic/tclPosixStr.c Tue Oct 18 17:03:03 2011 +0200

+++ b/tcl-8.5.2.1/generic/tclPosixStr.c Tue Oct 18 17:09:41 2011 +0200

@@ -344,7 +344,7 @@

     case EPERM: return "EPERM";

 #endif

 #if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))

-    case EPFNOSUPPORT: return "EPFNOSUPPORT";

+

 #endif

 #ifdef EPIPE

     case EPIPE: return "EPIPE";

@@ -404,7 +404,7 @@

     case ESHUTDOWN: return "ESHUTDOWN";

 #endif

 #ifdef ESOCKTNOSUPPORT

-    case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";

+

 #endif

 #ifdef ESPIPE

     case ESPIPE: return "ESPIPE";

@@ -792,7 +792,7 @@

     case EPERM: return "not owner";

 #endif

 #if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))

-    case EPFNOSUPPORT: return "protocol family not supported";

+

 #endif

 #ifdef EPIPE

     case EPIPE: return "broken pipe";

@@ -852,7 +852,7 @@

     case ESHUTDOWN: return "can't send afer socket shutdown";

 #endif

 #ifdef ESOCKTNOSUPPORT

-    case ESOCKTNOSUPPORT: return "socket type not supported";

+

 #endif

 #ifdef ESPIPE

     case ESPIPE: return "invalid seek";

diff -r 97fbe6d3b5aa -r 87ac4519efd8 tcl-8.5.2.1/win/makefile.vc

--- a/tcl-8.5.2.1/win/makefile.vc       Tue Oct 18 17:03:03 2011 +0200

+++ b/tcl-8.5.2.1/win/makefile.vc       Tue Oct 18 17:09:41 2011 +0200

@@ -448,7 +448,7 @@

 #---------------------------------------------------------------------

 !if $(DEBUG)

-ldebug = -debug:full -debugtype:cv

+ldebug = -debugtype:cv

 !else

 ldebug = -release -opt:ref -opt:icf,3

 !endif

diff -r 97fbe6d3b5aa -r 87ac4519efd8 tk-8.5.2.0/win/makefile.vc

--- a/tk-8.5.2.0/win/makefile.vc        Tue Oct 18 17:03:03 2011 +0200

+++ b/tk-8.5.2.0/win/makefile.vc        Tue Oct 18 17:09:41 2011 +0200

@@ -472,7 +472,7 @@

 #---------------------------------------------------------------------

 !if $(DEBUG)

-ldebug = -debug:full -debugtype:cv

+ldebug = -debugtype:cv

 !else

 ldebug = -release -opt:ref -opt:icf,3

 !endif

* Compile the dependencies:

For 32 bits:

$ Toolsbuildbotexternal.bat

For 64 bits:

把Toolsbuildbotexternal-amd64.bat中的:

call "%VS90COMNTOOLS%....VCvcvarsall.bat" x86_amd64

修改为:

call "%VS100COMNTOOLS%....VCvcvarsall.bat" x86_amd64

$ Toolsbuildbotexternal-amd64.bat

* Get openssl 1.0.0e

You need perl to compile openssl

set PATH=%PATH%;C:Perlbin

cd openssl-1.0.0e

For 32 bits:

perl Configure --openssldir=D:NotBackedUpsupportopenssl-1.0.0e enable-camellia disable-idea VC-WIN32

msdo_ms.bat # possibly .msdo_nasm.bat with http://nasm.sf.net

这里,需要修改msnt.mak的内容,不然会有链接错误,修改的内容如下:

增加的内容:

$(OBJ_D)mem_clr.obj: $(SRC_D)cryptomem_clr.c

  $(CC) /Fo$(OBJ_D)mem_clr.obj  $(LIB_CFLAGS) -c $(SRC_D)cryptomem_clr.c

把:

$(OBJ_D)mem.obj $(OBJ_D)mem_dbg.obj $(OBJ_D)cversion.obj

修改为:

$(OBJ_D)mem.obj $(OBJ_D)mem_dbg.obj $(OBJ_D)cversion.obj $(OBJ_D)mem_clr.obj

最后:

nmake -f msnt.mak

nmake -f msntdll.mak

For 64 bits:

perl Configure --openssldir=D:NotBackedUpsupportopenssl-1.0.0e enable-camellia disable-idea VC-WIN64A

msdo_win64a.bat

修改nt.mak如下:

# The output directory for everything intersting

OUT_D=out64

# The output directory for all the temporary muck

TMP_D=tmp64

# The output directory for the header files

INC_D=inc64

然后nmake一下

nmake -f msnt.mak

修改ntdll.mak如下:

# The output directory for everything intersting

OUT_D=out64dll

# The output directory for all the temporary muck

TMP_D=tmp64dll

# The output directory for the header files

INC_D=inc64

INCO_D=inc64openssl

nmake -f msntdll.mak

这一步中间可能会有些错,需要把uptable.obj复制到ms目录下

## $ nmake -f msntdll.mak test

Compile Python

* Modify Python 2.7.2 so that it will compile with Visual Studio 2010:

diff -r 87ac4519efd8 -r 0e7993d51350 Python-2.7.2/Lib/distutils/command/build_ext.py

--- a/Python-2.7.2/Lib/distutils/command/build_ext.py   Tue Oct 18 17:09:41 2011 +0200

+++ b/Python-2.7.2/Lib/distutils/command/build_ext.py   Tue Oct 18 17:15:40 2011 +0200

@@ -193,7 +193,7 @@

             # Append the source distribution include and library directories,

             # this allows distutils on windows to work in the source tree

             self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))

-            if MSVC_VERSION == 9:

+            if MSVC_VERSION in (9, 10):

                 # Use the .lib files for the correct architecture

                 if self.plat_name == 'win32':

                     suffix = ''

diff -r 87ac4519efd8 -r 0e7993d51350 Python-2.7.2/Lib/distutils/msvc9compiler.py

--- a/Python-2.7.2/Lib/distutils/msvc9compiler.py       Tue Oct 18 17:09:41 2011 +0200

+++ b/Python-2.7.2/Lib/distutils/msvc9compiler.py       Tue Oct 18 17:15:40 2011 +0200

@@ -240,7 +240,7 @@

             log.debug("Unable to find productdir in registry")

     if not productdir or not os.path.isdir(productdir):

-        toolskey = "VS%0.f0COMNTOOLS" % version

+        toolskey = "VS100COMNTOOLS"

         toolsdir = os.environ.get(toolskey, None)

         if toolsdir and os.path.isdir(toolsdir):

@@ -645,6 +645,7 @@

             # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)

             # Ask the linker to generate the manifest in the temp dir, so

             # we can embed it later.

+            ld_args.append('/MANIFEST')

             temp_manifest = os.path.join(

                     build_temp,

                     os.path.basename(output_filename) + ".manifest")

diff -r 87ac4519efd8 -r 0e7993d51350 Python-2.7.2/PCbuild/bdist_wininst.vcproj

--- a/Python-2.7.2/PCbuild/bdist_wininst.vcproj Tue Oct 18 17:09:41 2011 +0200

+++ b/Python-2.7.2/PCbuild/bdist_wininst.vcproj Tue Oct 18 17:15:40 2011 +0200

@@ -75,11 +75,11 @@

                        <Tool

                                Name="VCLinkerTool"

                                AdditionalDependencies="comctl32.lib imagehlp.lib"

-                               OutputFile="..libdistutilscommandwininst-9.0.exe"

+                               OutputFile="..libdistutilscommandwininst-10.0.exe"

                                LinkIncremental="1"

                                SuppressStartupBanner="true"

                                IgnoreDefaultLibraryNames="LIBC"

-                               ProgramDatabaseFile="..libdistutilscommandwininst-9.0.pdb"

+                               ProgramDatabaseFile="..libdistutilscommandwininst-10.0.pdb"

                                SubSystem="2"

                                RandomizedBaseAddress="1"

                                DataExecutionPrevention="0"

@@ -165,11 +165,11 @@

                        <Tool

                                Name="VCLinkerTool"

                                AdditionalDependencies="comctl32.lib imagehlp.lib"

-                               OutputFile="..libdistutilscommandwininst-9.0-amd64.exe"

+                               OutputFile="..libdistutilscommandwininst-10.0-amd64.exe"

                                LinkIncremental="1"

                                SuppressStartupBanner="true"

                                IgnoreDefaultLibraryNames="LIBC"

-                               ProgramDatabaseFile="..libdistutilscommandwininst-9.0-amd64.pdb"

+                               ProgramDatabaseFile="..libdistutilscommandwininst-10.0-amd64.pdb"

                                SubSystem="2"

                                RandomizedBaseAddress="1"

                                DataExecutionPrevention="0"

diff -r 87ac4519efd8 -r 0e7993d51350 Python-2.7.2/Tools/msi/msi.py

--- a/Python-2.7.2/Tools/msi/msi.py     Tue Oct 18 17:09:41 2011 +0200

+++ b/Python-2.7.2/Tools/msi/msi.py     Tue Oct 18 17:15:40 2011 +0200

@@ -28,7 +28,7 @@

 # path to PCbuild directory

 PCBUILD="PCbuild"

 # msvcrt version

-MSVCR = "90"

+MSVCR = "100"

 # Name of certificate in default store to sign MSI with

 certname = None

 # Make a zip file containing the PDB files for this build?

@@ -179,8 +179,16 @@

 # Determine the target architecture

 dll_path = os.path.join(srcdir, PCBUILD, dll_file)

 msilib.set_arch_from_file(dll_path)

-if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"):

-    raise SystemError, "msisupport.dll for incorrect architecture"

+have_msisupport = os.path.exists("msisupport.dll")

+if have_msisupport:

+    try:

+        if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"):

+            raise SystemError("msisupport.dll for incorrect architecture")

+    except:

+        print("WARNING: Architecture check for msisupport.dll failed.")

+else:

+    print("WARNING: msisupport.dll not found. Architecture check for msisupport.dll skipped.")

+

 if msilib.Win64:

     upgrade_code = upgrade_code_64

     # Bump the last digit of the code by one, so that 32-bit and 64-bit

@@ -852,18 +860,18 @@

                         "Python test suite (Lib/test/)", 11,

                         parent = default_feature, attributes=2|8)

-def extract_msvcr90():

+def extract_msvcr100():

     # Find the redistributable files

     if msilib.Win64:

         arch = "amd64"

     else:

         arch = "x86"

-    dir = os.path.join(os.environ['VS90COMNTOOLS'], r"....VCredist%sMicrosoft.VC90.CRT" % arch)

+    dir = os.path.join(os.environ['VS100COMNTOOLS'], r"....VCredist%sMicrosoft.VC100.CRT" % arch)

-    result = []

+    result = [None,]

     installer = msilib.MakeInstaller()

-    # omit msvcm90 and msvcp90, as they aren't really needed

-    files = ["Microsoft.VC90.CRT.manifest", "msvcr90.dll"]

+    # omit msvcm100 and msvcp100, as they aren't really needed

+    files = ["msvcr100.dll",]

     for f in files:

         path = os.path.join(dir, f)

         kw = {'src':path}

@@ -881,9 +889,9 @@

     for name, pat, file in (("bzip2","bzip2-*", "LICENSE"),

                       ("Berkeley DB", "db-*", "LICENSE"),

                       ("openssl", "openssl-*", "LICENSE"),

-                      ("Tcl", "tcl8*", "license.terms"),

-                      ("Tk", "tk8*", "license.terms"),

-                      ("Tix", "tix-*", "license.terms")):

+                      ("Tcl", "tcl-8*", "license.terms"),

+                      ("Tk", "tk-8*", "license.terms"),):

+                      # ("Tix", "tix-*", "license.terms")):

         out.write("nThis copy of Python includes a copy of %s, which is licensed under the following terms:nn" % name)

         dirs = glob.glob(srcdir+"/../"+pat)

         if not dirs:

@@ -939,20 +947,20 @@

                     language=installer.FileVersion(pydllsrc, 1))

     DLLs = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs")

-    # msvcr90.dll: Need to place the DLL and the manifest into the root directory,

+    # msvcr100.dll: Need to place the DLL and the manifest into the root directory,

     # plus another copy of the manifest in the DLLs directory, with the manifest

     # pointing to the root directory

-    root.start_component("msvcr90", feature=private_crt)

+    root.start_component("msvcr100", feature=private_crt)

     # Results are ID,keyword pairs

-    manifest, crtdll = extract_msvcr90()

-    root.add_file(manifest[0], **manifest[1])

+    manifest, crtdll = extract_msvcr100()

+    # root.add_file(manifest[0], **manifest[1])

     root.add_file(crtdll[0], **crtdll[1])

     # Copy the manifest

     # Actually, don't do that anymore - no DLL in DLLs should have a manifest

-    # dependency on msvcr90.dll anymore, so this should not be necessary

+    # dependency on msvcr100.dll anymore, so this should not be necessary

     #manifest_dlls = manifest[0]+".root"

     #open(manifest_dlls, "w").write(open(manifest[1]['src']).read().replace("msvcr","../msvcr"))

-    #DLLs.start_component("msvcr90_dlls", feature=private_crt)

+    #DLLs.start_component("msvcr100_dlls", feature=private_crt)

     #DLLs.add_file(manifest[0], src=os.path.abspath(manifest_dlls))

     # Now start the main component for the DLLs directory;

@@ -1325,9 +1333,9 @@

 # Merge CRT into MSI file. This requires the database to be closed.

 mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules")

 if msilib.Win64:

-    modules = ["Microsoft_VC90_CRT_x86_x64.msm", "policy_9_0_Microsoft_VC90_CRT_x86_x64.msm"]

+    modules = ["Microsoft_VC100_CRT_x64.msm",]

 else:

-    modules = ["Microsoft_VC90_CRT_x86.msm","policy_9_0_Microsoft_VC90_CRT_x86.msm"]

+    modules = ["Microsoft_VC100_CRT_x86.msm",]

 for i, n in enumerate(modules):

     modules[i] = os.path.join(mod_dir, n)

diff -r 87ac4519efd8 -r 0e7993d51350 Python-2.7.2/Tools/msi/msilib.py

--- a/Python-2.7.2/Tools/msi/msilib.py  Tue Oct 18 17:09:41 2011 +0200

+++ b/Python-2.7.2/Tools/msi/msilib.py  Tue Oct 18 17:15:40 2011 +0200

@@ -5,7 +5,7 @@

 import win32com.client

 import pythoncom, pywintypes

 from win32com.client import constants

-import re, string, os, sets, glob, subprocess, sys, _winreg, struct

+import re, string, os, sets, glob, subprocess, sys, _winreg, struct, _msi

 try:

     basestring

@@ -350,7 +350,7 @@

 class CAB:

     def __init__(self, name):

         self.name = name

-        self.file = open(name+".txt", "wt")

+        self.files = []

         self.filenames = sets.Set()

         self.index = 0

@@ -369,51 +369,18 @@

         if not logical:

             logical = self.gen_id(dir, file)

         self.index += 1

-        if full.find(" ")!=-1:

-            print >>self.file, '"%s" %s' % (full, logical)

-        else:

-            print >>self.file, '%s %s' % (full, logical)

+        self.files.append((full, logical))

         return self.index, logical

     def commit(self, db):

-        self.file.close()

         try:

             os.unlink(self.name+".cab")

         except OSError:

             pass

-        for k, v in [(r"SoftwareMicrosoftVisualStudio7.1SetupVS", "VS7CommonBinDir"),

-                     (r"SoftwareMicrosoftVisualStudio8.0SetupVS", "VS7CommonBinDir"),

-                     (r"SoftwareMicrosoftVisualStudio9.0SetupVS", "VS7CommonBinDir"),

-                     (r"SoftwareMicrosoftWin32SDKDirectories", "Install Dir"),

-                    ]:

-            try:

-                key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k)

-                dir = _winreg.QueryValueEx(key, v)[0]

-                _winreg.CloseKey(key)

-            except (WindowsError, IndexError):

-                continue

-            cabarc = os.path.join(dir, r"Bin", "cabarc.exe")

-            if not os.path.exists(cabarc):

-                continue

-            break

-        else:

-            print "WARNING: cabarc.exe not found in registry"

-            cabarc = "cabarc.exe"

-        cmd = r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name)

-        p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,

-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

-        for line in p.stdout:

-            if line.startswith("  -- adding "):

-                sys.stdout.write(".")

-            else:

-                sys.stdout.write(line)

-            sys.stdout.flush()

-        if not os.path.exists(self.name+".cab"):

-            raise IOError, "cabarc failed"

+        _msi.FCICreate(self.name+".cab", self.files)

         add_data(db, "Media",

                 [(1, self.index, None, "#"+self.name, None, None)])

         add_stream(db, self.name, self.name+".cab")

-        os.unlink(self.name+".txt")

         os.unlink(self.name+".cab")

         db.Commit()

For 64 bits - apply additional patch:

diff -r 85c73eff95c1 Python-2.7.2/Tools/msi/msi.py

--- a/Python-2.7.2/Tools/msi/msi.py     Tue Oct 25 16:29:23 2011 +0200

+++ b/Python-2.7.2/Tools/msi/msi.py     Tue Oct 25 17:41:17 2011 +0200

@@ -26,7 +26,7 @@

 # Is Tcl available at all?

 have_tcl = True

 # path to PCbuild directory

-PCBUILD="PCbuild"

+PCBUILD="PCbuild\amd64"

 # msvcrt version

 MSVCR = "100"

 # Name of certificate in default store to sign MSI with

@@ -863,7 +863,7 @@

 def extract_msvcr100():

     # Find the redistributable files

     if msilib.Win64:

-        arch = "amd64"

+        arch = "x64"

     else:

         arch = "x86"

     dir = os.path.join(os.environ['VS100COMNTOOLS'], r"....VCredist%sMicrosoft.VC100.CRT" % arch)

* Open Python-2.7.2PCbuildpcbuild.sln with Visual Studio (automatic conversion)

* Close the solution

* Modify Python-2.7.2PCbuild_bsddb.vcxproj for each source line, from:

    <ClCompile Include="cryptoaes_method.c" />

to

    <ClCompile Include="$(bsddbDir)..cryptoaes_method.c" />

* Modify Python-2.7.2PCbuild_ssl.vcxproj and Python-2.7.2PCbuild_hashlib.vcxproj - remove each PreBuildEvent section (could not get build_ssl.py to work, prefered manual compilation)

* Open Python-2.7.2PCbuildpcbuild.sln with Visual Studio

* Change to Release (for 64 bits: "Release | x64")

* Choose in menu "View" => "Property Manager"

* open project _bsddb > "Release | Win32" > pyd > pyproject > User macros (for 64 bits: "Release | x64")

* change value of opensslDir, from "$(externalsDir)openssl-0.9.8d" to "$(externalsDir)openssl-1.0.0e"

* Change properties in project tkinter > Linker > Input > Additional Dependencies > edit:

For 32 bits: remove $(tcltkLib) and add $(tcltkDir)libtcl85g.lib;$(tcltkDir)libtk85g.lib;

For 64 bits: remove $(tcltk64Lib) and add $(tcltk64Dir)libtcl85g.lib;$(tcltk64Dir)libtk85g.lib;

复制db-4.7.25.0目录下所有文件到Python-2.7.3PCbuild

* Build solution

Use either the UI or following commands:

For 32 bits:

msbuild PCbuildpcbuild.sln  /p:Configuration="Release" /p:Platform="Win32"

msbuild /p:useenv=true PCbuildbdist_wininst.vcxproj /p:Configuration="Release" /p:Platform="Win32"

For 64 bits:

msbuild PCbuildpcbuild.sln  /p:Configuration="Release" /p:Platform="x64"

msbuild /p:useenv=true PCbuildbdist_wininst.vcxproj /p:Configuration="Release" /p:Platform="x64"

* copy Python-2.7.2/PC/pyconfig.h to Python-2.7.2/pyconfig.h (necessary otherwise distutils complains that it can't find the file when compiling packages)

* Test python:

cd PCbuild;

For 32 bits:

rt.bat -q -uall -rwW

For 64 bits:

rt.bat -q -x64 -uall -rw

热点推荐

    SQL Error: select * from ***_***_news where id in ()