Wednesday, July 18, 2012

building dbus-python on windows with mingw

dbus-python Build Instructions for Windows (x86) with MinGW

Revision history

  1. r0.0.20120706 - First draft
  2. r0.1.20120718 - Clean up markdown and post to poquitopicante.blogspot.com
  3. r1.0.20120720 - Use autolauch
    • Need --with-dbus-session-bus-default-address=autolaunch: for dbus to work out-of-the-box and to keep dbus-python from throwing exception.
    • Also If using git repo, use ./autogen.sh instead of ./configure. Make sure you have autotools installed in your MinGW toolchain.
  4. r1.1.20120723 - Correct GTK path
    • Remove dbus-glib examples Makefile patch; it's not needed if path to GTK runtime bin is correct, i.e.: no quotes in MS-Windows paths!
    • This was not an issue with dbus-binding-tool.exe, #52322 in bugzilla. There are no problems for dbus-glib to create binding "glue" when in glib-server mode if path to GTK bin folder is correctly.
    • setenv.cmd has an issue in which the quotation marks are in the wrong place, causing the quotes to be copied into the path, which is a big no-no in MS-Windows, because it causes inconsistent results. E.g. dbus-binding-tool.exe could be built, but not run.

Overview

These are instructions for building dbus-python, a binding to dbus on a MS-Windows x86 system using MinGW.

Set up MinGW build environment

  1. Download and install most recent version of mingw-get-inst from sourceforge, current version is 20120426. This only needs to be done once because afterwards you can just run ...
    $ mingw-get update
    $ mingw-get install mingw-get
    
    ... to get the latest version. During the install, which is an Inno-Setup GUI, select the option to install the "C compiler" and "MSYS Basic System" but leave other default install options. It should install MinGW in C:\mingw and MSYS in C:\mingw\msys\1.0. It doesn't change your path or add any environmental variables, but it does add a shortcut to the MSYS bash shell on your desktop and start menu, and register mingw-get-inst so you can un-install it later. There is lots of rich material on MinGW and MSYS on the Internet. Also take a look at Configuring and Using mingw-get.
  2. Start the MSYS shell, from the start menu, and install (or update) the developers toolkit. If you need to upgrade a component, use mingw-get upgrade <component>.
    $ mingw-get update
    $ mingw-get install gcc
    $ mingw-get install g++
    $ mingw-get install msys-make
    $ mingw-get install mingw32-make
    $ mingw-get install mingw-developer-toolkit
    
  3. While still in the MSYS shell, install expat.
    $ mingw-get install expat
    $ mingw-get install libexpat
    $ mingw-get install msys-expat
    $ mingw-get install msys-libexpat
    
  4. You also need libz and zlib.
    $ mingw-get install libz
    $ mingw-get install zlib
    $ mingw-get install msys-zlib
    
  5. You may also need or want the following:
    • GNU patch, wget, tar, libxml2 and possibly others (libxslt and libffi). If possible install them from MinGW/MSYS with mingw-get. Use mingw-get list <package> to search for packages.
      $ mingw-get install msys-patch
      $ mingw-get install msys-wget
      $ mingw-get install msys-tar
      $ mingw-get install msys-libxml2
      
    • lib2xml and libxslt are also available from xmlsoft as windows binaries. If use them, copy the files into the matching folders in /local, e.g. bin files go in /local/bin.
    • zlib is also available from zlib, there are links to binaries, but it is easy to build by following the directions on Fragrant Memories, however, the generated library zlib1.dll may conflict with your Intel Wifi controller or something else. The MinGW/MSYS libraries are libz-1.dll and msys-z.dll. The files zlib1.dll, libexpat-1.dll and libxml2-2.dll may actually already be in your GTK runtime bin folder.
      $ which zlib1.dll /c/Program Files/Intel/WiFi/bin/zlib1.dll
    • libffi is available here and on Github and installation instructions are here.

Python

Download and install Python (2.7.3) with the Python Windows Installer.

PyGTK or GTK+

  1. Download and install either the PyGTK all-in-one installer for your Python version (e.g. 2.7) or the GTK-2.0 all-in-one installer. If you're determined to build GLib from source see this post on Bootstrapping GLIB with MinGW.
  2. Fix the setenv.bat by either removing the quotes entirely from the SET PATH statements, or correcting them as in the patch below.
    --- a/python27/lib/site-packages/gtk-2.0/runtime/bin/setenv.cmd
    +++ b/python27/lib/site-packages/gtk-2.0/runtime/bin/setenv.cmd
    @@ -23,14 +23,14 @@
     call:abspath PYTHON_PKGCONFIG "%PYTHON_ROOT%\Lib\pkgconfig\"
    
     if defined PATH (
    -    set PATH="%PYTHON_ROOT%;%PYTHON_SCRIPTS%;%RUNTIME_BIN%;%PATH%"
    +    set "PATH=%PYTHON_ROOT%;%PYTHON_SCRIPTS%;%RUNTIME_BIN%;%PATH%"
     ) else (
    -    set PATH="%PYTHON_ROOT%;%PYTHON_SCRIPTS%;%RUNTIME_BIN%"
    +    set "PATH=%PYTHON_ROOT%;%PYTHON_SCRIPTS%;%RUNTIME_BIN%"
     )
     if defined PKG_CONFIG_PATH (
    -    set PKG_CONFIG_PATH="%PYTHON_PKGCONFIG%;%RUNTIME_PKGCONFIG%;%PKGCONFIG_PATH%"
    +    set "PKG_CONFIG_PATH=%PYTHON_PKGCONFIG%;%RUNTIME_PKGCONFIG%;%PKGCONFIG_PATH%"
     ) else (
    -    set PKG_CONFIG_PATH="%PYTHON_PKGCONFIG%;%RUNTIME_PKGCONFIG%"
    +    set "PKG_CONFIG_PATH=%PYTHON_PKGCONFIG%;%RUNTIME_PKGCONFIG%"
     )
    
     cls
    
  3. After correcting the setenv.cmd script as above, make a GTK bash shell environment by copying the MSYS/MinGW shell icon on the desktop (or making a shortcut to c:\mingw\msys\1.0\msys.bat) , right-clicking, selecting Properties, editing the Target: to be C:\WINDOWS\system32\cmd.exe /C ""C:\Python27\Lib\site-packages\gtk-2.0\runtime\bin\setenv.cmd"&&"C:\MinGW\msys\1.0\msys.bat" and renaming it to GTK MinGW shell. If the icon gets screwed up, select Properties again, Change Icon and point it to the same location as the original MSYS/MinGW shell shortcut's icon path. Note you will still have to point PKG_CONFIG to the GTK runtime pkgconfig.exe and add both /usr/local/lib/pkgconfig, /mingw/lib/pkgconfig and /usr/lib/pkgconfig to your PKG_CONFIG_PATH in your ./configure commands, but this should add all of the other GTK and PKG_CONFIG paths and environmental variables you'll need, especially for dbus-glib. An alternative is to simply add the GTK runtime to the path of your bash shell by editing (or creating) your ~/.bashrc file.
    $ export GTK_BASEPATH="/c/Python27/Lib/site-packages/gtk-2.0/runtime/"
    $ export PATH=$GTK_BASEPATH/bin:$PATH
    
    Another alternative is to start the PyGTK/GTK Command Prompt which executes setenv.cmd, creating several environmental variables in that shell such as PYTHON_ROOT, PYTHON_PKGCONFIG, RUNTIME_PKGCONFIG, PKG_CONFIG_PATH and RUNTIME_BIN, thereby making sure that your GTK environment is correctly configured. Then type c:\mingw\msys\1.0\msys.bat to start a MSYS/MinGW shell which will also set up your MinGW/MSYS environment. Note: you may have already added GTK to your path during installation, depending on what options you selected.
    The library libgio-2.0-0.dll and other binaries are used by dbus-binding-tool.exe and others, so you will need to use this shell, or make the GTK runtime bin folder available, whenever you wan to use dbus-glib.

Build DBus

  1. Download the tarball or clone the git repository a folder in C:\, e.g. C:\DBus. Note: If you clone the repo, then instead of ./configure you will need to use ./autogen.sh which requires autotools. Use mingw-get to install autoconf, automake, m4 and libtool for both MSYS and MinGW. Also you may want to checkout the latest stable tag into your own private branch git checkout -b <myBranch> dbus-1.6.4.
    $ mingw-get install autoconf
    $ mingw-get install automake
    $ mingw-get install libtool
    $ mingw-get install msys-autoconf
    $ mingw-get install msys-automake
    $ mingw-get install msys-m4
    $ mingw-get install msys-libtool
    
  2. Apply the MemoryBarrier macro patch. The location of this patch is debatable, and there have been some mailing list posts, tickets, forks and suggeted patches [1, 2, 3, 4, 5, 6, 7, 8]. I applied it to dbus\dbus-sysdeps-win.c which is where the macro is used. I also added a prototype in the header so that gcc won't warn me about it. I have no idea whether this works as intended, or even what the intent was, so use it at your own risk. It is identical to the macro used by mingw-w64 in winnt.h. The other options are to get rid of the MemoryBarrier() call or use a different compiler such as MSVC or MinGW-w64.

    MemoryBarrier.patch for dbus-sysdeps-win.c

    --- a/dbus/dbus-sysdeps-win.c
    +++ b/dbus/dbus-sysdeps-win.c
    @@ -54,6 +54,13 @@
     #include <windows.h>
     #include <ws2tcpip.h>
     #include <wincrypt.h>
    +
    +__CRT_INLINE VOID MemoryBarrier(VOID)
    +{
    +  LONG Barrier = 0;
    +  __asm__ __volatile__("xchgl %%eax,%0 "
    +    :"=r" (Barrier));
    +}
    
     /* Declarations missing in mingw's headers */
     extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR  StringSid, PSID *Sid);
    

    MemoryBarrierHeader.patch for dbus-sysdeps-win.h

    --- a/dbus/dbus-sysdeps-win.h
    +++ b/dbus/dbus-sysdeps-win.h
    @@ -38,6 +38,8 @@
    
     #define DBUS_CONSOLE_DIR "/var/run/console/"
    
    +
    +void MemoryBarrier(void);
    
     void _dbus_win_set_errno (int err);
     const char* _dbus_win_error_from_last_error (void);
    
    You can use git apply --ignore-space-change --ignore-whitespace <path/to/MemoryBarrier.patch> followed by commit -am "<your message>" or patch <path/to/dbus-sysdeps-win.c> <path/to/MemoryBarrier.patch> if you are using the tarball.
  3. configure, make and install
    $ ./configure --with-dbus-session-bus-default-address=autolaunch: PYTHON=/c/Python27/python PYTHON_INCLUDES=-I/c/Python27/include/ PYTHON_LIBS='-L/c/Python27/Lib -lpython27' PKG_CONFIG=/c/Python27/Lib/site-packages/gtk-2.0/runtime/bin/pkg-config.exe PKG_CONFIG_PATH=/c/Python27/Lib/pkgconfig:/c/Python27/Lib/site-packages/gtk-2.0/runtime/lib/pkgconfig:/c/mingw/msys/1.0/local/lib/pkgconfig:/c/mingw/msys/1.0/lib/pkgconfig:/c/mingw/lib/pkgconfig am_cv_python_pythondir='${prefix}/Lib/site-packages' am_cv_python_pyexecdir='${exec_prefix}/Lib/site-packages'
    $ make
    $ make install
    
  4. Check that it works by opening a daemon, and monitoring it using two MSYS shells.

    MSYS shell with daemon

    $ dbus-daemon --session
    

    MSYS shell with monitor

    $ dbus-monitor
    signal sender=org.freedesktop.DBus -> dest=:1.0 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired   string ":1.0"
    method call sender=:1.0 -> dest=org.freedesktop.DBus serial=3 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch   string "eavesdrop=true,type='method_call'"
    method call sender=:1.0 -> dest=org.freedesktop.DBus serial=4 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch   string "eavesdrop=true,type='method_return'"
    method call sender=:1.0 -> dest=org.freedesktop.DBus serial=5 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch   string "eavesdrop=true,type='error'"
    
    You should see dbus-daemon and dbus-monitor as processes in ms-windows task manager. Use ctrl-c to kill the processes in each MSYS window.

Buld dbus-glib

  1. Download the tarball or clone the git repository on your hardrive, e.g. c:\dbus-glib. If you are using the git repo, checkout the latest tag into your own branch, and then use ./autogen.sh instead of ./configure. Also you may need to add --disable-gtk-doc as a configure option. I did not, but I used the tarball.
  2. confgure, make and install
    $ ./configure PYTHON=/c/Python27/python PYTHON_INCLUDES=-I/c/Python27/include/ PYTHON_LIBS='-L/c/Python27/Lib -lpython27' PKG_CONFIG=/c/Python27/Lib/site-packages/gtk-2.0/runtime/bin/pkg-config.exe PKG_CONFIG_PATH=/c/Python27/Lib/pkgconfig:/c/Python27/Lib/site-packages/gtk-2.0/runtime/lib/pkgconfig:/c/mingw/msys/1.0/local/lib/pkgconfig:/c/mingw/msys/1.0/lib/pkgconfig:/c/mingw/lib/pkgconfig am_cv_python_pythondir='${prefix}/Lib/site-packages' am_cv_python_pyexecdir='${exec_prefix}/Lib/site-packages'
    $ make
    $ make install
    

Build dbus-python, finally!

  1. Download the wip-windows tarball or clone the git repository and checkout 2012-07-04 branch on your hardrive, e.g. c:\dbus-python. Again, if using Git, you should use ./autogen.sh instead of ./configure, with the same arguments.
  2. configure, make and install
    $ ./configure PYTHON=/c/Python27/python PYTHON_INCLUDES=-I/c/Python27/include/ PYTHON_LIBS='-L/c/Python27/Lib -lpython27' PKG_CONFIG=/c/Python27/Lib/site-packages/gtk-2.0/runtime/bin/pkg-config.exe PKG_CONFIG_PATH=/c/Python27/Lib/pkgconfig:/c/Python27/Lib/site-packages/gtk-2.0/runtime/lib/pkgconfig:/c/mingw/msys/1.0/local/lib/pkgconfig:/c/mingw/msys/1.0/lib/pkgconfig:/c/mingw/lib/pkgconfig am_cv_python_pythondir='${prefix}/Lib/site-packages' am_cv_python_pyexecdir='${exec_prefix}/Lib/site-packages'
    
  3. Check that it works by starting Python by adding your MSYS environment site-packages folder to your Python path, starting Python and import dbus.
    $ export PYTHONPATH="c:\\mingw\\msys\\1.0\\local\\lib\\site-packages"
    $ python
    Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import dbus
    >>> session_bus = dbus.SessionBus()
    
  4. You now have a working dbus-python module. Yay!

Links

  1. https://bitbucket.org/bradpitcher/mingw-cross-env/src/5f91fb4e0199/src/dbus-1-fixes.patch
  2. https://sourceforge.net/tracker/?func=detail&atid=102435&aid=3420424&group_id=2435
  3. http://msdn.microsoft.com/en-us/library/ms684208%28VS.85%29.aspx
  4. https://bugs.freedesktop.org/show_bug.cgi?id=41423
  5. https://sourceforge.net/mailarchive/message.php?msg_id=24260705
  6. http://lists.gnu.org/archive/html/mingw-cross-env-list/2011-09/msg00033.html
  7. https://github.com/mxe/mxe/commit/d51ad53b664859b38c3cee61f18c4e8e8810fcef
  8. https://bitbucket.org/vog/mingw-cross-env/changeset/8bfc6d601bb1
This zip file contains an install script, patches, generated binaries, libraries and doc files.

Do not use it for evil.

Generated using markdown_py 2.2.0
Fork me on GitHub Creative Commons License
poquitopicante by Mark Mikofski is licensed under a Creative Commons Attribution 3.0 Unported License.
Based on a work at http://poquitopicante.blogspot.com.
Permissions beyond the scope of this license may be available at http://poquitopicante.blogspot.com/p/darn-disclaimer-and-litigious-license.html.