end to end build for win32

Goal: Build CairoGraphics dll as a single redistributable DLL. Use free tools that anyone can download. End up with a dll that doesn't need any other dlls, system or not. Be able to do the entire thing from a script if necessary, not requiring any interaction.

Original Author: Travis Griggs (travisgriggs@gmail.com)

Original Version: 1.8.8

Other Tested Versions:

Tools Needed:

This recipe for building may seem tediuous, in that it uses command line interface to do things. It was a goal in this case, that it be script-able, and require no user interaction. The first 3 steps are exceptions. In many cases, you could do things just as simply/quickly using file explorer, or wordpad. I've pointed these out in ...or... lines below some of the more obvious steps.

Install MSYS

Download and install MSYS.

In the following examples, I've installed mine in c:\Program Files\msys.

MSYS provides programs to do a very minimal unix system on your windows box. You do not need to install MINGW or the Mozilla Build Environment.

Install Dev Studio Express

Download and install Microsoft Visual C++ Studio Express.

I found that I could not use vcbuild to convert/upgrade projects until I followed the steps here. It may have been if I'd originally registered it, I wouldn't have had those problems?

Install curl (optional)

Download and install curl.

Make sure curl is in your path.

You don't technically need this. You can download the links to your build directory interactively using your favorite web browser. If you're not interesting in scripting it up, doing that is probably lighter weight than installing curl, unless you've just been waiting for a reason to do so.

Open a command shell/Setup environment

Open cmd32.exe. We'll use a command shell from here on out. If you need to close this and start again, you'll need to reproduce any of the environment variable settings we setup in here.

    set PATH=%PATH%;C:\Program Files\msys\bin


(adjust appended path as fits your installation; quotation marks on second command are necessary if you have spaces in said path)

Create/Clean/Set Build Directory

Designate a directory to work in. Clean it out and then we'll do all work in there with fresh copies.

   rmdir /S /Q %ROOTDIR%
   mkdir %ROOTDIR%
   cd %ROOTDIR%

Download and untar tarballs

Use curl to download FOUR tarballs: zlib, libpng, pixman, cairo. Adjust specific version paths as desired

   curl http://www.zlib.net/zlib-1.2.3.tar.gz -o zlib.tgz
   curl ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.2.40.tar.gz -o libpng.tgz
   curl http://www.cairographics.org/releases/pixman-0.16.2.tar.gz -o pixman.tgz
   curl http://www.cairographics.org/releases/cairo-1.8.8.tar.gz -o cairo.tgz

...or use Firefox/IE to navigate to the various sites and download the links

   tar -xzf zlib.tgz
   tar -xzf libpng.tgz
   tar -xzf pixman.tgz
   tar -xzf cairo.tgz

...or if you have a utility such as 7-zip installed, you can just select and "extract all" these from the file explorer

   move zlib-* zlib
   move libpng-* libpng
   move pixman-* pixman
   move cairo-* cairo

...or just rename them interactively using the file manager

Why the last 4 move commands? The default directory names are things like pixman-0.1.16 (version numbers included in the name). Some of the packages have compile paths dependent on the simpler names. So we do all 4 of them to keep them simple and consistent.

Build zlib

Zlib has a project (vcproj_ file, but only for old Visual C++ 6.0 versions. Our free version of Visual Studio 2009 won't upgrade it. Fortunately, the libpng project, is nice enough to include a project file that is new enough for our free version. So we create a directory for it, and copy it over:

   mkdir %ROOTDIR%\zlib\projects\visualc71
   cd %ROOTDIR%\zlib\projects\visualc71
   copy %ROOTDIR%\libpng\projects\visualc71\zlib.vcproj .

...or use the file manager to create the projects\visualc71 directory and drag a copy of libpng\projects\visualc71\zlib.vcproj there

Now we can upgrade it. This does whatever needs to happen so we can build it with our new and free version of Express.

   vcbuild /upgrade zlib.vcproj

This will produce a bunch of scary looking warning text. Some of it yellow. It's ok, ignore it.

Our next problem is, that the project file, by default is configured to build with the /MD option, which means it will be dynamically linked to the Microsoft runtime. This will be a problem if it links to the current MS runtime library, because target deployment machines won't necessarily have that specific version. There is no real dependency on a particular version. So it's easier to compile that statically in. It doesn't make the library that much bigger.

   sed /RuntimeLibrary=/s/2/0/ zlib.vcproj > fixed.vcproj
   move /Y fixed.vcproj zlib.vcproj

...or open zlib.vcproj with Wordpad and use a search/replace to change all RuntimeLibrary="2" to RuntimeLibrary="0"

Finally, build it

   vcbuild zlib.vcproj "LIB Release"

Build libpng

This is very similiar, but a little simpler, than building zlib.

   cd %ROOTDIR%\libpng\projects\visualc71
   vcbuild /upgrade libpng.vcproj
   sed /RuntimeLibrary=/s/2/0/ libpng.vcproj > fixed.vcproj
   move /Y fixed.vcproj libpng.vcproj
   vcbuild libpng.vcproj "LIB Release"

Build pixman

First, we patch up Pixman's Makefiles so that it too does -MT (static) instead of -MD (dynamic) for compiling. This operation is not necessary in recent Pixman releases (0.18.0 for example) as they already use -MD. Pixman does not compile with the .vcproj files though, but rather with Makefiles, so we edit a different file, a little differently, but it's the same basic approach.

   cd %ROOTDIR%\pixman\pixman
   sed s/-MD/-MT/ Makefile.win32 > Makefile.fixed
   move /Y Makefile.fixed Makefile.win32

...or open Makefile.win32 with Wordpad and use a search/replace to change all -MT to -MD

And now, compile it

   make -f Makefile.win32 "CFG=release"

Setup additional INCLUDE/LIB paths

Before we proceed with building the final Cairo library, we have to add the results of the previous 3 builds to our INCLUDE and LIB paths

   set INCLUDE=%INCLUDE%;%ROOTDIR%\pixman\pixman
   set INCLUDE=%INCLUDE%;%ROOTDIR%\cairo\boilerplate
   set INCLUDE=%INCLUDE%;%ROOTDIR%\cairo\src

   set LIB=%LIB%;%ROOTDIR%\zlib\projects\visualc71\Win32_LIB_Release\Zlib
   set LIB=%LIB%;%ROOTDIR%\libpng\projects\visualc71\Win32_LIB_Release

Build cairo

This is similiar to pixman. There's an additional edit we do to the Makefile (replacing zdll.lib with zlib.lib).

   cd %ROOTDIR%\cairo
   sed s/-MD/-MT/ build\Makefile.win32.common > build\Makefile.fixed
   move /Y build\Makefile.fixed build\Makefile.win32.common
   sed s/zdll.lib/zlib.lib/ build\Makefile.win32.common > build\Makefile.fixed
   move /Y build\Makefile.fixed build\Makefile.win32.common

   make -f Makefile.win32 "CFG=release"

   if you have errors, try to remove all chars " from src/cairo-features.h


You've got a standalone cairo.dll... (found in %ROOTDIR%\cairo\src\release)