How to compile Cairo for Visual C++ 2008 (Express edition)
-
01-07-2019 - |
Question
Most precompiled Windows binaries are made with the MSYS+gcc toolchain. It uses MSVCRT runtime, which is incompatible with Visual C++ 2005/2008.
So, how to go about and compile Cairo 1.6.4 (or later) for Visual C++ only. Including dependencies (png,zlib,pixman).
Solution
Here are instructions for building Cairo/Cairomm with Visual C++.
Required:
- Visual C++ 2008 Express SP1 (now includes SDK)
- MSYS 1.0
To use VC++ command line tools, a batch file 'vcvars32.bat' needs to be run.
C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vcvars32.bat
ZLib
Download (and extract) zlib123.zip from http://www.zlib.net/
cd zlib123 nmake /f win32/Makefile.msc dir # zlib.lib is the static library # # zdll.lib is the import library for zlib1.dll # zlib1.dll is the shared library
libpng
Download (and extract) lpng1231.zip from http://www.libpng.org/pub/png/libpng.html
The VC++ 9.0 compiler gives loads of "this might be unsafe" warnings. Ignore them; this is MS security panic (the code is good).
cd lpng1231\lpng1231 # for some reason this is two stories deep nmake /f ../../lpng1231.nmake ZLIB_PATH=../zlib123 dir # libpng.lib is the static library # # dll is not being created
Pixman
Pixman is part of Cairo, but a separate download.
Download (and extract) pixman-0.12.0.tar.gz from http://www.cairographics.org/releases/
Use MSYS to untar via 'tar -xvzf pixman*.tar.gz'
Both Pixman and Cairo have Makefiles for Visual C++ command line compiler (cl), but they use Gnu makefile and Unix-like tools (sed etc.). This means we have to run the make from within MSYS.
Open a command prompt with VC++ command line tools enabled (try 'cl /?'). Turn that command prompt into an MSYS prompt by 'C:\MSYS\1.0\MSYS.BAT'.
DO NOT use the MSYS icon, because then your prompt will now know of VC++. You cannot run .bat files from MSYS.
Try that VC++ tools work from here: 'cl -?'
Try that Gnu make also works: 'make -v'.
Cool.
cd (use /d/... instead of D:) cd pixman-0.12.0/pixman make -f Makefile.win32
This defaults to MMX and SSE2 optimizations, which require a newish x86 processor (Pentium 4 or Pentium M or above: http://fi.wikipedia.org/wiki/SSE2 )
There's quite some warnings but it seems to succeed.
ls release # pixman-1.lib (static lib required by Cairo)
Stay in the VC++ spiced MSYS prompt for also Cairo to compile.
cairo
Download (and extract) cairo-1.6.4.tar.gz from http://www.cairographics.org/releases/
cd cd cairo-1.6.4
The Makefile.win32 here is almost good, but has the Pixman path hardwired.
Use the modified 'Makefile-cairo.win32':
make -f ../Makefile-cairo.win32 CFG=release \ PIXMAN_PATH=../../pixman-0.12.0 \ LIBPNG_PATH=../../lpng1231 \ ZLIB_PATH=../../zlib123
(Write everything on one line, ignoring the backslashes)
It says "no rule to make 'src/cairo-features.h'. Use the manually prepared one (in Cairo > 1.6.4 there may be a 'src/cairo-features-win32.h' that you can simply rename):
cp ../cairo-features.h src/
Retry the make command (arrow up remembers it).
ls src/release # # cairo-static.lib
cairomm (C++ API)
Download (and extract) cairomm-1.6.4.tar.gz from http://www.cairographics.org/releases/
There is a Visual C++ 2005 Project that we can use (via open & upgrade) for 2008.
cairomm-1.6.4\MSCV_Net2005\cairomm\cairomm.vcproj
Changes that need to be done:
Change active configuration to "Release"
Cairomm-1.0 properties (with right click menu)
C++/General/Additional Include Directories: ..\..\..\cairo-1.6.4\src (append to existing) Linker/General/Additional library directories: ..\..\..\cairo-1.6.4\src\release ..\..\..\lpng1231\lpng1231 ..\..\..\zlib123 Linker/Input/Additional dependencies: cairo-static.lib libpng.lib zlib.lib msimg32.lib
- Optimization: fast FPU code
C++/Code generation/Floating point model Fast
Right click on 'cairomm-1.0' and 'build'. There are some warnings.
dir cairomm-1.6.4\MSVC_Net2005\cairomm\Release # # cairomm-1.0.lib # cairomm-1.0.dll # cairomm.def
OTHER TIPS
These steps can build the latest cairo on 2015-11-15 for Visual Studio 2015 community. The debug build is DLL, linking to the DLL version of CRT. The release build is static library, linking to the static link version of CRT and requiring no DLLs.
Install GnuWin
The build scripts require GNU command line tools. The following steps are tested with GnuWin from Chocolatey. MSYS might also work.
Download
zlib128.zip, lpng1619.zip, cairo-1.14.4.tar.xz, pixman-0.32.8.tar.gz
Extract
Extract these archives and rename the directories:
. (my_cairo_build_root)
├─cairo
├─libpng
├─pixman
└─zlib
zlib
Do not build. The build script uses MSVCRT that clashes with Visual Studio 2015. Use the generated lib from libpng build.
libpng
Edit libpng\projects\vstudio\zlib.props
:
- in
<ZLibSrcDir>
remove the version number:..\..\..\..\zlib
- in
<WindowsSDKDesktopARMSupport>
changetrue
tofalse
Open libpng\projects\vstudio\vstudio.sln
in Visual Studio and confirm the upgrade. Use the default Debug
configuration, and right click project libpng
to build. Switch to Release Library
configuration and right click project libpng
to build.
pixman
Edit pixman\Makefile.win32.common
:
- Replace
CFG_CFLAGS = -MD -O2
withCFG_CFLAGS = -MT -O2
(linking to the static link version of CRT in release build) - Replace
@mkdir
with@"mkdir"
(there arecmd
's builtinmkdir
and GnuWin'smkdir
, the quotes force the latter to be used)
Run Visual Studio x86 Native Command Prompt from start menu:
cd /d my_cairo_build_root
cd pixman\pixman
make -f Makefile.win32
make -f Makefile.win32 CFG=debug
cairo
Edit cairo\build\Makefile.win32.common
:
- Replace
CFG_CFLAGS = -MD -O2
withCFG_CFLAGS = -MT -O2
- Replace
CAIRO_LIBS += $(LIBPNG_PATH)/libpng.lib
withCAIRO_LIBS += $(LIBPNG_PATH)/lib/$(CFG)/libpng16.lib
. Now, copy the directorylibpng\projects\vstudio\Debug
into (created)libpng\lib\
and rename it todebug
. Copy the directorylibpng\projects\vstudio\Release Library
intolibpng\lib\
and rename it torelease
. - Replace
CAIRO_LIBS += $(ZLIB_PATH)/zdll.lib
withCAIRO_LIBS += $(LIBPNG_PATH)/lib/$(CFG)/zlib.lib
There are two
@mkdir -p $(CFG)/`dirname $<`
lines. Replace both of them with:@"mkdir" -p $(CFG)/$< @"rmdir" $(CFG)/$<
Edit cairo\build\Makefile.win32.features-h
:
- Replace all
@echo
with@"echo"
There is an unusable link.exe
in GnuWin. Rename C:\GnuWin\bin\link.exe
to link_.exe
to avoid clash.
Run Visual Studio x86 Native Command Prompt from start menu:
cd /d my_cairo_build_root
cd cairo
make -f Makefile.win32 CFG=debug
make -f Makefile.win32 CFG=release
The last two command will show "Built successfully!"
but return error. Ignore them.
Rename back C:\GnuWin\bin\link.exe
.
Configure Visual Studio
Create a directory include
and copy the following headers in:
cairo\cairo-version.h
(notcairo\src\cairo-version.h
)cairo\src\*.h
, excludingcairo\src\cairo-version.h
Add that directory to include path in Visual Studio.
Add cairo\src\$(Configuration)
and libpng\lib\$(Configuration)
to library path. $(Configuration)
will automatically expand to Debug
or Release
when building.
Put cairo\src\debug\cairo.dll
and libpng\lib\debug\libpng16.dll
to one of Windows' PATH
.
Before #include <cairo.h>
, setup the link options:
#ifndef NDEBUG
# pragma comment(lib, "cairo")
#else
#define CAIRO_WIN32_STATIC_BUILD
# pragma comment(lib, "cairo-static")
# pragma comment(lib, "libpng16")
# pragma comment(lib, "zlib")
#endif
The instructions don't seem to work with current version of imlib, I wonder if it's worth reasking this question ?
Did you check here: http://cairographics.org/visualstudio/ ? What do you mean 'It uses MSCVRT runtime, which is incompatible with Visual C++ 2005/2008' ? What are the exact problems you're having?
I ran into two problems when building on Windows (Visual Studio 2008, GNU Make 3.81):
Invalid "if" constructs in src/Makefile.sources. Fixed that using
sed "s/^if \([A-Z_]*\)$/ifeq ($(\1), 1)/" src\Makefile.sources
_lround
is not available on Windows/MSVC. Worked around that usingsed "s/#define _cairo_lround lround/static inline long cairo_const _cairo_lround(double r) { return (long)floor(r + .5); }/"`
(which is probably a poor fix)
These issues aside, everything works great (for both x86 and x86_64 architectures).
I have done this, but I don't have any ready-written instructions. My builds are also rather minimal as I haven't needed support for eg. PNG and SVG files, I just used it to render generated vector graphics to memory buffers.
But what I did was read through the config.h
and other files for the UNIX/GNU build system and write my own suited for MSVC, and then create a project with the appropriate source files. It probably takes a few hours at best to do this, but when you're done it just works ;)
Edit: Do see this page, it has an MSVC 2003 (7.1) project for building cairo: http://slinavlee.googlepages.com/
MSYS+gcc toolchain uses the old MSVCRT runtime library (now built into Windows) and Visual C++ 2005/2008 bring their own. It is a known fact that code should not depend on multiple runtimes. Passing things s.a. file handles, memory pointers etc. will be affected, and will cause apparently random crashes in such scenario.
I have not been bitted by this. Then again, I don't really target Windows any more, either. But I've been told enough to not even try the solution.
What could have worked, is linking all the dependencies statically into the lib (say, Cairomm). Static libs don't have a runtime bound to them, do they? But I did not try this. I actually got the VC++ building of all ingredients to work, but it took days.
I hadn't found the URL you give. Strange in itself; I looked 'everywhere'. Then again, it is for Visual Studio 2003.NET, so two generations behind already.