Monday, November 19, 2012

Python x64 Package Extensions with pip, MSVC 2008 Express & SDK 7

[UPDATE 2014-11-13] Free x86 and AMD64 (x86-64) VC90 c-compilers for Python-2.7 are now available from Microsoft. The free VC90 compilers can be used to install package source that contains c-extensions using either pip, setuptools or distutils. For example, pip install dulwich will build and install the Python Git implementation which contains several speedups as c-extensions.

[UPDATED 2012-02-04, 2014-04-18] You can skip this if you fix your vcvarsall.bat to point at the correct paths.

If you try `user@machine ~$ pip install package` from a bash shell or even `C:\Users\user>C:\Python27\Scripts\pip.exe install package` on a 64-bit MS Windows machine with the 64-bit version of Python installed, then you are likely to get a traceback from `distutils.msvc9ccompiler.py` that `vcvarsall.bat` only returned `path` but it was also looking for `lib`, `libpath` and `includes`. Oh well.

Because you know that your version of Python 2.7 was compiled with MS Visual C++ 2008 (aka VC90), you might try to use pip in the VC90 command prompt, since it loads the variables for you, but then you will get the following linker error:
fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
In a virgin cmd.exe shell you might try to run vcvarsall.bat amd64 to see if it works, but then you will see that it doesn't, when you get this discouraging stifling message:
The specified configuration type is missing.  The tools for the configuration might not be installed.
Then you might put this into Google and eventually you will find that MVSC 2008 Express doesn't support 64-bit compilation without Windows SDK 7 (see this post to find out where you can download this). Luckily, that has it's own nifty environment, run it from the start menu and change to 64-bit compilers and release mode by typing ...
> setenv /x64 /release
... and watching the screen font color change from yellow to green. Fun! Distutils would also like you to tell it not to bother looking around for vcvarsall, and just use the SDK environment by setting two environment variables:
> set DISTUTILS_USE_SDK=1
> set MSSdk=1
Also, you will need to have both Python27 and Python27\Scripts on your path before you run the SDK 7 CMD shell, or distutils will still fail. Unfortunately you can't add this by editing the path after starting the shell. The easiest way to do this is to right click on the My Computer icon on the desktop, select the Advanced tab and then click the Environment Variables button near the bottom. This will bring up the Environment Variables window. Add a new user variable for your personal profile by clicking the New button in the upper pane, and then type PATH in the Variable name: box and C:\Python27;C:\Python27\Scripts in the Variable value: box. Note the semicolon in between the 2 paths, if you've never edited your path before, this is the path separator on MS Windows. Then click OK, OK and OK. The changes are immediate for new CMD shells. Your local PATH is appended to the end of the system PATH.

Now try `pip install package` again and if you're lucky, voila, pip says, "Sucessfully installed package". Thanks pip! I tried this with dulwich, and it installed no problem.

There is some nifty info in the Python distutils docs and the Cython folks also have some nice 64-bit extensions help too.
Fork me on GitHub