<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Objarni</id>
	<title>Inkscape Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Objarni"/>
	<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/Special:Contributions/Objarni"/>
	<updated>2026-05-05T18:21:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99461</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99461"/>
		<updated>2016-05-11T09:21:42Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Using CMake to build Inkscape */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Using CMake to build Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake /path/to/inkscape&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/path/to/inkscape is the folder where you checked out inkscape to.&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;br /&gt;
&lt;br /&gt;
== Using CMake to run tests ==&lt;br /&gt;
&lt;br /&gt;
First, install Google Test framework by running download-gtest.sh in the main directory of inkscape source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/inkscape&lt;br /&gt;
bash download-gtest.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, toggle the CMake config var &amp;quot;WITH_GTEST&amp;quot; to ON, e.g. by editing CMakeCache.txt, or by passing &amp;quot;-DWITH_GTEST=ON&amp;quot; to cmake. Don't forget to re-run cmake after the configuration change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/buildinkscape&lt;br /&gt;
# modify CMakeCache.txt&lt;br /&gt;
cmake ../inkscape&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, run &amp;quot;make check&amp;quot; from same directory to run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make check&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring your build further ==&lt;br /&gt;
&lt;br /&gt;
It is possible to change some more options of the build, e.g. whether to compile against GTK2 or GTK3 libraries. If you fiddle a lot with this, you may want to install the interactive cmake configuration tool &amp;quot;ccmake&amp;quot;, like so:&lt;br /&gt;
[[File:CCMAKE.PNG|200px|thumb|right|ccmake screen capture]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install cmake-curses-gui&lt;br /&gt;
ccmake ../inkscape  # In buildinkscape folder&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ccmake utility will have features to re-run cmake for you before exiting.&amp;lt;br /&amp;gt;&lt;br /&gt;
For example you can use CMAKE_INSTALL_PREFIX Path in which &amp;quot;make install&amp;quot; installs Inkscape and allow handle multiple Inkscape instalations. &amp;lt;br /&amp;gt;&lt;br /&gt;
Press enter on the line to edit. &amp;lt;br /&amp;gt;Press again to save, when all your changes are done press c to configure, exit help and press g to generate.&amp;lt;br /&amp;gt; After this you exit ccmake and can finish with make.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== adding options to cmake ===&lt;br /&gt;
&lt;br /&gt;
you can specify some variable on cmake invokation. i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake .. -G &amp;quot;MinGW Makefiles&amp;quot; -DCMAKE_BUILD_TYPE=Debug&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Useful CMake configuration variables include&lt;br /&gt;
&lt;br /&gt;
* CMAKE_BUILD_TYPE: Either Release or Debug (a string).&lt;br /&gt;
* WITH_GTK3_EXPERIMENTAL: ON/OFF. Toggle between GTK2 or GTK3 ui toolkit.&lt;br /&gt;
* CMAKE_INSTALL_PREFIX: Path in which &amp;quot;make install&amp;quot; installs Inkscape.&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99456</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99456"/>
		<updated>2016-05-11T09:21:06Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Using CMake to build Inkscape */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Using CMake to build Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake path/to/inkscape/sources&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;br /&gt;
&lt;br /&gt;
== Using CMake to run tests ==&lt;br /&gt;
&lt;br /&gt;
First, install Google Test framework by running download-gtest.sh in the main directory of inkscape source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/inkscape&lt;br /&gt;
bash download-gtest.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, toggle the CMake config var &amp;quot;WITH_GTEST&amp;quot; to ON, e.g. by editing CMakeCache.txt, or by passing &amp;quot;-DWITH_GTEST=ON&amp;quot; to cmake. Don't forget to re-run cmake after the configuration change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/buildinkscape&lt;br /&gt;
# modify CMakeCache.txt&lt;br /&gt;
cmake ../inkscape&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, run &amp;quot;make check&amp;quot; from same directory to run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make check&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring your build further ==&lt;br /&gt;
&lt;br /&gt;
It is possible to change some more options of the build, e.g. whether to compile against GTK2 or GTK3 libraries. If you fiddle a lot with this, you may want to install the interactive cmake configuration tool &amp;quot;ccmake&amp;quot;, like so:&lt;br /&gt;
[[File:CCMAKE.PNG|200px|thumb|right|ccmake screen capture]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install cmake-curses-gui&lt;br /&gt;
ccmake ../inkscape  # In buildinkscape folder&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ccmake utility will have features to re-run cmake for you before exiting.&amp;lt;br /&amp;gt;&lt;br /&gt;
For example you can use CMAKE_INSTALL_PREFIX Path in which &amp;quot;make install&amp;quot; installs Inkscape and allow handle multiple Inkscape instalations. &amp;lt;br /&amp;gt;&lt;br /&gt;
Press enter on the line to edit. &amp;lt;br /&amp;gt;Press again to save, when all your changes are done press c to configure, exit help and press g to generate.&amp;lt;br /&amp;gt; After this you exit ccmake and can finish with make.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== adding options to cmake ===&lt;br /&gt;
&lt;br /&gt;
you can specify some variable on cmake invokation. i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake .. -G &amp;quot;MinGW Makefiles&amp;quot; -DCMAKE_BUILD_TYPE=Debug&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Useful CMake configuration variables include&lt;br /&gt;
&lt;br /&gt;
* CMAKE_BUILD_TYPE: Either Release or Debug (a string).&lt;br /&gt;
* WITH_GTK3_EXPERIMENTAL: ON/OFF. Toggle between GTK2 or GTK3 ui toolkit.&lt;br /&gt;
* CMAKE_INSTALL_PREFIX: Path in which &amp;quot;make install&amp;quot; installs Inkscape.&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99371</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99371"/>
		<updated>2016-05-05T20:48:28Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
* [https://bugs.launchpad.net/inkscape/+bugs?field.tag=gtk3 GTK 3 Bugs]&lt;br /&gt;
* Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc. See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
** This might have been fixed by r14870 - the icon clipping problem.&lt;br /&gt;
* &amp;lt;strike&amp;gt;Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here). This is probably caused by the use of SPIcon instead of a standard GtkImage widget.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** The clipping of icons in the toolbar is fixed in r14870. Problem had to do with custom button widget which wraps icon. The preferred/minimum width/height was not taking into account the padding around the icon.&lt;br /&gt;
** We have too many ways of creating buttons with icons which leads to inconsistency of behavior.&lt;br /&gt;
* All custom widgets now use the Cairo drawing model.  All need to be fully tested, and several (e.g., the filter editor) are not rendered correctly.&lt;br /&gt;
* Several of the Gtk+ widgets have changed their layout (in particular, the GtkSpinButton is now much wider). Many of the toolbars now overflow the screen horizontally, and many dialogs are now far too wide.  The layout of affected containers should be redesigned to account for this.&lt;br /&gt;
* The rules for sizing of widgets within containers has changed in Gtk+ 3.  In many cases, widgets will initially appear far too big, or with zero size.  All dialogs and containers need to be checked for these issues.&lt;br /&gt;
* Mac Issues:&lt;br /&gt;
** No tablet input support on Mac (e.g. Wacom). MyPaint seems to be working on this.&lt;br /&gt;
*** https://community.mypaint.org/t/how-to-build-mypaint-on-mac-osx-without-macports/344&lt;br /&gt;
*** https://bugzilla.gnome.org/show_bug.cgi?id=695701&lt;br /&gt;
** Support for global menu bar.&lt;br /&gt;
*** GEdit uses OSX menu bar and has native file dialogs&lt;br /&gt;
* The text &amp;quot;Blur&amp;quot; and &amp;quot;Opacity&amp;quot; inside the &amp;quot;interactive progress bar&amp;quot; widgets (are these custom widgets?) in Fill and stroke dialog are cut in half or less, and are rendered unreadable. There is also some different modes of interaction, with top half of the widgets meaning &amp;quot;move instantly to this point&amp;quot; and (part of) bottom half meaning &amp;quot;slightly adjust value&amp;quot;, however the latter is really hard to use as it's something like on or two pixel rows high.&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * GtkHBox and GtkVBox are now just GtkBox with an orientation attribute.&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
* Rulers - src/widgets/ruler.cpp&lt;br /&gt;
** Should probably be updated from GIMP.&lt;br /&gt;
* SPIcon - src/widgets/icon.cpp&lt;br /&gt;
** Should be replaced with regular GtkImage.&lt;br /&gt;
** SPIcon does more than rendering the icon:&lt;br /&gt;
**# Handles custom size: Inkscape::ICON_SIZE_DECORATION&lt;br /&gt;
**# Old to new icon name conversion&lt;br /&gt;
**# Rendering icons from icon.svg&lt;br /&gt;
**# Rendering into cache&lt;br /&gt;
** All the above could be removed.&lt;br /&gt;
* SPCanvas - src/display/sp-canvas.cpp&lt;br /&gt;
** Needs to stay a custom widget. Fixed for GTK3.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;br /&gt;
&lt;br /&gt;
== Deferred changes ==&lt;br /&gt;
&lt;br /&gt;
Work items, which should be carried out after the release of Inkscape 0.93.  These are tasks, which would be impractical to perform until after we have permanently ended our support for Gtk+ 2. For example, these may make use of new Gtk+ 3 features, which have no simple fallback available in Gtk+ 2.&lt;br /&gt;
&lt;br /&gt;
* Delete all Gtk+ 2 backward-compatibility code.  This will remove over 700 blocks of conditional build instructions from our code base, and thousands of lines of redundant code.  This is essential for future maintainability, and will greatly simplify future work on Gtk+ 3 features.&lt;br /&gt;
* Load all theme information from an external CSS style sheet.  This will potentially tidy our code by removing hard-coded styling instructions, and will make it possible to properly apply user themes to Inkscape.&lt;br /&gt;
* Switch to using a GtkIconTheme, with all custom icons installed in a standard way instead of bundled within a single SVG document.  This will make it easier to provide user icon themes, and get rid of a lot of deprecated code.&lt;br /&gt;
** We should also unify all the code for creating buttons with icons.&lt;br /&gt;
** GTK3 respects the HiDPI setting while GTK2 does not. System icons are rendered with high DPI when needed but Inkscape specific icons are not. This will probably be fixed by moving to GtkIconTheme.&lt;br /&gt;
** Many GTK methods using GtkIconSize have been deprecated but GtkIconSize itself has not been. This can be confusing. We have a custom value for GtkIconSize that we should try to remove.&lt;br /&gt;
* Switch to using GtkApplication instead of GtkMain.&lt;br /&gt;
* Switch to using GAction instead of GtkAction &amp;lt;- this one might be deferred indefinitely; see Gimp's direction for comparison (Gimp has stated they will not switch).&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99366</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99366"/>
		<updated>2016-05-05T20:45:42Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Issues */ added issue about blur and opacity widgets&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
* [https://bugs.launchpad.net/inkscape/+bugs?field.tag=gtk3 GTK 3 Bugs]&lt;br /&gt;
* Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc. See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
* &amp;lt;strike&amp;gt;Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here). This is probably caused by the use of SPIcon instead of a standard GtkImage widget.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** The clipping of icons in the toolbar is fixed in r14870. Problem had to do with custom button widget which wraps icon. The preferred/minimum width/height was not taking into account the padding around the icon.&lt;br /&gt;
** We have too many ways of creating buttons with icons which leads to inconsistency of behavior.&lt;br /&gt;
* All custom widgets now use the Cairo drawing model.  All need to be fully tested, and several (e.g., the filter editor) are not rendered correctly.&lt;br /&gt;
* Several of the Gtk+ widgets have changed their layout (in particular, the GtkSpinButton is now much wider). Many of the toolbars now overflow the screen horizontally, and many dialogs are now far too wide.  The layout of affected containers should be redesigned to account for this.&lt;br /&gt;
* The rules for sizing of widgets within containers has changed in Gtk+ 3.  In many cases, widgets will initially appear far too big, or with zero size.  All dialogs and containers need to be checked for these issues.&lt;br /&gt;
* Mac Issues:&lt;br /&gt;
** No tablet input support on Mac (e.g. Wacom). MyPaint seems to be working on this.&lt;br /&gt;
*** https://community.mypaint.org/t/how-to-build-mypaint-on-mac-osx-without-macports/344&lt;br /&gt;
*** https://bugzilla.gnome.org/show_bug.cgi?id=695701&lt;br /&gt;
** Support for global menu bar.&lt;br /&gt;
*** GEdit uses OSX menu bar and has native file dialogs&lt;br /&gt;
* The text &amp;quot;Blur&amp;quot; and &amp;quot;Opacity&amp;quot; inside the &amp;quot;interactive progress bar&amp;quot; widgets (are these custom widgets?) in Fill and stroke dialog are cut in half or less, and are rendered unreadable. There is also some different modes of interaction, with top half of the widgets meaning &amp;quot;move instantly to this point&amp;quot; and (part of) bottom half meaning &amp;quot;slightly adjust value&amp;quot;, however the latter is really hard to use as it's something like on or two pixel rows high.&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * GtkHBox and GtkVBox are now just GtkBox with an orientation attribute.&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
* Rulers - src/widgets/ruler.cpp&lt;br /&gt;
** Should probably be updated from GIMP.&lt;br /&gt;
* SPIcon - src/widgets/icon.cpp&lt;br /&gt;
** Should be replaced with regular GtkImage.&lt;br /&gt;
** SPIcon does more than rendering the icon:&lt;br /&gt;
**# Handles custom size: Inkscape::ICON_SIZE_DECORATION&lt;br /&gt;
**# Old to new icon name conversion&lt;br /&gt;
**# Rendering icons from icon.svg&lt;br /&gt;
**# Rendering into cache&lt;br /&gt;
** All the above could be removed.&lt;br /&gt;
* SPCanvas - src/display/sp-canvas.cpp&lt;br /&gt;
** Needs to stay a custom widget. Fixed for GTK3.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;br /&gt;
&lt;br /&gt;
== Deferred changes ==&lt;br /&gt;
&lt;br /&gt;
Work items, which should be carried out after the release of Inkscape 0.93.  These are tasks, which would be impractical to perform until after we have permanently ended our support for Gtk+ 2. For example, these may make use of new Gtk+ 3 features, which have no simple fallback available in Gtk+ 2.&lt;br /&gt;
&lt;br /&gt;
* Delete all Gtk+ 2 backward-compatibility code.  This will remove over 700 blocks of conditional build instructions from our code base, and thousands of lines of redundant code.  This is essential for future maintainability, and will greatly simplify future work on Gtk+ 3 features.&lt;br /&gt;
* Load all theme information from an external CSS style sheet.  This will potentially tidy our code by removing hard-coded styling instructions, and will make it possible to properly apply user themes to Inkscape.&lt;br /&gt;
* Switch to using a GtkIconTheme, with all custom icons installed in a standard way instead of bundled within a single SVG document.  This will make it easier to provide user icon themes, and get rid of a lot of deprecated code.&lt;br /&gt;
** We should also unify all the code for creating buttons with icons.&lt;br /&gt;
** GTK3 respects the HiDPI setting while GTK2 does not. System icons are rendered with high DPI when needed but Inkscape specific icons are not. This will probably be fixed by moving to GtkIconTheme.&lt;br /&gt;
** Many GTK methods using GtkIconSize have been deprecated but GtkIconSize itself has not been. This can be confusing. We have a custom value for GtkIconSize that we should try to remove.&lt;br /&gt;
* Switch to using GtkApplication instead of GtkMain.&lt;br /&gt;
* Switch to using GAction instead of GtkAction &amp;lt;- this one might be deferred indefinitely; see Gimp's direction for comparison (Gimp has stated they will not switch).&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99326</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99326"/>
		<updated>2016-05-04T10:39:10Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Widgets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
* [https://bugs.launchpad.net/inkscape/+bugs?field.tag=gtk3 GTK 3 Bugs]&lt;br /&gt;
* Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc. See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
* &amp;lt;strike&amp;gt;Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here). This is probably caused by the use of SPIcon instead of a standard GtkImage widget.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** The clipping of icons in the toolbar is fixed in r14870. Problem had to do with custom button widget which wraps icon. The preferred/minimum width/height was not taking into account the padding around the icon.&lt;br /&gt;
** We have too many ways of creating buttons with icons which leads to inconsistency of behavior.&lt;br /&gt;
* All custom widgets now use the Cairo drawing model.  All need to be fully tested, and several (e.g., the filter editor) are not rendered correctly.&lt;br /&gt;
* Several of the Gtk+ widgets have changed their layout (in particular, the GtkSpinButton is now much wider). Many of the toolbars now overflow the screen horizontally, and many dialogs are now far too wide.  The layout of affected containers should be redesigned to account for this.&lt;br /&gt;
* The rules for sizing of widgets within containers has changed in Gtk+ 3.  In many cases, widgets will initially appear far too big, or with zero size.  All dialogs and containers need to be checked for these issues.&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * GtkHBox and GtkVBox are now just GtkBox with an orientation attribute.&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
* Rulers - src/widgets/ruler.cpp&lt;br /&gt;
** Should probably be updated from GIMP.&lt;br /&gt;
* SPIcon - src/widgets/icon.cpp&lt;br /&gt;
** Should be replaced with regular GtkImage.&lt;br /&gt;
** SPIcon does much more than just rendering the icon. I (Tav) don't think it can be replaced by GtkImage.&lt;br /&gt;
*** What more does it do? (objarni)&lt;br /&gt;
* SPCanvas - src/display/sp-canvas.cpp&lt;br /&gt;
** Needs to stay a custom widget. Fixed for GTK3.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;br /&gt;
&lt;br /&gt;
== Deferred changes ==&lt;br /&gt;
&lt;br /&gt;
Work items, which should be carried out after the release of Inkscape 0.93.  These are tasks, which would be impractical to perform until after we have permanently ended our support for Gtk+ 2. For example, these may make use of new Gtk+ 3 features, which have no simple fallback available in Gtk+ 2.&lt;br /&gt;
&lt;br /&gt;
* Delete all Gtk+ 2 backward-compatibility code.  This will remove over 700 blocks of conditional build instructions from our code base, and thousands of lines of redundant code.  This is essential for future maintainability, and will greatly simplify future work on Gtk+ 3 features.&lt;br /&gt;
* Load all theme information from an external CSS style sheet.  This will potentially tidy our code by removing hard-coded styling instructions, and will make it possible to properly apply user themes to Inkscape.&lt;br /&gt;
* Switch to using a GtkIconTheme, with all custom icons installed in a standard way instead of bundled within a single SVG document.  This will make it easier to provide user icon themes, and get rid of a lot of deprecated code.&lt;br /&gt;
** We should also unify all the code for creating buttons with icons.&lt;br /&gt;
** GTK3 respects the HiDPI setting while GTK2 does not. System icons are rendered with high DPI when needed but Inkscape specific icons are not. This will probably be fixed by moving to GtkIconTheme.&lt;br /&gt;
** Many GTK methods using GtkIconSize have been deprecated but GtkIconSize itself has not been. This can be confusing. We have a custom value for GtkIconSize that we should try to remove.&lt;br /&gt;
* Switch to using GtkApplication instead of GtkMain.&lt;br /&gt;
* Switch to using GAction instead of GtkAction &amp;lt;- this one might be deferred indefinitely; see Gimp's direction for comparison (Gimp has stated they will not switch).&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99321</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99321"/>
		<updated>2016-05-04T10:34:32Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
* [https://bugs.launchpad.net/inkscape/+bugs?field.tag=gtk3 GTK 3 Bugs]&lt;br /&gt;
* Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc. See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
* &amp;lt;strike&amp;gt;Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here). This is probably caused by the use of SPIcon instead of a standard GtkImage widget.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** The clipping of icons in the toolbar is fixed in r14870. Problem had to do with custom button widget which wraps icon. The preferred/minimum width/height was not taking into account the padding around the icon.&lt;br /&gt;
** We have too many ways of creating buttons with icons which leads to inconsistency of behavior.&lt;br /&gt;
* All custom widgets now use the Cairo drawing model.  All need to be fully tested, and several (e.g., the filter editor) are not rendered correctly.&lt;br /&gt;
* Several of the Gtk+ widgets have changed their layout (in particular, the GtkSpinButton is now much wider). Many of the toolbars now overflow the screen horizontally, and many dialogs are now far too wide.  The layout of affected containers should be redesigned to account for this.&lt;br /&gt;
* The rules for sizing of widgets within containers has changed in Gtk+ 3.  In many cases, widgets will initially appear far too big, or with zero size.  All dialogs and containers need to be checked for these issues.&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * GtkHBox and GtkVBox are now just GtkBox with an orientation attribute.&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
* Rulers - src/widgets/ruler.cpp&lt;br /&gt;
** Should probably be updated from GIMP.&lt;br /&gt;
* SPIcon - src/widgets/icon.cpp&lt;br /&gt;
** Should be replaced with regular GtkImage.&lt;br /&gt;
** SPIcon does much more than just rendering the icon. I (Tav) don't think it can be replaced by GtkImage.&lt;br /&gt;
* SPCanvas - src/display/sp-canvas.cpp&lt;br /&gt;
** Needs to stay a custom widget. Fixed for GTK3.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;br /&gt;
&lt;br /&gt;
== Deferred changes ==&lt;br /&gt;
&lt;br /&gt;
Work items, which should be carried out after the release of Inkscape 0.93.  These are tasks, which would be impractical to perform until after we have permanently ended our support for Gtk+ 2. For example, these may make use of new Gtk+ 3 features, which have no simple fallback available in Gtk+ 2.&lt;br /&gt;
&lt;br /&gt;
* Delete all Gtk+ 2 backward-compatibility code.  This will remove over 700 blocks of conditional build instructions from our code base, and thousands of lines of redundant code.  This is essential for future maintainability, and will greatly simplify future work on Gtk+ 3 features.&lt;br /&gt;
* Load all theme information from an external CSS style sheet.  This will potentially tidy our code by removing hard-coded styling instructions, and will make it possible to properly apply user themes to Inkscape.&lt;br /&gt;
* Switch to using a GtkIconTheme, with all custom icons installed in a standard way instead of bundled within a single SVG document.  This will make it easier to provide user icon themes, and get rid of a lot of deprecated code.&lt;br /&gt;
** We should also unify all the code for creating buttons with icons.&lt;br /&gt;
** GTK3 respects the HiDPI setting while GTK2 does not. System icons are rendered with high DPI when needed but Inkscape specific icons are not. This will probably be fixed by moving to GtkIconTheme.&lt;br /&gt;
** Many GTK methods using GtkIconSize have been deprecated but GtkIconSize itself has not been. This can be confusing. We have a custom value for GtkIconSize that we should try to remove.&lt;br /&gt;
* Switch to using GtkApplication instead of GtkMain.&lt;br /&gt;
* Switch to using GAction instead of GtkAction &amp;lt;- this one might be deferred indefinitely; see Gimp's direction for comparison (Gimp has stated they will not switch).&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99251</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99251"/>
		<updated>2016-05-02T07:18:11Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Issues */ better formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
* Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc. See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
&lt;br /&gt;
* Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here)&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * No patterns documented yet&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
 * Rulers - src/widgets/rulers.cpp&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99246</id>
		<title>GTK+ 3 issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=GTK%2B_3_issues&amp;diff=99246"/>
		<updated>2016-05-02T07:17:37Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Issues */ added a couple of issues&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for Gtk documentation, any issues, questions or notes about the porting of inkscape to Gtk3. This document will be sent to the gtk/gnome developers and may be useful for Gimp developers who undergo the same process.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
Document your issues with porting Inkscape to Gtk3 below.&lt;br /&gt;
&lt;br /&gt;
 * Jumping palette. The color bar/palette does not seem to be able to decide how high it should be, at least for some combinations of palette width, height, etc.&lt;br /&gt;
   See launchpad bug [https://bugs.launchpad.net/inkscape/+bug/1201545 #1201545].&lt;br /&gt;
&lt;br /&gt;
 * Icons are too small / cut. (if someone can find the launchpad bug for this one, please add link here)&lt;br /&gt;
&lt;br /&gt;
== Standard Practice ==&lt;br /&gt;
&lt;br /&gt;
List any repetative actions during the upgrade and note anything that needed doing when moving from gtk2 to gtk3 widgets (for examine hbox and vbox) be clear if the action is using gtk3 or gtkmm (which often papers over some of the move to gtk3)&lt;br /&gt;
&lt;br /&gt;
 * No patterns documented yet&lt;br /&gt;
&lt;br /&gt;
== Widgets ==&lt;br /&gt;
&lt;br /&gt;
List any and all custom widgets currently being used in Inkscape.&lt;br /&gt;
&lt;br /&gt;
 * Rulers - src/widgets/rulers.cpp&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
&lt;br /&gt;
Any ideas which are interesting&lt;br /&gt;
&lt;br /&gt;
 * No ideas yet&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99126</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99126"/>
		<updated>2016-04-16T08:27:22Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Configuring your build further */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Using CMake to build Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake ./path/to/inkscape/sources&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;br /&gt;
&lt;br /&gt;
== Using CMake to run tests ==&lt;br /&gt;
&lt;br /&gt;
First, install Google Test framework by running download-gtest.sh in the main directory of inkscape source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/inkscape&lt;br /&gt;
bash download-gtest.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, toggle the CMake config var &amp;quot;WITH_GTEST&amp;quot; to ON, e.g. by editing CMakeCache.txt, or by passing &amp;quot;-DWITH_GTEST=ON&amp;quot; to cmake. Don't forget to re-run cmake after the configuration change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/buildinkscape&lt;br /&gt;
# modify CMakeCache.txt&lt;br /&gt;
cmake ../inkscape&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, run &amp;quot;make check&amp;quot; from same directory to run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make check&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring your build further ==&lt;br /&gt;
&lt;br /&gt;
It is possible to change some more options of the build, e.g. whether to compile against GTK2 or GTK3 libraries. If you fiddle a lot with this, you may want to install the interactive cmake configuration tool &amp;quot;ccmake&amp;quot;, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install cmake-curses-gui&lt;br /&gt;
ccmake ../inkscape  # In buildinkscape folder&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ccmake utility will have features to re-run cmake for you before exiting.&lt;br /&gt;
&lt;br /&gt;
Useful CMake configuration variables include&lt;br /&gt;
&lt;br /&gt;
* CMAKE_BUILD_TYPE: Either Release or Debug (a string).&lt;br /&gt;
* WITH_GTK3_EXPERIMENTAL: ON/OFF. Toggle between GTK2 or GTK3 ui toolkit.&lt;br /&gt;
* CMAKE_INSTALL_PREFIX: Path in which &amp;quot;make install&amp;quot; installs Inkscape.&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99121</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99121"/>
		<updated>2016-04-15T18:52:23Z</updated>

		<summary type="html">&lt;p&gt;Objarni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Using CMake to build Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake ./path/to/inkscape/sources&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;br /&gt;
&lt;br /&gt;
== Using CMake to run tests ==&lt;br /&gt;
&lt;br /&gt;
First, install Google Test framework by running download-gtest.sh in the main directory of inkscape source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/inkscape&lt;br /&gt;
bash download-gtest.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, toggle the CMake config var &amp;quot;WITH_GTEST&amp;quot; to ON, e.g. by editing CMakeCache.txt, or by passing &amp;quot;-DWITH_GTEST=ON&amp;quot; to cmake. Don't forget to re-run cmake after the configuration change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/buildinkscape&lt;br /&gt;
# modify CMakeCache.txt&lt;br /&gt;
cmake ../inkscape&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, run &amp;quot;make check&amp;quot; from same directory to run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make check&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring your build further ==&lt;br /&gt;
&lt;br /&gt;
It is possible to change some more options of the build, e.g. whether to compile against GTK2 or GTK3 libraries. If you fiddle a lot with this, you may want to install the interactive cmake configuration tool &amp;quot;ccmake&amp;quot;, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install cmake-curses-gui&lt;br /&gt;
ccmake ../inkscape  # In buildinkscape folder&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ccmake utility will have features to re-run cmake for you before exiting.&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99111</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99111"/>
		<updated>2016-04-15T13:57:21Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Testing/Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Using CMake to build Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake ./path/to/inkscape/sources&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;br /&gt;
&lt;br /&gt;
== Using CMake to run tests ==&lt;br /&gt;
&lt;br /&gt;
First, install Google Test framework by running download-gtest.sh in root of inkscape source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/inkscape&lt;br /&gt;
./download-gtest.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, toggle the CMake config var &amp;quot;WITH_GTEST&amp;quot; to ON, e.g. by editing CMakeCache.txt or by using ccmake. Don't forget to re-run cmake after the configuration change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/buildinkscape&lt;br /&gt;
# modify CMakeCache.txt&lt;br /&gt;
cmake ../inkscape&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, run &amp;quot;make check&amp;quot; from same directory to run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make check&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99106</id>
		<title>CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=CMake&amp;diff=99106"/>
		<updated>2016-04-15T11:31:37Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* How you can help */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work is a on going to get this build system functional!'''&lt;br /&gt;
&lt;br /&gt;
Cmake is a cross-platform build system know to work on all major platforms we support (*nix, Windows, OSX).&lt;br /&gt;
&lt;br /&gt;
CMake is an extensible, open-source system that has many powerful features.&lt;br /&gt;
Those features include:&lt;br /&gt;
&lt;br /&gt;
* Supports complex, large build environments. CMake has been proven in several large projects (KDE, ParaView, SecondLife, Scribus)&lt;br /&gt;
* Generates native build files (e.g., makefiles on Unix; workspaces/projects on MS Visual C++). Therefore, standard tools can be used on any platform/compiler configuration.&lt;br /&gt;
* Powerful system introspection abilities including the ability to find installed include files, libraries and executables. Also the ability to test the compiler for supported features.&lt;br /&gt;
* Integrated testing system called CTest.&lt;br /&gt;
* Integrated packaging system called CPack.&lt;br /&gt;
* Easy integration with CDash and Dart dashboard servers.&lt;br /&gt;
* Powerful scripting language with simple syntax.&lt;br /&gt;
* Supports in-place and out-of-place builds. Multiple compilation trees are possible from a single source tree.&lt;br /&gt;
* Can be easily extended to add new features.&lt;br /&gt;
* CMake is open source, under a liberal BSD license.&lt;br /&gt;
* CMake operates with a cache designed to be interfaced with a graphical editor. The cache provides optional interaction to conditionally control the build process.&lt;br /&gt;
* Ability to create Mac OSX Frameworks and Application Bundles.&lt;br /&gt;
* Supports adding complex custom rules to the build.&lt;br /&gt;
&lt;br /&gt;
== How you can help ==&lt;br /&gt;
&lt;br /&gt;
We have completed the building of the CMakeLists.txt for almost everything needed.&lt;br /&gt;
We are now working on get the build to compile properly. See below Testing/Using to help.&lt;br /&gt;
&lt;br /&gt;
There is a separate [[CMake Tasks]] page with things that are left to do w.r.t. cmake building of Inkscape.&lt;br /&gt;
&lt;br /&gt;
== SIMPLE CmakeLists.txt ==&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== SIMPLE with single sub-directory Cmakelists.txt ==&lt;br /&gt;
&lt;br /&gt;
    SET(libavoid_SRC&lt;br /&gt;
    connector.cpp&lt;br /&gt;
    geometry.cpp&lt;br /&gt;
    graph.cpp&lt;br /&gt;
    makepath.cpp&lt;br /&gt;
    polyutil.cpp&lt;br /&gt;
    region.cpp&lt;br /&gt;
    router.cpp&lt;br /&gt;
    shape.cpp&lt;br /&gt;
    static.cpp&lt;br /&gt;
    timer.cpp&lt;br /&gt;
    vertices.cpp&lt;br /&gt;
    visibility.cpp&lt;br /&gt;
    #Add our subdirectory sourcelist Var&lt;br /&gt;
    ${libavoid_parameter_SRC}&lt;br /&gt;
    )&lt;br /&gt;
    # this adds a single sub-directory&lt;br /&gt;
    ADD_SUBDIRECTORY(parameter)&lt;br /&gt;
&lt;br /&gt;
== Testing/Using ==&lt;br /&gt;
&lt;br /&gt;
Experience with Scribus '''strongly''' suggests using an &amp;quot;out of source&amp;quot;build arrangement. E.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir buildinkscape&lt;br /&gt;
cd buildinkscape&lt;br /&gt;
cmake ./path/to/inkscape/sources&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
References: &lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install4 Installing Scribus with Cmake] &amp;lt;br /&amp;gt;&lt;br /&gt;
[http://docs.scribus.net/index.php?lang=en&amp;amp;page=install5 Installing with CMake on OSX]&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99101</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99101"/>
		<updated>2016-04-15T09:15:54Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Print full command line used when building */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Print full command line used when building ==&lt;br /&gt;
&lt;br /&gt;
When you produce Makefiles using cmake, and make fails, you can get verbose output e.g. the full gcc command line used for compilation, by adding VERBOSE=1 to make:&lt;br /&gt;
&lt;br /&gt;
    $ make VERBOSE=1&lt;br /&gt;
&lt;br /&gt;
== Clean up cmake cache ==&lt;br /&gt;
If you end up in a dead-end with things not building anymore, you can clean the cmake cached files by issuing&lt;br /&gt;
&lt;br /&gt;
    $ make clean-cmake-files&lt;br /&gt;
&lt;br /&gt;
.. followed by regenerating the Makefiles:&lt;br /&gt;
&lt;br /&gt;
    $ cmake ../inkscape&lt;br /&gt;
&lt;br /&gt;
Note that this will require a full-rebuild of the whole of Inkscape&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99096</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99096"/>
		<updated>2016-04-15T08:16:16Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Clean up cmake cache */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Print full command line used when building ==&lt;br /&gt;
&lt;br /&gt;
When you produce Makefiles using cmake, you can you the following to print the full compiler command lines used to build project:&lt;br /&gt;
&lt;br /&gt;
    $ make VERBOSE=1&lt;br /&gt;
&lt;br /&gt;
== Clean up cmake cache ==&lt;br /&gt;
If you end up in a dead-end with things not building anymore, you can clean the cmake cached files by issuing&lt;br /&gt;
&lt;br /&gt;
    $ make clean-cmake-files&lt;br /&gt;
&lt;br /&gt;
.. followed by regenerating the Makefiles:&lt;br /&gt;
&lt;br /&gt;
    $ cmake ../inkscape&lt;br /&gt;
&lt;br /&gt;
Note that this will require a full-rebuild of the whole of Inkscape&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99091</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99091"/>
		<updated>2016-04-15T08:15:17Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Your First CMake Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Print full command line used when building ==&lt;br /&gt;
&lt;br /&gt;
When you produce Makefiles using cmake, you can you the following to print the full compiler command lines used to build project:&lt;br /&gt;
&lt;br /&gt;
    $ make VERBOSE=1&lt;br /&gt;
&lt;br /&gt;
== Clean up cmake cache ==&lt;br /&gt;
If you end up in a dead-end with things not building anymore, you can clean the cmake cached files by issuing&lt;br /&gt;
&lt;br /&gt;
    $ make clean-cmake-files&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99086</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99086"/>
		<updated>2016-04-14T18:03:01Z</updated>

		<summary type="html">&lt;p&gt;Objarni: /* Your First CMake Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Print full command line used when building&lt;br /&gt;
==========================================&lt;br /&gt;
&lt;br /&gt;
When you produce Makefiles using cmake, you can you the following to print the full compiler command lines used to build project:&lt;br /&gt;
&lt;br /&gt;
    $ make VERBOSE=1&lt;br /&gt;
&lt;br /&gt;
== Clean up cmake cache ==&lt;br /&gt;
If you end up in a dead-end with things not building anymore, you can clean the cmake cached files by issuing&lt;br /&gt;
&lt;br /&gt;
    $ make clean-cmake-files&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99081</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99081"/>
		<updated>2016-04-13T13:11:05Z</updated>

		<summary type="html">&lt;p&gt;Objarni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
== Clean up cmake cache ==&lt;br /&gt;
If you end up in a dead-end with things not building anymore, you can clean the cmake cached files by issuing&lt;br /&gt;
&lt;br /&gt;
    $ make clean-cmake-files&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99076</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99076"/>
		<updated>2016-04-13T12:41:08Z</updated>

		<summary type="html">&lt;p&gt;Objarni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file and exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake without not mess up the source folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    $ cd ..&lt;br /&gt;
    $ mkdir cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the path to the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cd cmake-tutorial-build&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99066</id>
		<title>Working with CMake</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Working_with_CMake&amp;diff=99066"/>
		<updated>2016-04-13T11:39:50Z</updated>

		<summary type="html">&lt;p&gt;Objarni: cmake encourages separation of source and build directories, the example now adheres to that convention&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a developer-oriented introduction to CMake and how to modify the CMake build scripts.&lt;br /&gt;
&lt;br /&gt;
We assume you already know the basics of how to use cmake to configure and build Inkscape (if not, see Inkscape's README).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions and Variables ==&lt;br /&gt;
&lt;br /&gt;
cmake has its own language and syntax, but it's pretty simple.  Essentially, everything is a function call.&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Even just setting variables is a function call:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Function calls have parenthesis but arguments aren't separated with commas, just whitespace.  It's fine to add newlines between arguments inside the parens.  CMake isn't strict about casing for function names, so SET() and set() are equivalent, but it is strict about variable name casing.  We'll adopt the convention of keeping function names lower case, and variable names upper case.&lt;br /&gt;
&lt;br /&gt;
Strings don't always have to be quoted, although it's also a good convention to follow.  So, these are all functionally equivalent in this case:&lt;br /&gt;
&lt;br /&gt;
    SET(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    set(MYVAR&lt;br /&gt;
        foobar)&lt;br /&gt;
    SET(MYVAR foobar)&lt;br /&gt;
&lt;br /&gt;
Variables are referenced using a dollar sign and curly brackets:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Your First CMake Script ==&lt;br /&gt;
&lt;br /&gt;
You now know enough to create a trivial cmake program.&lt;br /&gt;
&lt;br /&gt;
Create an empty directory and open a file named 'CMakeLists.txt' in your favorite text editor.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir cmake-tutorial&lt;br /&gt;
    $ cd cmake-tutorial&lt;br /&gt;
    $ gedit CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
Type the following lines into this CMakeLists.txt file:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    message(&amp;quot;${MYVAR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Save the text file, exit your editor. The folder cmake-tutorial is your source folder from cmakes perspective&lt;br /&gt;
and you need a build directory to run cmake and not mess up this folder with build artefacts:&lt;br /&gt;
&lt;br /&gt;
    cd ..&lt;br /&gt;
    mkdir cmake-tutorial-build&lt;br /&gt;
    cd cmake-tutorial-build&lt;br /&gt;
&lt;br /&gt;
Now run cmake in the build directory, specifying the source directory:&lt;br /&gt;
&lt;br /&gt;
    $ cmake ../cmake-tutorial&lt;br /&gt;
    foobar&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /tmp/cmake-tutorial&lt;br /&gt;
&lt;br /&gt;
CMake will automatically recognize &amp;quot;CMakeLists.txt&amp;quot; as its config file.  CMake assumes that the current directory is where we want all our stuff built to.  The '.' argument to the cmake command tells CMake to look in the current directory for source files.&lt;br /&gt;
&lt;br /&gt;
== Pre-defined Variables ==&lt;br /&gt;
&lt;br /&gt;
As you can imagine, CMake provides a broad set of pre-defined variables that relate to build systems.&lt;br /&gt;
&lt;br /&gt;
It has a bunch to help determine what platform the build is building for:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;UNIX:  ${UNIX}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;APPLE: ${APPLE}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;WIN32: ${WIN32}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;MSVC:  ${MSVC}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints for me:&lt;br /&gt;
&lt;br /&gt;
    UNIX:  1&lt;br /&gt;
    APPLE: &lt;br /&gt;
    WIN32: &lt;br /&gt;
    MSVC:  &lt;br /&gt;
&lt;br /&gt;
CMake also has a slew of variables to keep track of directories that things should go to:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_SOURCE_DIR&lt;br /&gt;
    CMAKE_SOURCE_DIR&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR&lt;br /&gt;
    PROJECT_BINARY_DIR&lt;br /&gt;
    CMAKE_BINARY_DIR&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR&lt;br /&gt;
    CMAKE_INSTALL_PREFIX&lt;br /&gt;
&lt;br /&gt;
Let's take a closer look at these:&lt;br /&gt;
&lt;br /&gt;
    message(&amp;quot;PROJECT_NAME              ${PROJECT_NAME}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_SOURCE_DIR        ${PROJECT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_SOURCE_DIR          ${CMAKE_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;PROJECT_BINARY_DIR        ${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_BINARY_DIR          ${CMAKE_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_CURRENT_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
    message(&amp;quot;CMAKE_INSTALL_PREFIX      ${CMAKE_INSTALL_PREFIX}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
For me this prints out:&lt;br /&gt;
&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /usr/local&lt;br /&gt;
&lt;br /&gt;
The 'source' vs. 'binary' variables are the same if the user is doing an in-tree build but differ if out-of-tree.  Generally, if you do out-of-tree builds yourself, you can be reasonably confident your code will work either way.&lt;br /&gt;
&lt;br /&gt;
The 'current' variables come into play when you have a directory hierarchy with CMakeList.txt files at various levels.  Variables like CMAKE_CURRENT_SOURCE_DIR refer to the currently processing child location in the tree, whereas CMAKE_SOURCE_DIR will always reference the root of the source tree.&lt;br /&gt;
&lt;br /&gt;
Also, be aware that the user is able to set their own installation prefix, so be careful about assumptions about where things will be installed.&lt;br /&gt;
&lt;br /&gt;
Let's try building our example in a more complex way to see how these variables change:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build install&lt;br /&gt;
    $ cd build &amp;amp;&amp;amp; cmake .. -DCMAKE_INSTALL_PREFIX=../install&lt;br /&gt;
    ...&lt;br /&gt;
    PROJECT_NAME              Project&lt;br /&gt;
    PROJECT_SOURCE_DIR        /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_SOURCE_DIR          /tmp/cmake-tutorial&lt;br /&gt;
    CMAKE_CURRENT_SOURCE_DIR  /tmp/cmake-tutorial&lt;br /&gt;
    PROJECT_BINARY_DIR        /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_BINARY_DIR          /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_CURRENT_BINARY_DIR  /tmp/cmake-tutorial/build&lt;br /&gt;
    CMAKE_INSTALL_PREFIX      /tmp/cmake-tutorial/install&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conditionals ==&lt;br /&gt;
&lt;br /&gt;
'If' statements are pretty fundamental in all languages, but particularly so for configuring software.  Here's how to do an if statement in CMake:&lt;br /&gt;
&lt;br /&gt;
    set(MYVAR &amp;quot;foobar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if(MYVAR STREQUAL &amp;quot;foobar&amp;quot;)&lt;br /&gt;
        set(FOOBAR &amp;quot;yes&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
    if(FOOBAR)&lt;br /&gt;
        message(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
    elseif(NOT DEFINED FOOBAR)&lt;br /&gt;
        message(&amp;quot;Your FOOBAR is fubar.&amp;quot;)&lt;br /&gt;
    else()&lt;br /&gt;
        message(&amp;quot;Goodbye, cruel world...&amp;quot;)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
Couple things to note - there's none of the usual ==, &amp;lt;, etc. boolean operators.  Instead use EQUAL and LESS for numerical comparisons, STREQUAL, and STRLESS for strings.  Other frequently used tests include EXISTS, DEFINED, AND, OR, and NOT.  MATCHES provides a handy way to do regular expression testing on strings.  VERSION_EQUAL, VERSION_LESS, and VERSION_GREATER are helpful for testing release version strings.  There's a bunch of tests relating to checking status on files.  Also notice in the second if statement, that FOOBAR's value of &amp;quot;yes&amp;quot; is automatically recognized as a true value.  &amp;quot;no&amp;quot; is a false value.&lt;br /&gt;
&lt;br /&gt;
For a complete list of available unary and binary tests and what CMake recognizes as true and false values, see https://cmake.org/cmake/help/v3.0/command/if.html.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Basic text manipulation in CMake can be done via the string() routine.  The first argument to the string() function is the operation to be performed - CONCAT, SUBSTRING, LENGTH, REGEX, COMPARE, MD5, etc.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(A &amp;quot;foobar&amp;quot;)&lt;br /&gt;
    string(SUBSTRING &amp;quot;${A}&amp;quot; 3 3 B)&lt;br /&gt;
    string(TOUPPER &amp;quot;${B}&amp;quot; C)&lt;br /&gt;
    message(&amp;quot;${C}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints&lt;br /&gt;
&lt;br /&gt;
    BAR&lt;br /&gt;
&lt;br /&gt;
Did you notice in this last example how we had a cmake_minimum_required() call?&lt;br /&gt;
&lt;br /&gt;
CMake has grown in functionality since it was originally first introduced, and the cmake_minimum_required() let's us specify what level of compatibility our script expects.  After all, the version of cmake installed on different users' systems is going to vary considerably so this is a very basic thing to check.&lt;br /&gt;
&lt;br /&gt;
I don't know if there is a website somewhere that indicates what cmake functionality is available in which cmake versions.  However, cmake seems to be good about warning us when we use something that requires a specific version of cmake, and warns us in this example if we don't specify what we require.  Obviously we don't want to set the version *too* recent or else users will be unable to run cmake to build Inkscape!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
CMake strives to make handling lists of strings straightforward and easy.  Basically, it handles lists as semi-colon delimited strings, and automatically handles converting back and forth:&lt;br /&gt;
&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    message(&amp;quot;${FOOLIST}&amp;quot;)&lt;br /&gt;
    message(${FOOLIST})&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a;b;c;d;e&lt;br /&gt;
    abcde&lt;br /&gt;
&lt;br /&gt;
The [https://cmake.org/cmake/help/v3.0/command/string.html list() function] provides operations such as APPEND, REVERSE, SORT, REMOVE_AT, REMOVE_ITEM, REMOVE_DUPLICATES, GET, etc. similar to string.&lt;br /&gt;
&lt;br /&gt;
Iterating through the items can be done with a for loop:&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 2.8)&lt;br /&gt;
    set(FOOLIST a b c d e)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 1)&lt;br /&gt;
    list(REMOVE_AT FOOLIST 2)&lt;br /&gt;
    foreach(v ${FOOLIST})&lt;br /&gt;
        message(${v})&lt;br /&gt;
        list(APPEND LETTERS ${v})&lt;br /&gt;
    endforeach()&lt;br /&gt;
    message(${LETTERS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prints out&lt;br /&gt;
&lt;br /&gt;
    a&lt;br /&gt;
    c&lt;br /&gt;
    e&lt;br /&gt;
    ace&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Configuring a software project often involves fiddling with files.  Configuration files may need settings changed in them.  Generated code files need generated.  Other files may need stuff substituted in them or read out of them.  CMake has a wealth of functionality to help here.&lt;br /&gt;
&lt;br /&gt;
The most basic would be reading the contents of a file into a variable consisting of a list of strings:&lt;br /&gt;
&lt;br /&gt;
    file(STRINGS /usr/share/inkscape/palettes/inkscape.gpl INKSCAPE_PALETTE)&lt;br /&gt;
    list(GET INKSCAPE_PALETTE 0 1 PALETTE_NAME)&lt;br /&gt;
    message(&amp;quot;${PALETTE_NAME}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Prints out:&lt;br /&gt;
&lt;br /&gt;
    GIMP Palette;Name: Inkscape default&lt;br /&gt;
&lt;br /&gt;
Like list() and string(), the first argument to file() is the operation to perform.  Other operations are WRITE, GLOB, REMOVE, TO_CMAKE_PATH, TIMESTAMP, COPY, and a bunch more.  This routine is pretty powerful, as you can see from [https://cmake.org/cmake/help/v3.0/command/file.html the file() documentation].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Building and Installing ==&lt;br /&gt;
&lt;br /&gt;
Now that we've done a quick look at CMake's basic syntax, you should be comfortable with tinkering with Inkscape's CMakeLists.txt and other CMake config files.  Now on to the nitty gritty of how to actually build code files into executables and get them installed on the system.&lt;br /&gt;
&lt;br /&gt;
There are plenty of detailed tutorials out there for how to do this from scratch, which I'll suggest perusing if you're creating a cmake project from scratch.  But if you're working on Inkscape's build system you really just need to know the key bits and pieces to look for.&lt;br /&gt;
&lt;br /&gt;
First, you'll need a list of source code files.  CMake's '''file()''' function has a GLOB operation that enables it to automatically find source files, but this is generally considered bad practice, so we'll typically list the source code files explicitly somewhere.&lt;br /&gt;
&lt;br /&gt;
    set(inkscape_SRC&lt;br /&gt;
        attributes.h&lt;br /&gt;
        attributes.cpp&lt;br /&gt;
        ...&lt;br /&gt;
        version.cpp&lt;br /&gt;
        version.h&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
These source files could be directly associated with an executable, but in Inkscape we compile most of the source code into an object library, using the '''add_library()''' function:&lt;br /&gt;
&lt;br /&gt;
    add_library(inkscape_base OBJECT ${inkscape_SRC})&lt;br /&gt;
&lt;br /&gt;
This way we can create both the inkscape and inkview executables using the same core codebase, with CMake's '''add_executable()''':&lt;br /&gt;
&lt;br /&gt;
    add_executable(inkscape main.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
    add_executable(inkview inkview.cpp $&amp;lt;TARGET_OBJECTS:inkscape_base&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We also need to link external libraries into the mix, using '''target_link_libraries()''':&lt;br /&gt;
&lt;br /&gt;
    set(INKSCAPE_TARGET_LIBS inkscape nrtype_LIB croco_LIB avoid_LIB 2geom_LIB ...)&lt;br /&gt;
&lt;br /&gt;
    target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
    target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})&lt;br /&gt;
&lt;br /&gt;
Finally, we install the two executables via something like:&lt;br /&gt;
&lt;br /&gt;
    install(&lt;br /&gt;
        PROGRAMS      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
                      ${EXECUTABLE_OUTPUT_PATH}/inkscape&lt;br /&gt;
        DESTINATION   ${CMAKE_INSTALL_PREFIX}/bin&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
== Inkscape's Build File Structure ==&lt;br /&gt;
&lt;br /&gt;
To keep things manageable we split code out of CMakeLists.txt into more specialized files, whose logic all feeds back up to the top CMakeLists.txt.  There are a few different ways this is done:&lt;br /&gt;
&lt;br /&gt;
Our codebase is split into subdirectories containing various libraries and other collections of C++ files.  We use CMake's '''add_subdirectory()''' to register each of these subdirs.  CMake then recursively navigates into them, looks for a sub-CMakeLists.txt and then processes it.  &lt;br /&gt;
&lt;br /&gt;
The '''include()''' function is used to insert other CMake files as snippets into the current file.  This can be handy for building up a collection of custom functions and macros.  In Inkscape we typically place these into the CMakeScripts/ subdirectory and name the files with the *.cmake extension.&lt;br /&gt;
&lt;br /&gt;
'''find_package()''' is critical for detecting and handling external dependencies, and deserves special mention.  The first argument to this routine is the name of a dependency, which should correspond to a File&amp;lt;Dependency&amp;gt;.cmake file in the CMakeScripts/Modules/ directory.&lt;br /&gt;
&lt;br /&gt;
So, to add a new dependency library Foo to Inkscape, you first must find or write a FindFoo.cmake file and put it at CMakeScripts/Modules/FindFoo.cmake.  Then you use it like this:&lt;br /&gt;
&lt;br /&gt;
    find_package(Foobar)&lt;br /&gt;
    if(FOOBAR_FOUND)&lt;br /&gt;
        set(WITH_FOOBAR ON)&lt;br /&gt;
        list(APPEND INKSCAPE_INCS_SYS ${FOOBAR_INCLUDE_DIRS})&lt;br /&gt;
        list(APPEND INKSCAPE_LIBS ${FOOBAR_LIBRARIES})&lt;br /&gt;
        add_definitions(${FOOBAR_DEFINITIONS})&lt;br /&gt;
    else()&lt;br /&gt;
        set(WITH_FOOBAR OFF)&lt;br /&gt;
    endif()&lt;br /&gt;
&lt;br /&gt;
The exact logic will vary from dependency to dependency; review the Find&amp;lt;Dependency&amp;gt;.cmake file to see what variables it exports.  For dependencies that are required, you use a REQUIRED parameter and can skip the check if its found (since cmake will bail if it isn't).&lt;br /&gt;
&lt;br /&gt;
    find_package(Baz REQUIRED)&lt;br /&gt;
    list(APPEND INKSCAPE_INCS_SYS ${BAZ_INCLUDE_DIRS})&lt;br /&gt;
    list(APPEND INKSCAPE_LIBS ${BAZ_LIBRARIES})&lt;br /&gt;
    add_definitions(${BAZ_DEFINITIONS})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other Notable CMake Functions ==&lt;br /&gt;
&lt;br /&gt;
Let's take a quick overview of a few of the other common function calls that you'll run across in Inkscape's CMake files.&lt;br /&gt;
&lt;br /&gt;
'''configure_file()''' is a convenient way to process template files and substitute parameters in them with the values of variables within the cmake script.  A common use would be to substitute the current release version number into C files or documentation, or to fill in configuration values into a config.h.in template.  &lt;br /&gt;
&lt;br /&gt;
'''option()''' lets you establish cmake options the user can use to control the build.  This is typically used to allow the user to control whether to compile in various sub-modules or to specify alternate libraries.&lt;br /&gt;
&lt;br /&gt;
'''add_custom_target()''' is used to create additional make targets, like 'make dist', 'make uninstall', 'make check', and so on.  You can provide it with a separate CMake file to be executed, or simply list a sequence of COMMANDS for it to invoke.&lt;br /&gt;
&lt;br /&gt;
add_definitions&lt;/div&gt;</summary>
		<author><name>Objarni</name></author>
	</entry>
</feed>