https://public.kitware.com/Wiki/api.php?action=feedcontributions&user=Shdwjk&feedformat=atomKitwarePublic - User contributions [en]2024-03-28T16:57:16ZUser contributionsMediaWiki 1.38.6https://public.kitware.com/Wiki/index.php?title=CMake/Projects&diff=24871CMake/Projects2010-07-10T17:57:53Z<p>Shdwjk: /* Libraries */ Added PoDoFo PDF Library to the list of libraries using CMake</p>
<hr />
<div>= Desktop suites and development platforms =<br />
<br />
* [http://www.kde.org KDE4 ] - the next version of the powerful Open Source desktop, application suite and development platform will be built using CMake, which together with Qt4 will make it possible to run KDE4 not only on Linux/UNIX, but also Mac OS X and Windows.<br />
<br />
* [http://www.compiz.org Compiz] - An OpenGL compositing window manager, using CMake to easier facilitate a unified build system for its plugin based architecture and autogenerated options code.<br />
<br />
=Libraries=<br />
<br />
* [http://www.arl.hpc.mil/ice/ eXtensible Data Model and Format (XDMF)]<br />
<br />
* [http://www.mysql.com/ MySql ] - The world's most popular open source database<br />
<br />
* [http://gdcm.sf.net Grassroots DiCoM (GDCM)]<br />
<br />
* [http://vxl.sourceforge.net/ Vision-something-Libraries (VXL)]<br />
<br />
* [http://www.cs.utah.edu/~whitaker/vispack Vispack - C++ library developed for processing volumes images and surfaces ]<br />
<br />
* [http://teem.sourceforge.net Teem - libraries for representing, processing, and visualizing scientific raster data]<br />
<br />
* [http://www.mip.informatik.uni-kiel.de/~wwwadmin/Software/Doc/BIAS/html/intro.html BIAS - The Basic Image AlgorithmS C++ Library ]<br />
<br />
* [http://www.cvgpr.uni-mannheim.de/gosch/software/golib/doc/html GoLib - general c++ library]<br />
<br />
* [http://cmk.navorski.com/index.php?wiki=CmkSql cmkSQL - an abstract SQL Library]<br />
<br />
* [http://www.mcc.uiuc.edu/qmc/AtomicHF/ AtomicHF - Package to solve Hartree-Fock equations for a spherical system using Numerov algorithm] <br />
<br />
* [http://www.xvt.com/ XVT - A software development environment for easily building cross-platform GUI applications in C or C++.] <br />
<br />
* [http://www.vinoisnotouzo.com/hl2sdk-cmake/ The Half-Life 2 SDK in CMake]<br />
<br />
* [http://aften.sourceforge.net/ The aften Open Source A/52 encoder]<br />
<br />
* [http://icculus.org/physfs/ PhysicsFS file i/o library]<br />
<br />
* [http://www.zorba-xquery.org The Zorba XQuery Processor]<br />
<br />
* [http://digest.sourceforge.net The Digest Software Project] implements C and C++ libraries, and a PAM module, for digest authentication as specified by RFC 2069<br />
<br />
* [http://libsudo.sourceforge.net libsudo] allows a C/C++ application to execute a process as a different user (think of it as "system(process, user)")<br />
<br />
* [http://www.rapidterrain.com Live Terrain Format] <br/> High-performance synthetic natural environment engine and database format for conducting attenuated line of sight queries correlated to the real world.<br />
<br />
* [http://www.openbabel.org OpenBabel] Alternate build system in 2.2 releases, planned to be main build system in 3.x. Chemical toolbox designed to speak the many languages of chemical data.<br />
<br />
* [http://fc-solve.berlios.de/ Freecell Solver] - an ANSI C library (and some standalone command-line programs) for automatically solving boards of various variants of [[wikipedia:Solitaire|Card Solitaire]].<br />
<br />
* [http://wiki.openimageio.org/wiki/Main_Page OpenImageIO] is a library for reading and writing images, and a bunch of related classes, utilities, and applications.<br />
<br />
* [http://www.boost.org Boost C++ Libraries] Boost provides free peer-reviewed portable C++ source libraries, that are intended to be widely useful, and usable across a broad spectrum of applications.<br />
<br />
* [http://eris.liralab.it/yarp/ YARP: Yet Another Robot Platform] is an open source middleware for robotic programming.<br />
<br />
* [http://podofo.sourceforge.net/index.html PoDoFo:] A free, portable and easy to use PDF parsing and creation library.<br />
<br />
=Toolkits=<br />
<br />
* [http://www.vtk.org Visualization Toolkit VTK]<br />
<br />
* [http://www.itk.org Insight Segmentation and Registration Toolkit ITK]<br />
<br />
* [http://dicom.offis.de/dcmtk.php.en DICOM ToolKit (DCMTK)]<br />
<br />
* [http://www3.ict.csiro.au/ict/content/display/0,,a16254_b16408_d72676,00.html Medical Imaging ToolKit]<br />
<br />
* [http://www.mitk.org MITK - The Medical Imaging Interaction Toolkit]<br />
<br />
* [http://www.naughter.com/aa.html AA+ - A class framework for Computational Astronomy]<br />
<br />
* [http://fltk.org Fltk - cross-platform C++ GUI toolkit for UNIX®/Linux® (X11), Microsoft® Windows®, and MacOS® X]<br />
<br />
* [http://fl-inventor.sourceforge.net FlInventor - 3D toolkit]<br />
<br />
* [http://orca-robotics.sourceforge.net/getting.html ORCA - open-source framework for developing component-based robotic systems]<br />
<br />
* [http://www.kwwidgets.org KWWidgets - A free, cross-platform and open-license scientific-visualization GUI Toolkit.]<br />
<br />
* [http://www.igstk.org IGSTK - Image Guided Surgery Toolkit]<br />
<br />
* [http://coolfluidsrv.vki.ac.be/coolfluid COOLFluiD - CFD Environment]<br />
<br />
* [http://webtoolkit.eu/ Webtoolkit (AKA Wt)] is C++ library and application server for web applications which mimics the Qt API (it's like Qt but it spits HTML + CSS + JavaScript)<br />
<br />
* [http://www.ellogon.org/ Ellogon - A natural language engineering platform]<br />
<br />
* [https://savannah.nongnu.org/projects/certi CERTI] an Open Source HLA RTI.<br />
<br />
* [https://savannah.nongnu.org/projects/tsp TSP] the Transport Sample Protocol<br />
<br />
=Tools=<br />
<br />
* [http://www.gccxml.org GCC-XML - Dumps C++ Interface to XML]<br />
<br />
* [http://ctieware.eng.monash.edu.au/twiki/bin/view/Simulation/IPv6Suite IPv6Suite - open source OMNeT++ model suite for accurate simulation of IPv6 protocols and networks ]<br />
<br />
* [http://www.robots.ox.ac.uk/~pnewman/TheMOOS MOOS - Mission Orientated Operating Suite]<br />
<br />
* [http://www.csync.org/ csync - a client only bidirectional file synchronizer]<br />
<br />
* [http://www.csync.org/ pam_csync - a pam module for roaming home directories]<br />
<br />
* [http://cdrkit.org/ cdrkit - portable command-line CD/DVD recorder software]<br />
<br />
=Languages=<br />
<br />
<br />
* [http://gpp.niacland.net/telecharger.html.en Goto++ - a goto language]<br />
<br />
* [http://www.compuphase.com/pawn/pawn.htm Pawn - An embedded scripting language formerly called Small]<br />
<br />
=Applications=<br />
* [http://www.aqsis.org Aqsis - a high-quality 3D render engine that implements the RenderMan interface]<br />
<br />
* [http://www.aspeed.com ASPEED Software]<br>ASPEED's products include the ACCELLERANT SDK for parallelizing applications for grids or clusters. ASPEED provides APIs for easily improving application performance, with bindings in FORTRAN, C, C++, Java and C#. ACCELLERANT also provides an Application Manager for quickly parallelizing batch jobs from the command line; and Workload Balancer for simple resource management. ACCELLERANT supports Windows and Linux, as well as numerous "grid vendor" products.<br />
::''"ASPEED's SDK supports a wide range of platforms and languages, and CMake fit the bill perfectly for our build and release cycle. It works for Visual Studio IDE development, and it works from the command line under either Windows (nmake) or Linux. It works for FORTRAN as well as C++. It's an enormous time-saver, allowing us to quickly develop applications for multiple platforms. This in turn has allowed us to build, test and release software more frequently, giving us a market advantage."''<br>-Mike Dalessio, Head of Development, ASPEED Software<br />
<br />
* [http://avidemux.berlios.de/index.html Avidemux - a free video editor designed for simple cutting, filtering and encoding tasks.]<br />
<br />
* [http://www.blender.org/ Blender - Blender is the free open source 3D content creation suite, available for all major operating systems under the GNU General Public License.]<br />
<br />
* [http://boson.eu.org/ Boson - an OpenGL real-time strategy game for UNIX/Linux]<br />
<br />
* [http://www.i-medlab.com CadColon] is a Computer Aided Detection (CAD) system designed to support radiologist's diagnosis of suspect polyps in the colon and rectum, using high and low dose CT.<br />
<br />
''"I started to develop on a project on Linux OS in C++ language on 3 January 2005, and I had never written from scratch any configure.in files, nor used autoconf tools seriously before. So since one of my task was to create the building process for the whole project, I had 2 choices: learn and use autoconf, or search in Internet for an alternative. The one day research ended up in CMake.org, which is an easy but very powerful tool, which allowed me to achieve all I wanted to do (debug/release/profile compilations, compilation based on the developer name, easily maintainable and customizable compilation of many shared/static libraries and applications), and which has a very fast learning curve, exactly what a projet need to achieve its aim in short time."''<br />
<br />
- Luca Cappa<br />
<br />
* [https://launchpad.net/cuneiform-linux Cuneiform for Linux - Cuneiform is an multi-language OCR system originally developed and open sourced by Cognitive Technologies.]<br />
<br />
* [http://cycabtk.gforge.inria.fr/wiki/doku.php CycabTK - An opensource mobile robot simulator ]<br />
<br />
* [http://ncmi.bcm.tmc.edu/homes/stevel/EMAN/doc/download.html EMAN - Software for Single Particle Analysis and Electron Micrograph Analysis ] <br />
<br />
* [http://www.over-look.org Fing - A cross-platform command line tool for Network and Service discovery ] <br />
<br />
* [http://hugin.sf.net hugin, well known panorama stitching gui and more]<br />
<br />
* [http://www.evl.uic.edu/cavern/agave/immersaview/index.html ImmersaView]<br />
<br />
* [http://www.inkscape.org Inkscape - an Open Source vector graphics editor, with capabilities similar to Illustrator, CorelDraw, or Xara X, using the W3C standard Scalable Vector Graphics (SVG) file format]<br />
<br />
* [http://www.5star-shareware.com/Windows/WebDev/HTML/inscite.html InSciTE program editor]<br />
<br />
* [http://www.k-3d.org K-3D - free-as-in-freedom 3D graphics for professional artists]<br />
<br />
* [http://kvirc.net KVIrc - The K-Visual IRC Client]<br />
<br />
* [http://www.lyx.org LyX - a document processor]<br />
<br />
* [http://www.mendeley.com Mendeley Desktop - a Qt4 document-management and collaboration tool for academic researchers.]<br />
<br />
* [http://icculus.org/mojosetup/ MojoSetup - a cross-platform software installer]<br />
<br />
* [http://opencog.org/ OpenCog - An artificial intelligence framework]<br />
<br />
* [http://www.openwengo.org/ OpenWengo - an open source VoIP telephony application]<br />
<br />
* [http://www.paraview.org ParaView Parallel Visualization Application]<br />
<br />
* [http://westhoffswelt.de/projects/pdf_presenter_console.html Pdf Presenter Console] The Pdf Presenter Console (PPC) is a GTK based presentation viewer application which uses Keynote like multi-monitor output to provide meta information to the speaker during the presentation. It is able to show a normal presentation window on one screen, while showing a more sophisticated overview on the other one providing information like a picture of the next slide, as well as the left over time till the end of the presentation. The input files processed by PPC are PDF documents, which can be created using nearly any of today's presentation software.<br />
<br />
* [http://cms.mcc.uiuc.edu/qmcpack QMCPACK Quantum Monte Carlo Package for HPC]<br />
<br />
* [http://qtm.blogistan.co.uk/ QTM] - A desktop blogging client based on Qt 4.<br />
<br />
* [http://www.rapidterrain.com RUGUD (Rapid Unified Generation of Urban Databases)] <br/> Plugin-based distributed terrain database production framework developed for the U.S. Department of Defense, aimed at scalable production of high-resolution visual and SAF terrain databases.<br />
<br />
* [http://www.rosegardenmusic.com/ Rosegarden - a MIDI and audio sequencer and musical notation editor]<br />
<br />
* [http://software.sci.utah.edu/ SCIRun]<br>A visual programming environment for modeling, simulation, and visualization, incorporating thirdparty packages such as Teem, Matlab, and the Insight Toolkit. SCIRun also includes Seg3D, a standalone executable for the segmentation of volumetric image data.<br />
<br />
* [http://www.scribus.net/ Scribus] - a powerful Open Source desktop publishing application, developed primarily developed for Linux, now also available for Mac OS X and Windows]<br />
<br />
* [http://secondlife.com/ Second Life] - Second Life® is a 3-D virtual world created by its Residents. Since opening to the public in 2003, it has grown explosively and today is inhabited by millions of Residents from around the globe. <br />
<br />
* [http://www.slicer.org Slicer - Medical Visualization and Processing Environment for Research]<br />
<br />
* [http://icculus.org/toby/ Toby - a LOGO-inspired TurtleGraphics environment]<br />
<br />
* [http://www.kitware.com/products/volview.html VolView Interactive System for Volume Visualization]<br />
<br />
* [http://www.wireshark.org Wireshark] Wireshark is the world's foremost network protocol analyzer, and is the de facto (and often de jure) standard across many industries and educational institutions.<br />
<br />
<br />
* [http://davis.wpi.edu/~xmdv Multivariate Data Visualization Tool - XmdvTool]<br />
<br />
* [http://www.xtrkcad.org XTrkCAD - a CAD program for designing model railroads]<br />
<br />
* [http://www.qutecom.org/ QuteCom - a multiplattform and multiprotocol VoIP softphone]<br />
<br />
* [http://www.gpsdrive.de GPSDrive - a GPS navigation system]<br />
<br />
* [http://avogadro.openmolecules.net Avogadro] - advanced molecular editor designed for cross-platform use in computational chemistry, molecular modeling, bioinformatics, materials science, and related areas. It offers flexible rendering and a powerful plugin architecture.<br />
<br />
* [http://sentinella.sourceforge.net/ Sentinella - A KDE app that asociates the system activity to actions]<br />
<br />
* [http://www.robotcub.org The RobotCub project] realized an open platform for research in embodied cognition. For our software we use cmake ([http://eris.liralab.it RobotCub online manual]).<br />
<br />
* [http://www.weechat.org/ WeeChat - Fast, light and extensible chat client]<br />
<br />
=Controls=<br />
<br />
<br />
* [http://wxart2d.sourceforge.net/ wxArt2d]<br />
<br />
=Other=<br />
<br />
* [http://plplot.sourceforge.net PLplot] is a mix of a core scientific plotting library written in C, multiple computer language interfaces to that library (some of them generated using [http://www.swig.org/ SWIG]), a set of 20+ test examples written for each computer language interface, multiple plotting device driver plug-ins that are dynamically loaded by our core library, and a complete docbook-based documentation build. This build complexity is handled with ease by CMake on Linux (with good ctest results for the examples written in each computer language that we interface). We are also beginning to get encouraging build results on the Mac OS X and windows platforms.<br />
<br />
* [http://www.opengc.org/index.html OpenGC - The Open Source Glass Cockpit Project]<br />
<br />
* [http://oscar.vision.ee.ethz.ch/gpuseg GPUSEG - Real-Time, GPU-Based Foreground-Background Segmentation]<br />
<br />
* [http://www.tecn.upf.es/openMOIV/ OpenMOIV - is an object-oriented, 3D multi-platform toolkit that helps you develop molecular visualization applications]<br />
<br />
* [http://devolab.cse.msu.edu/software/avida Avida - Digital Life Platform]<br />
<br />
* [http://storm.bmi.ohio-state.edu/documentation.php Storm]<br />
<br />
* [http://www.octave.org Octaviz - Viz for Octave]<br />
<br />
* [http://www.sci.utah.edu/research/annot3d.html Annot3D - 3D annotation system]<br />
<br />
* [http://caddlab.rad.unc.edu/software/MIND MIND - DICOM query/move tool]<br />
<br />
* [http://www.mcc.uiuc.edu/ohmms/ ohmms - object-oriented high-performance solutions for multi-scale materials simulations]<br />
<br />
* [http://www.atracsys.com/_opensource/HornRegistrationDoc/html/ HornRegistration]<br />
<br />
* [http://software.ericsink.com/20040129.html CMake User Review]<br />
<br />
* [http://www.yzis.org/ Yzis - a brand new editor inspired by vim] <br />
<br />
* [http://miktex.org/ MiKTeX - TeX implementation for the Windows operating system]<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake_FAQ&diff=23833CMake FAQ2010-05-17T13:42:42Z<p>Shdwjk: Undo revision 23197 by Russel08 (Talk)</p>
<hr />
<div>== General information and availability ==<br />
=== What is CMake? ===<br />
CMake is a cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform-independent and compiler-independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. CMake is quite sophisticated: it is possible to support complex environments requiring system configuration, preprocessor generation, code generation, and template instantiation. Please go to http://www.cmake.org/HTML/About.html to learn more about CMake.<br />
<br />
=== What is the current release? ===<br />
The latest release of CMake is always available at: http://www.cmake.org/HTML/Download.html<br />
<br />
From there, you can fetch CMake binaries for Windows or several Unix variants, or you can download the source code of CMake.<br />
<br />
You can also access nightly development through CVS; see http://www.cmake.org/HTML/Download.html for more information. You may also browse the [http://www.cmake.org/cgi-bin/viewcvs.cgi/?root=CMake cvs repository online].<br />
<br />
=== I found a Bug! What should I do? ===<br />
Please report the bug in our bug tracker: http://www.cmake.org/Bug<br />
<br />
Please make sure to look at the old bugs not to include duplicates, include detailed instructions of the bug and how to reproduce it.<br />
<br />
=== I want a new feature in CMake. What should I do? ===<br />
Report a feature request in our Bug tracker http://www.cmake.org/Bug<br />
<br />
Please make sure to look at the old feature requests not to include duplicates, include detailed instructions of the feature and proposed implementation.<br />
<br />
=== What is the most recent version covered by the Mastering CMake book? ===<br />
A new edition of the [http://www.kitware.com/products/cmakebook.html Mastering CMake] book has been released which documents CMake 2.6.<br />
<br />
The following features have been added since printing the book:<br />
<br />
* New INSTALL command (cmake --help-command INSTALL)<br />
* New LIST command (cmake --help-command LIST)<br />
* Updated FIND_PATH, FIND_PROGRAM, and FIND_FILE commands to be more powerful (cmake --help-command FIND_PATH)<br />
* RPATH and Mac OS X install_name support (cmake --help-command SET_TARGET_PROPERTIES)<br />
* CPack Beta (not finished or documented)<br />
* EXECUTE_PROCESS was added and replaces EXEC_PROGRAM<br />
* Other changes have been bug fixes and internal CMake restructuring<br />
<br />
=== Where can I find searchable CMake Mailing Archives? ===<br />
There exists at list those ones:<br />
* [http://dir.gmane.org/gmane.comp.programming.tools.cmake.user cmake on Gmane]<br />
* [http://www.mail-archive.com/cmake@cmake.org/ http://www.mail-archive.com/cmake@cmake.org/]<br />
* [http://marc.info/?l=cmake http://marc.info/?l=cmake]<br />
* Use google ''site'' keyword in order to search directly in the CMake browsable ML:<br />
site:http://www.cmake.org/pipermail/cmake/ <search terms><br />
<br />
== Running CMake ==<br />
<br />
=== Is there an option to produce more 'verbose' compiling? ===<br />
<br />
On Makefile generators, you can set the Makefile variable VERBOSE to 1. For example on UNIX:<br />
make VERBOSE=1<br />
<br />
You can also set CMAKE_VERBOSE_MAKEFILE to ON.<br />
<br />
On Windows (nmake) you can override CMAKE_VERBOSE_MAKEFILE by using<br />
nmake /S<br />
On Unix make you can mostly override verbose mode by using<br />
make VERBOSE=""<br />
<br />
If you are on Windows using Borland or NMake Makefiles, you will see lines like:<br />
<br />
cl @c:\DOCUME~1\ANDY~1.KIT\LOCALS~1\Temp\nma03504<br />
<br />
The reason for this is that Borland and Microsoft Visual Studio make programs have limitation on the length of command strings. They overcome this limitation by writing arguments to the file and then pass file to the program.<br />
<br />
If you actually want to see what the command looks like, set CMAKE_START_TEMP_FILE and CMAKE_END_TEMP_FILE to ""<br />
<br />
=== Is there a way to skip checking of dependent libraries when compiling? ===<br />
<br />
'''Using the Makefile Generator'''<br />
<br />
When using the Makefile generator under *nix you can append "/fast" to your target name. For example:<br />
<br />
make target_name/fast<br />
<br />
Under Windows use a backslash instead:<br />
<br />
make target_name\fast<br />
<br />
'''Using Visual Studio >= 7.1'''<br />
<br />
If you have Visual Studio .NET 7.1 or greater you can use the native option to right click on a project and choose to build just that project.<br />
<br />
'''Using Visual Studio <= 7.0'''<br />
<br />
CMake doesn't try to compile all dependent libraries when you compile a library but it will do so for binary targets. You can't avoid this however you can take advantage of CTRL+F7 to manually compile a source file for the affected target and then relink the target by right clicking on it and choosing Link. You'll have to ensure that all dependent libraries are made up-to-date however or suffer through Visual's slow check.<br />
<br />
=== I set a cmake variable in my environment, but it didn't change anything. Why? ===<br />
CMake build settings are stored in the CMake cache corresponding to a project's build tree. They are called CMake "cache entries" and have no relation to your command shell's environment variables. Use a CMake GUI (CMakeSetup on Windows or ccmake on UNIX) or the wizard mode (cmake -i) to edit cache entries. Initial values may also be specified for a build by using the -D command line argument to cmake when it is first run to produce a new build tree.<br />
<br />
=== How do I use a different compiler? ===<br />
<br />
==== Method 1: use environment variables ====<br />
<br />
For C and C++, set the <tt>CC</tt> and <tt>CXX</tt> environment<br />
variables. This method is not guaranteed to work for all generators.<br />
(Specifically, if you are trying to set Xcode's <tt>GCC_VERSION</tt>,<br />
this method confuses Xcode.)<br />
<br />
For example:<br />
<pre><br />
CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source<br />
</pre><br />
<br />
==== Method 2: use cmake -D ====<br />
<br />
Set the appropriate <tt>CMAKE_FOO_COMPILER</tt> variable(s) to a valid<br />
compiler name or full path on the command-line using <tt>cmake -D</tt>.<br />
<br />
For example:<br />
<pre><br />
cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source<br />
</pre><br />
<br />
==== Method 3 (avoid): use set() ====<br />
<br />
Set the appropriate <tt>CMAKE_FOO_COMPILER</tt> variable(s) to a valid<br />
compiler name or full path in a list file using <tt>set()</tt>. This<br />
must be done ''before'' any language is set (ie before any<br />
<tt>project()</tt> or <tt>enable_language()</tt> command).<br />
<br />
For example:<br />
<pre><br />
set(CMAKE_C_COMPILER "gcc-4.2")<br />
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")<br />
<br />
project("YourProjectName")<br />
</pre><br />
<br />
=== I change CMAKE_C_COMPILER in the GUI but it changes back on the next configure step. Why? ===<br />
<br />
Once a build tree is created with a given compiler it cannot be changed. There are a variety of implementation reasons for this policy.<br />
<br />
=== In CCMake, typing full paths is tedious. Is there a better way? ===<br />
Since CMake 1.6, you can use tab completion in the path entries in CCMake. All you do is type first couple of characters and press <TAB> key. CCMake will examine the current typed path and try to expand it to some existing path. If that is possible, it will do it. If not, it will not do anything.<br />
<br />
For example:<br />
<br />
/usr/loc<TAB><br />
<br />
will expand to<br />
<br />
/usr/local/<br />
<br />
<br />
<br />
== Out-of-source build trees ==<br />
<br />
=== What is an "out-of-source" build? ===<br />
When your build generates files, they have to go somewhere. An in-source build puts them in your source tree. An out-of-source build puts them in a completely separate directory, so that your source tree is unchanged.<br />
<br />
In the first example, an in-place build is performed, i.e., the binaries are placed in the same directory as the source code.<br />
<br />
cd Hello<br />
ccmake .<br />
make<br />
<br />
In the second example, an out-of-place build is performed, i.e., the source code, libraries, and executables are produced in a directory separate from the source code directory(ies).<br />
<br />
mkdir HelloBuild<br />
cd HelloBuild<br />
ccmake ../Hello<br />
make<br />
<br />
Out-of-source builds are recommended, as you can build multiple variants in separate directories, e.g., HelloBuildDebug, HelloBuildRelease.<br />
<br />
Note: Before performing an out-of-source build ensure that any possible CMake generated in-source build information is removed from the source directory, e.g., CMakeFiles directory, and CMakeCache.txt.<br />
<br />
=== I run an out-of-source build but CMake generates in-source anyway. Why? ===<br />
This means that there is a CMakeCache.txt file in the source tree, possibly as part of an existing in-source build. If CMake is given the path to a directory with a CMakeCache.txt file, it assumes the directory is a build tree. Therefore if one runs "cmake ../mysrc" to build out-of-source but there is a mysrc/CMakeCache.txt file then cmake will treat mysrc as the build tree.<br />
<br />
This is a side-effect of the feature that allows "cmake ." to be used to regenerate a build tree. The behavior will not be changed because mixing in-source and out-of-source builds is not safe anyway (configured headers may be found in the wrong place).<br />
<br />
=== Why does CMake use full paths, or can I copy my build tree? ===<br />
CMake uses full paths because:<br />
<br />
# configured header files may have full paths in them, and moving those files without re-configuring would cause upredictable behavior.<br />
# because cmake supports out of source builds, if custom commands used relative paths to the source tree, they would not work when they are run in the build tree because the current directory would be incorrect.<br />
# on Unix systems rpaths might be built into executables so they can find shared libraries at run time. If the build tree is moved old executables may use the old shared libraries, and not the new ones.<br />
<br />
Can the build tree be copied or moved?<br />
<br />
The short answer is NO. The reason is because full paths are used in CMake, see above. The main problem is that cmake would need to detect when the binary tree has been moved and rerun. Often when people want to move a binary tree it is so that they can distribute it to other users who may not have cmake in which case this would not work even if cmake would detect the move.<br />
<br />
The workaround is to create a new build tree without copying or moving the old one.<br />
<br />
<br />
=== CMake does not generate a "make distclean" target. Why? ===<br />
Some build trees created with GNU autotools have a "make distclean" target that cleans the build and also removes Makefiles and other parts of the generated build system. CMake does not generate a "make distclean" target because CMakeLists.txt files can run scripts and arbitrary commands; CMake has no way of tracking exactly which files are generated as part of running CMake. Providing a distclean target would give users the false impression that it would work as expected. (CMake does generate a "make clean" target to remove files generated by the compiler and linker.)<br />
<br />
A "make distclean" target is only necessary if the user performs an in-source build. CMake supports in-source builds, but we strongly encourage users to adopt the notion of an out-of-source build. Using a build tree that is separate from the source tree will prevent CMake from generating any files in the source tree. Because CMake does not change the source tree, there is no need for a distclean target. One can start a fresh build by deleting the build tree or creating a separate build tree.<br />
<br />
(If a CMakeLists.txt uses ADD_CUSTOM_COMMAND to generate source files in the source tree, not the build tree, then in CMake 2.2 or higher "make clean" will remove them. See next question.)<br />
<br />
=== Running "make clean" does not remove custom command outputs. Why? ===<br />
In CMake 2.2 and higher custom command outputs should be removed by make clean. Make sure you are using at least this version. Prior to CMake 2.2 custom command outputs were not automatically added to the list of files to clean. In CMake 2.0 the developer can specify a list of files to be deleted. This can be done using SET_DIRECTORY_PROPERTIES setting property ADDITIONAL_MAKE_CLEAN_FILES to the list of files.<br />
<br />
We however strongly recommend using an "out-of-source" build which never writes any files to the source tree. Using a separate source and build tree greatly reduces the need for "make clean" and "make distclean" targets to clean away files that differ between builds.<br />
<br />
<br />
== Writing CMakeLists.txt ==<br />
<br />
=== How to have backward and forward compatibility? ===<br />
<br />
As of CMake 2.6 we employ a "Policy" mechanism to provide backwards compatibility.<br />
The basic requirement for projects is to include one line at the top of the highest CMakeLists.txt file:<br />
<br />
cmake_minimum_required(VERSION 2.6) # or other version<br />
<br />
This tells versions of CMake older than that specified that they are too old to build the project.<br />
They will report this information to the user.<br />
It also tells versions of CMake newer than that specified that the project may not be aware of policies introduced in later versions, which enables additional compatibility.<br />
For futher documentation, see<br />
<br />
* [[CMake_Policies|CMake Policy Mechanism]]<br />
* [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:cmake_policy cmake_policy() command]<br />
* [http://www.cmake.org/cmake/help/cmake2.6docs.html#section_Policies CMake 2.6 Policies]<br />
<br />
=== How do I get the current source or binary directory? ===<br />
The variable CMAKE_CURRENT_SOURCE_DIR contains the absolute path to your current source directory, while CMAKE_CURRENT_BINARY_DIR points to the equivalent binary directory.<br />
<br />
=== Why are my CMake variables not updated in the GUI after a SET command? ===<br />
The cache variables listed in the GUI when you press "Configure" are used to initialize the values seen by the code in CMakeLists.txt files.<br />
<br />
Changes made by the code are used during the configure step and seen by the generators but are not stored back into the cache. For example:<br />
<br />
SET(BUILD_SHARED_LIBS ON)<br />
<br />
will turn on building of shared libraries for the directory containing the command and all subdirectories, but the change will not appear in the GUI.<br />
<br />
You can use the CACHE and FORCE options on the SET command to change variables in a way that will be reflected in the GUI. Run<br />
<br />
cmake --help-command SET<br />
<br />
to see full instructions for the command.<br />
<br />
<br />
=== How can I change the default build mode and see it reflected in the GUI? ===<br />
Adapt the following commands in your CMakeLists.txt (this example sets the Release<br />
With Debug Information mode):<br />
<pre><br />
IF(NOT CMAKE_BUILD_TYPE)<br />
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING<br />
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."<br />
FORCE)<br />
ENDIF(NOT CMAKE_BUILD_TYPE)<br />
</pre><br />
<br />
=== How do I generate an executable, then use the executable to generate a file? ===<br />
<br />
Create the generator executable by just adding a target:<br />
<br />
ADD_EXECUTABLE(generate generate.c)<br />
<br />
The rest of the process is simpler in CMake 2.6 and above than in previous versions.<br />
<br />
Use <code>ADD_CUSTOM_COMMAND</code> to specify a custom build rule for the file.<br />
(In this example we assume <code>generate</code> accepts the input and output files as arguments.)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT someoutput.txt<br />
COMMAND generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt<br />
)<br />
<br />
This tells CMake how to build the file but does not actually add a rule to the build system.<br />
Another target must require it.<br />
One may create a custom target explicitly for this rule:<br />
<br />
ADD_CUSTOM_TARGET(driver ALL DEPENDS someoutput.txt)<br />
<br />
or the file may be added as part of some other target:<br />
<br />
ADD_EXECUTABLE(product product.c someoutput.txt)<br />
<br />
<font color=#555555><br />
In CMake 2.4 and below the <code>generate</code> target may not be specified directly in the <code>COMMAND</code> option of <code>add_custom_command</code><br />
(but it can still be used in the <code>DEPENDS</code> option as of CMake 2.4).<br />
Instead use GET_TARGET_PROPERTY to obtain the location of the generated executable.<br />
Additionally, the output must always be specified by full path.<br />
<br />
GET_TARGET_PROPERTY(GENERATE_EXE generate LOCATION)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
COMMAND ${GENERATE_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
DEPENDS generate<br />
)<br />
</font><br />
<br />
=== How can I generate a source file during the build? ===<br />
The ADD_CUSTOM_COMMAND command lets you generate a source file that you can then include in another target. For example:<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c<br />
)<br />
ADD_EXECUTABLE(foo foo.c)<br />
<br />
This will create an executable by copying bar.c to foo.c and then compiling foo.c to produce foo. CMake allows you to put generate source files in the current source or binary directory, so we were careful to output foo.c to the current binary directory. When we add foo.c to foo, CMake will look in either directory for it. Even if foo.c does not yet exist, CMake is smart enough to notice that a custom command creates it. (For the file named as the OUTPUT, CMake has its GENERATED source file property set to true.)<br />
<br />
You can also use ADD_CUSTOM_COMMAND when the<br />
[[CMake_FAQ#How_do_I_generate_an_executable.2C_then_use_the_executable_to_generate_a_file.3F|generator command is another executable in the same project]].<br />
<br />
Sometimes, the program doing the generation may generate multiple output files that each need to be part of the build. CMake 2.4 or higher supports having multiple files listed in the OUTPUT section. For example, suppose you had a program that read input.txt and generated three files output1.cpp, output2.h, and output3.cpp, and that those three files needed to be compiled into an executable program. The cmake list file for that would look like this:<br />
<br />
PROJECT(FOO)<br />
# make sure cmake addes the binary directory for the project to the include path<br />
INCLUDE_DIRECTORIES(${FOO_BINARY_DIR})<br />
# add the executable that will do the generation<br />
ADD_EXECUTABLE(my_generator my_generator.cxx)<br />
GET_TARGET_PROPERTY(MY_GENERATOR_EXE my_generator LOCATION)<br />
# add the custom command that will generate all three files<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp<br />
COMMAND ${MY_GENERATOR_EXE} ${FOO_BINARY_DIR} ${FOO_SOURCE_DIR}/input.txt<br />
DEPENDS my_generator<br />
MAIN_DEPENDENCY ${FOO_SOURCE_DIR}/input.txt<br />
)<br />
# now create an executable using the generated files<br />
ADD_EXECUTABLE(generated<br />
${FOO_BINARY_DIR}/output1.cpp<br />
${FOO_BINARY_DIR}/output2.h<br />
${FOO_BINARY_DIR}/output3.cpp)<br />
<br />
CMake 2.4 allows you to generate a header file. Because generated headers often cause unnecessary rebuilds, you should try to avoid them; consider using the CONFIGURE_FILE command to prepare the header at CMake time. If you must generate a header file, use code like this:<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h<br />
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.h ${CMAKE_CURRENT_BINARY_DIR}/foo.h<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.h<br />
)<br />
ADD_EXECUTABLE(foo foo.c ${CMAKE_CURRENT_BINARY_DIR}/foo.h)<br />
<br />
This is like the first example above, except that it generates a header instead of a C file. The header might not exist when the build system scans foo.c's dependencies, so there is no way for CMake to know that this target requires foo.h unless we can tell it that foo.h may exist in the future. We give CMake this knowledge by listing the generated header file in the set of source files for the target. (This requires CMake 2.4. Previous versions of CMake required use of the OBJECT_DEPENDS source file property.)<br />
<br />
=== How can I add a dependency to a source file which is generated in a subdirectory? ===<br />
<br />
Rules created with <code>ADD_CUSTOM_COMMAND</code> as [[CMake_FAQ#How_can_I_generate_a_source_file_during_the_build.3F|above]] have scope only in the directory in which they are specified.<br />
If the generated file is needed in another directory, a target-level dependency needs to be added.<br />
Create a target in the subdirectory with the custom rule in order to drive it:<br />
<br />
# subdir/CMakeLists.txt<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c<br />
)<br />
ADD_CUSTOM_TARGET(generate_foo DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.c)<br />
<br />
Now other targets can depend on the target from the subdirectory:<br />
<br />
# CMakeLists.txt<br />
ADD_SUBDIRECTORY(subdir)<br />
# Create the executable.<br />
ADD_EXECUTABLE(generated ${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c)<br />
# Tell CMake the source won't be available until build time.<br />
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c PROPERTIES GENERATED 1)<br />
# Make sure the source is generated before the executable builds.<br />
ADD_DEPENDENCIES(generated generate_foo)<br />
<br />
=== I use EXEC_PROGRAM but the result is not set in subdirectories. Why? ===<br />
<br />
An unfortunate holdover from ancient CMake versions is that certain commands are "inherited" into subdirectories and others are not. EXEC_PROGRAM is not inherited. What this means is that when the listfile code from a parent directory executes in a subdirectory the EXEC_PROGRAM command is left out. Therefore the code executes differently. This problem was fixed in CMake 2.2, but for older versions you will have to cache the result:<br />
<br />
<pre><br />
EXEC_PROGRAM(my-program OUTPUT_VARIABLE MY_OUTPUT)<br />
SET(MY_OUTPUT "${MY_OUTPUT}" CACHE INTERNAL "")<br />
</pre><br />
<br />
This will store the result in a global location so it will be available in the subdirectory. Be sure to choose a descriptive name for MY_OUTPUT to avoid conflict in the global setting.<br />
<br />
=== How can I get or set environment variables? ===<br />
<br />
CMake names environment variables using an ENV prefix and surrounding the names in curly braces. Here is an example:<br />
<br />
<pre><br />
MESSAGE("$ENV{PATH}")<br />
</pre><br />
<br />
Reading variables will work in any version of CMake. Writing to them works in CMake 2.2 and higher using the following syntax:<br />
<br />
<pre><br />
SET(ENV{HELLO} "World")<br />
</pre><br />
<br />
Note that there is currently no way to tell apart an empty environment variable value from a variable that is not set at all.<br />
<br />
One should avoid using environment variables for controlling the flow of CMake code (such as in IF commands). The build system generated by CMake may re-run CMake automatically when CMakeLists.txt files change. The environment in which this is executed is controlled by the build system and may not match that in which CMake was originally run. If you want to control build settings on the CMake command line, you need to use cache variables set with the -D option. The settings will be saved in CMakeCache.txt so that they don't have to be repeated every time CMake is run on the same build tree.<br />
<br />
Also, environment variables SET in the CMakeLists.txt ''only'' take effect for cmake itself, so you cannot use this method to set an environment variable that a custom command might need.<br />
<br />
=== Why do I have unwanted semicolons ; in my compiler flags? ===<br />
CMake has a list data type. A list is stored as a string of semicolon-separated list elements. Whitespace separated arguments to a SET statement are interpreted as list elements. For instance, SET(var a b c d e) will give "var" a value of a;b;c;d;e and this list can be used by other CMake commands. However, if you pass ${var} to a non-CMake external tool, such as a compiler's command line, you are passing a;b;c;d;e which is not what you want. Instead you either need to pass "${var}", so that the list will be converted to a whitespace-separated string, or you need to SET(var "a b c d e") in the 1st place so that you're working with a string, not a list.<br />
<br />
=== How can I get quoting and escapes to work properly? ===<br />
If you want to escape a character in CMake, you use "\", like in C code. For example, if you wanted to have a quote embedded in a string you would do this: "\"". However, each level of CMake that processes your code will need one level of escaping to work. So, if you configure a file that is read by cmake or cpack and you want to do the same thing, you would do "\\\"". You would still need to escape the " for the first cmake that processes the string. However, this time, you would want to also escape a '\' as well. This would leave the next level of processing with "\"". Also, for custom commands that may get passed to a shell, it maybe required to do escaping for that shell.<br />
<br />
=== Isn't the "Expression" in the "ELSE (Expression)" confusing? ===<br />
Traditional CMakeLists.txt files prior to 2.6.0, require the following syntax. In the IF syntax, the ELSE section requires the same (Expression) as the IF section. This sometimes can make the script kind of hard to follow, take the short example below:<br />
<br />
IF(WIN32)<br />
...do something...<br />
ELSE(WIN32)<br />
...do something else...<br />
ENDIF(WIN32)<br />
<br />
You might think that the ELSE section, here containing "...do something else...", is for the WIN32 portion of the script. That is not so! It is actually handling the NOT WIN32 section.<br />
<br />
As of CMake 2.6.0 the ELSE() and ENDIF() constructs can be empty. The same is true for closing constructs on ENDMACRO(), ENDFUNCTION(), and ENDFOREACH(). If you require 2.4.x compatibility, CMake 2.4.3 or greater recognizes the CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS option (which is superfluous in 2.6.0)<br />
<br />
cmake_minimum_required(VERSION 2.4.3)<br />
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)<br />
<br />
if(WIN32)<br />
...do something...<br />
elseif(APPLE)<br />
...do something else...<br />
else()<br />
...do something else...<br />
endif()<br />
<br />
=== Which regular expressions are supported by CMake? ===<br />
When using MATCHES or MATCHALL in an IF command, or using any of the STRING(REGEX ...) commands, CMake expects regular expressions, not globs (wild cards). CMake uses the same regular expression engine above all platforms. Here are the meanings of the metacharacters:<br />
<br />
^ Matches at beginning of a line<br />
$ Matches at end of a line<br />
. Matches any single character<br />
[ ] Matches any character(s) inside the brackets<br />
[^ ] Matches any character(s) not inside the brackets<br />
- Matches any character in range on either side of a dash<br />
| Matches a pattern on either side of the |<br />
* Matches preceding pattern zero or more times<br />
+ Matches preceding pattern one or more times<br />
? Matches preceding pattern zero or once only<br />
() Saves a matched expression and uses it in a later match<br />
<br />
Example: "[-][L]([^ ;])+" matches all strings beginning with -L and ending with a space or a semicolon, the usual linkdirs under Linux.<br />
<br />
Here is how to catch a part of a string. The variable test is filled with some content, and then we want to catch the "me":<br />
<br />
SET(test "hello world ! catch: me if you can")<br />
STRING(REGEX REPLACE ".*catch: ([^ ]+).*" "\\1" result "${test}" )<br />
MESSAGE(STATUS "result= ${result}")<br />
<br />
This is slightly tricky. The part inside the brackets is available in \\1 . CMake will copy the variable test to the variable result, but then it will replace everything that the regular expression matches with \\1. This means the first regular expression has to match the whole string and the part we want to catch has to be put in parens.<br />
<br />
-- result= me<br />
<br />
For those of you who know Perl, the equivalent Perl code could be:<br />
<br />
$test = "hello world ! catch: me if you can";<br />
$result = $test;<br />
$result =~ s/.*catch: ([^ ]+).*/$1/;<br />
print "-- result= $result\n";<br />
<br />
There are other ways to do this in Perl, but this is how we do it in CMake because \\1 does not become a variable like $1 does in perl, so there is no SET(result ${\\1}) in CMake.<br />
<br />
<br />
=== How to convert a semicolon separated list to a whitespace separated string? ===<br />
<br />
set(foo<br />
abc.c<br />
abc.b<br />
abc.a<br />
)<br />
<br />
foreach(arg ${foo})<br />
set(bar "${bar} ${arg}")<br />
endforeach(arg ${foo})<br />
<br />
message("foo: ${foo}")<br />
message("bar: ${bar}")<br />
<br />
=== How can I build multiple modes without switching ? ===<br />
To build multiple modes (e.g. Debug and Release) in one shot without constantly running cmake -DCMAKE_BUILD_TYPE=Debug and cmake -DCMAKE_BUILD_TYPE=Release in source tree create a directory for builds eg.:<br />
<br />
<pre><br />
Project-directory/<br />
/Build<br />
</pre><br />
<br />
Inside you can place as many target directories for out-of-source build modes as you want, e.g.:<br />
<br />
<pre><br />
Project-directory/<br />
/Build<br />
/Debug<br />
/Release<br />
</pre><br />
<br />
In each of these directories issue a command (assuming that you have CMakeLists.txt directly in Project-directory)<br />
<br />
<pre><br />
cmake -DCMAKE_BUILD_TYPE=type_of_build ../../<br />
</pre><br />
<br />
to create a cmake cache configured for requested build type.<br />
<br />
Now you can make each build just by entering appropriate directory and executing a make command.<br />
<br />
=== How can I extend the build modes with a custom made one ? ===<br />
The following code snipet (taken from a CMakeLists.txt) adds a Maintainer mode:<br />
<pre><br />
SET( CMAKE_CXX_FLAGS_MAINTAINER "-Wall -Wabi" CACHE STRING<br />
"Flags used by the C++ compiler during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_C_FLAGS_MAINTAINER "-Wall -pedantic" CACHE STRING<br />
"Flags used by the C compiler during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER<br />
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING<br />
"Flags used for linking binaries during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER<br />
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING<br />
"Flags used by the shared libraries linker during maintainer builds."<br />
FORCE )<br />
MARK_AS_ADVANCED(<br />
CMAKE_CXX_FLAGS_MAINTAINER<br />
CMAKE_C_FLAGS_MAINTAINER<br />
CMAKE_EXE_LINKER_FLAGS_MAINTAINER<br />
CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )<br />
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs<br />
SET( CMAKE_BUILD_TYPE "" CACHE STRING<br />
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Maintainer."<br />
FORCE )<br />
</pre><br />
Notes: The flags used in this example are specific to GCC. Change them as needed for your project. Additionally the SET(CMAKE_BUILD_TYPE) command will override<br />
a CMAKE_BUILD_TYPE previously set in the CMakeLists.txt.<br />
<br />
=== Why does <code>foreach</code> skip empty values? ===<br />
<br />
The code in question is of the form<br />
<br />
set(var "a;b;;c;d") # list 'a', 'b', '', 'c', 'd'<br />
foreach(v ${var})<br />
# v=a, v=b, v=c, v=d, one at a time<br />
endforeach()<br />
<br />
and the loop variable 'v' never attains the empty-string value ''.<br />
This is because the <code>${var}</code> syntax is an unquoted argument so the CMake language expands the list and removes the empty value.<br />
The foreach command does not even see the empty value.<br />
One can verify this because the code<br />
<br />
foreach(v a b "" c d)<br />
...<br />
endforeach()<br />
<br />
will see the empty value.<br />
<br />
=== Does CMake support precompiled headers? ===<br />
<br />
Yes and no. Every platform does precompiled headers a bit differently, and there is currently no first-class interface provided by CMake and implemented on every platform.<br />
However, CMake does provide enough primitives for projects to use precompiled headers on specific platforms.<br />
Our issue tracker has a [http://www.cmake.org/Bug/view.php?id=1260 feature request] with attachements providing user-contributed helper macros for some platforms.<br />
<br />
== Writing FindXXX.cmake files ==<br />
<br />
=== What are the rules to write a FindXXX.cmake file? ===<br />
<br />
Let's follow the instructions and the advices in the <br />
Modules/readme.txt [http://www.cmake.org/cgi-bin/viewcvs.cgi/Modules/readme.txt?root=CMake&view=markup]<br />
file located in the CVS repository.<br />
<br />
=== Why does find_library look in system directories before its PATHS option? ===<br />
<br />
The code in question is often of the form<br />
<br />
find_library(FOO_LIBRARY NAMES foo PATHS /opt/foo/lib)<br />
<br />
CMake will find "<code>/usr/lib/libfoo.so</code>" instead of "<code>/opt/foo/lib/libfoo.so</code>" if both exist.<br />
The reason is that /opt/foo/lib is a <i>hard-coded guess</i> of the location.<br />
The documentation of <code>[http://www.cmake.org/cmake/help/cmake2.6docs.html#command:find_library find_library]</code> specifies the search order.<br />
User, project, and system configuration variables are always more local than hard-coded guesses and should override them, so<br />
the PATHS option is used last.<br />
<br />
Some find-modules compute probable locations based on other information <i>available from the system</i> such as a project-specific environment variable.<br />
The HINTS option (CMake 2.6 and higher) takes precedence over system directories specifically for this case:<br />
<br />
file(TO_CMAKE_PATH "$ENV{FOO_LIB_DIR}" FOO_LIB_DIR)<br />
find_library(FOO_LIBRARY NAMES foo HINTS ${FOO_LIB_DIR})<br />
<br />
CMake will find "<code>$ENV{FOO_LIB_DIR}/libfoo.so</code>" before "<code>/usr/lib/libfoo.so</code>".<br />
<br />
== Finding and using external packages ==<br />
<br />
=== How do I use CMake to generate SWIG wrapper libraries? ===<br />
<br />
CMake version 2 includes a module that supports the generation of SWIG wrapper libraries. The SWIG package defines the following macros: SWIG_ADD_MODULE and SWIG_LINK_LIBRARIES.<br />
<br />
<pre><br />
# This example shows how to use python<br />
# Currently these languages have been tested:<br />
# perl tcl ruby php4 pike<br />
<br />
FIND_PACKAGE(SWIG REQUIRED)<br />
INCLUDE(${SWIG_USE_FILE})<br />
<br />
FIND_PACKAGE(PythonLibs)<br />
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})<br />
<br />
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})<br />
<br />
SET(CMAKE_SWIG_FLAGS "")<br />
<br />
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)<br />
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")<br />
SWIG_ADD_MODULE(example python<br />
example.i example.cxx)<br />
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})<br />
<br />
</pre><br />
<br />
<pre><br />
# This example shows how to use tcl<br />
PROJECT(TCL_WRAP)<br />
SET ( MODULE_NAME project )<br />
SET ( INTERFACE_FILES project.i)<br />
SET ( SRC_FILES Vertex.h Vertex.cxx Shapes.h Shapes.cxx )<br />
<br />
FIND_PACKAGE(SWIG REQUIRED)<br />
INCLUDE(${SWIG_USE_FILE})<br />
<br />
# Look for TCL<br />
INCLUDE_DIRECTORIES(${TCL_INCLUDE_PATH})<br />
<br />
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80<br />
PATHS /usr/lib /usr/local/lib)<br />
IF (TCL_LIBRARY)<br />
TARGET_ADD_LIBRARY (${MODULE_NAME} TCL_LIBRARY)<br />
ENDIF (TCL_LIBRARY)<br />
<br />
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})<br />
<br />
SET(CMAKE_SWIG_FLAGS "-c++")<br />
<br />
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CPLUSPLUS ON)<br />
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CMAKE_SWIG_FLAGS "-includeall")<br />
SWIG_ADD_MODULE(${MODULE_NAME} tcl ${INTERFACE_FILES} ${SRC_FILES})<br />
SWIG_LINK_LIBRARIES(${MODULE_NAME} ${TCL_LIBRARIES})<br />
</pre><br />
<br />
=== How do I use CMake to build LaTeX documents? ===<br />
Use the following approach. Note that you have to set LATEX_COMPILE to LaTeX executable, DVIPDF_COMPILE to dvi to pdf converter. Also, the LaTeX source is TDocument.tex and the result is called TDocument.pdf. Note that this uses commands in CMake version 1.8 or later.<br />
<br />
PROJECT(Document)<br />
IF(LATEX_COMPILE)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.tex<br />
COMMAND ${LATEX_COMPILE} <br />
ARGS ${Document_SOURCE_DIR}/TDocument.tex <br />
)<br />
ENDIF(LATEX_COMPILE)<br />
<br />
IF(DVIPDF_COMPILE)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi <br />
COMMAND ${DVIPDF_COMPILE}<br />
ARGS ${Document_SOURCE_DIR}/TDocument.dvi<br />
)<br />
ENDIF(DVIPDF_COMPILE)<br />
<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf<br />
)<br />
<br />
The following uses commands in CMake version 2.0 and later<br />
<br />
PROJECT(Document)<br />
# <br />
# Find LaTeX<br />
#<br />
FIND_PACKAGE(LATEX)<br />
<br />
IF(LATEX_COMPILER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS ${Document_SOURCE_DIR}/TDocument.tex<br />
DEPENDS ${Document_SOURCE_DIR}/TDocument.tex<br />
COMMENT "Tex2dvi"<br />
)<br />
<br />
IF(DVIPS_CONVERTER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.ps<br />
COMMAND ${DVIPS_CONVERTER}<br />
ARGS ${Document_BINARY_DIR}/TDocument.dvi<br />
-o ${Document_BINARY_DIR}/TDocument.ps<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi<br />
COMMENT "dvi2ps"<br />
)<br />
<br />
IF(PS2PDF_CONVERTER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf<br />
COMMAND ${PS2PDF_CONVERTER}<br />
ARGS ${Document_BINARY_DIR}/TDocument.ps<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.ps<br />
COMMENT "ps2pdf"<br />
)<br />
<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf<br />
)<br />
ENDIF(PS2PDF_CONVERTER)<br />
ENDIF(DVIPS_CONVERTER)<br />
ENDIF(LATEX_COMPILER)<br />
<br />
=== How do I get LaTeX references to be correct? ===<br />
When your latex document contains references (e.g. \ref{...} command) you get to run two passes of latex. In the<br />
most general case, i.e. when additionally your document uses a bibtex bibliography, you shall need three<br />
passes of latex (and one pass of bibtex):<br />
# latex (first pass: for bibtex to have an .aux file)<br />
# bibtex (for generating the .bbl file)<br />
# latex (second pass)<br />
# latex (third pass)<br />
<br />
The following code snippet illustrates how you can "pervert" the bibtex and latex generated<br />
auxilary files (.aux, .log, .dvi, .bbl...) to create an "artificial" set of CMake dependencies.<br />
The side-effect of those dependencies should hopefully be the above described sequence of calls<br />
to latex and bibtex<br />
<pre><br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/UsersManual.tex<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (first pass)"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux<br />
COMMAND ${BIBTEX_COMPILER}<br />
ARGS -terse ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Bibtex"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (second pass)"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (third pass)"<br />
)<br />
# Eventually trigger the whole process<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log<br />
)<br />
</pre><br />
<br />
=== How can I set TEXINPUTS for a LaTeX compilation? ===<br />
First note that most often you can avoid using TEXINPUTS by copying all the necessary files (.tex source file and<br />
included graphic files e.g. .eps files) from your PROJECT_SOURCE_DIR hirarchy to your PROJECT_BINARY_DIR subdir<br />
[refer to CONFIGURE_FILE with the COPYONLY flag set for copying files]. Since by default latex uses the current working directory as value for TEXINPUTS you should be all set. As expected, this trick is quick AND dirty since your<br />
concerned PROJECT_BINARY_DIR subdir now contains files that are NOT generated by CMake (in the sense that those<br />
files are not the result of a system command but were merely duplicated)... <br />
<br />
If you consider it is cleaner or easier to define a TEXINPUTS environment variable [the latex command probably<br />
misses a -I flag] you can find an example in the InsightDocuments cvs archive (refer to the section "cvs access"<br />
near the bottom of Kitware's ITK download page) or use google with keywords "ITK_TEXINPUTS CONFIGURE_FILE".<br />
Look at InsightDocuments/CourseWare/Training/Vis2003/Latex/CMakeLists.txt and search for e.g. "LaTeXWrapper.sh.in".<br />
<br />
Roughly the mechanism goes:<br />
* SET ITK_TEXINPUTS with the desired TEXINPUTS<br />
* CONFIGURE_FILE "InsightDocuments/CourseWare/Training/Vis2003/LaTeXWrapper.sh.in" which generates an sh shell script setting the shell variable TEXINPUTS prior to running the latex command<br />
* use ADD_CUSTOM_COMMAND to invoke this shell script<br />
This very example is Win32 portable (except that LaTeXWrapper.bat.in generates a .bat shell script)<br />
<br />
== Library questions ==<br />
<br />
=== Can I build both shared and static libraries with one ADD_LIBRARY command? ===<br />
<br />
No. Each library you build must have a unique target name, i.e. the "libname" field of the ADD_LIBRARY command. That way, CMake can track dependencies separately for each library. Libraries can have the same OUTPUT_NAME, see the SET_TARGET_PROPERTIES command, but this is not the default.<br />
<br />
=== Does that mean I have to build all my library objects twice, once for shared and once for static?! I don't like that! ===<br />
<br />
In practice, most libraries have different defines and compiler flags for the shared vs. static cases. So you would have to build all your library objects twice anyways. However, if you happen to have '''''exactly''''' the same defines and compiler flags for the shared vs. static cases...<br />
<br />
...if you're using Linux and a GCC-style linker, you could do the following. Note that for this to work correctly on linux, the zzSTATIC source files should have been compiled with "-fPIC" to ensure they will work in a shared library.<br />
<br />
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)<br />
ADD_LIBRARY(zzSTATIC STATIC -fPIC)<br />
ADD_LIBRARY(zzDYNAMIC SHARED)<br />
TARGET_LINK_LIBRARIES(zzDYNAMIC -Wl,-whole-archive zzSTATIC -Wl,-no-whole-archive)<br />
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)<br />
<br />
...if you want a cross-platform approach that works on all compilers, not just GCC or Linux, you could extract the locations of previously built object files and insert them directly into the libraries that need them. This is documented in [http://www.cmake.org/Bug/view.php?id=5155 CMake Feature Request #5155: standard way to locate object files]. Unfortunately this approach relies on CMake's internal implementation, and that implementation could change in the future, breaking your code.<br />
<br />
=== How do I make my shared and static libraries have the same root name, but different suffixes? ===<br />
Set the OUTPUT_NAME of your shared and static libraries to the same thing.<br />
<br />
ADD_LIBRARY(foo SHARED ${foo_sources})<br />
ADD_LIBRARY(foo-static STATIC ${foo_sources})<br />
# The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it.<br />
# The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it.<br />
SET_TARGET_PROPERTIES(foo-static PROPERTIES OUTPUT_NAME "foo")<br />
# Now the library target "foo-static" will be named "foo.lib" with MS tools.<br />
# This conflicts with the "foo.lib" import library corresponding to "foo.dll",<br />
# so we add a "lib" prefix (which is default on other platforms anyway):<br />
SET_TARGET_PROPERTIES(foo-static PROPERTIES PREFIX "lib")<br />
<br />
One more detail is needed with CMake 2.6.x and lower (but not CMake 2.8 or higher). If you are building your shared and static libraries in the same directory, you will also need the following to keep your shared and static libraries from clobbering each other during the build.<br />
<br />
# Help CMake 2.6.x and lower (not necessary for 2.8 and above, but doesn't hurt):<br />
SET_TARGET_PROPERTIES(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1)<br />
SET_TARGET_PROPERTIES(foo-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)<br />
<br />
=== How do I rename a library after it has already been built? ===<br />
You don't rename it. It's been built! Its name is whatever CMakeLists.txt says it's supposed to be.<br />
<br />
Perhaps you want to copy the library to a different name. But, are you sure that's what you want to do? You could just change the name in your ADD_LIBRARY command or change its OUTPUT_NAME property using SET_TARGET_PROPERTY(). If you really really want to copy the library to a different name, try:<br />
<br />
GET_TARGET_PROPERTY(LIB_NAME Foo LOCATION)<br />
GET_TARGET_PROPERTY(Bar_prefix Foo PREFIX)<br />
GET_TARGET_PROPERTY(Bar_suffix Foo SUFFIX)<br />
SET(NEW_LIB_NAME ${Bar_prefix}Bar${Bar_suffix})<br />
<br />
ADD_CUSTOM_COMMAND(<br />
TARGET Foo<br />
POST_BUILD<br />
COMMAND ${CMAKE_COMMAND} -E copy ${LIB_NAME} ${NEW_LIB_NAME}<br />
)<br />
<br />
On Windows you may also want to copy the .dll import lib, using the same approach as above, but with IMPORT_PREFIX and IMPORT_SUFFIX. ''Problem: LOCATION only refers to 1 file, the .dll. What is a simple way to get the location of the import lib? Could provide a complicated way, but that's annoying.''<br />
<br />
=== Does CMake support "convenience" libraries? ===<br />
No. CMake does not currently support convenience libraries. A "convenience" library, as GNU libtool calls it, is an archive of objects to be mixed into other libraries. Other libraries "link" to the convenience library, but the convenience library does not export any symbols; GNU libtool never installs the convenience library; no programs ever link to the convenience library.<br />
<br />
This does '''not''' mean that a project using convenience libraries cannot be converted to CMake. Instead the source files may be listed in each target that needs them. They will be built for each target separately using all the preprocessor definitions and flags configured for that target.<br />
<br />
=== Why are libraries linked to my shared library included when something links to it? ===<br />
This question arises when one has a library B which links to some library A. When a third target, say C, links to B, CMake will automatically include C to A also. When the libraries are static, then this is always necessary. When the libraries are shared, this is the default behavior provided by CMake. CMake 2.6 and above provide the target property "LINK_INTERFACE_LIBRARIES" (http://www.cmake.org/HTML/cmake-2.6.html#prop_tgt:LINK_INTERFACE_LIBRARIES) to specify the libraries that should be transitively included in the link by CMake. CMake 2.4 and below do not support the property.<br />
<br />
Something like the following will work in CMake 2.6:<br />
<br />
<pre><br />
set_target_properties(mylibrary<br />
PROPERTIES<br />
LINK_INTERFACE_LIBRARIES ""<br />
)<br />
</pre><br />
<br />
=== CMake dependency scanner ===<br />
<br />
CMake does not preprocess source files while scanning dependencies. Code like<br />
<pre><br />
#if 0<br />
# include "bla.h"<br />
#endif<br />
</pre><br />
will result in a dependency on "bla.h". This sometimes leads to source files recompiling unnecessarily but will not break the build.<br />
<br />
== Installation questions ==<br />
<br />
=== Does CMake's "make install" support DESTDIR? ===<br />
'''Yes''', especially when the build-system generator uses CMake's builtin support for installing files: Simply define the DESTDIR environment variable during installation and CMake will treat that value as the root of the file system for all installation paths; naturally, the DESTDIR path must be absolute.<br />
<br />
For example, if the Makefile generator is used, then all of the following are example usages of DESTDIR (perhaps assuming the bash shell for the last 2):<br />
<br />
(1) make install DESTDIR="/some/absolute/path"<br />
(2) make DESTDIR="/some/absolute/path" install<br />
(3) DESTDIR="/some/absolute/path" make install<br />
(4) export DESTDIR="/some/absolute/path<br />
make install<br />
<br />
=== Can I do "make uninstall" with CMake?===<br />
By default, CMake does not provide the "make uninstall" target, so you cannot do this. We do not want "make uninstall" to remove useful files from the system.<br />
<br />
If you want an "uninstall" target in your project, then nobody prevents you from providing one. You need to delete the files listed in install_manifest.txt file. Here is how to do it. First create file cmake_uninstall.cmake.in in the top-level directory of the project:<br />
<br />
<pre><br />
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")<br />
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")<br />
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")<br />
<br />
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)<br />
STRING(REGEX REPLACE "\n" ";" files "${files}")<br />
FOREACH(file ${files})<br />
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")<br />
IF(EXISTS "$ENV{DESTDIR}${file}")<br />
EXEC_PROGRAM(<br />
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""<br />
OUTPUT_VARIABLE rm_out<br />
RETURN_VALUE rm_retval<br />
)<br />
IF(NOT "${rm_retval}" STREQUAL 0)<br />
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")<br />
ENDIF(NOT "${rm_retval}" STREQUAL 0)<br />
ELSE(EXISTS "$ENV{DESTDIR}${file}")<br />
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")<br />
ENDIF(EXISTS "$ENV{DESTDIR}${file}")<br />
ENDFOREACH(file)<br />
</pre><br />
<br />
Then in the top-level CMakeLists.txt add the following logic:<br />
<br />
<pre><br />
CONFIGURE_FILE(<br />
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"<br />
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"<br />
IMMEDIATE @ONLY)<br />
<br />
ADD_CUSTOM_TARGET(uninstall<br />
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")<br />
</pre><br />
<br />
Now you will have an "uninstall" target at the top-level directory of your build tree.<br />
<br />
Instead of creating an "uninstall" target, Unix users could enter this command in the shell:<br />
<br />
xargs rm < install_manifest.txt<br />
<br />
== Distribution questions ==<br />
<br />
=== Where is "make dist"? ===<br />
<br />
CMake doesn't create a "make dist" target.<br />
<br />
=== What is the best way to distribute source code or binaries for a cmake-based project? ===<br />
<br />
For creating source or binary packages there is now [[CMake#CPack | CPack]] coming with CMake, see the <br />
[[ CMake#CPack | documentation]].<br />
<br />
Of course you can also use any other ways to create packages.<br />
<br />
== Platform-specific questions ==<br />
=== How do I build universal binaries on Mac OS X? ===<br />
Before running CMake with an empty build tree, set the CMAKE_OSX_ARCHITECTURES environment variable. It should be set to contain a ; separated list of architectures that you want in the binary. For example, for 32-bit PowerPC and Intel you would do this:<br />
<br />
CMAKE_OSX_ARCHITECTURES=ppc;i386<br />
<br />
If you wish to build both as 32 and 64 bit, do this:<br />
<br />
CMAKE_OSX_ARCHITECTURES=ppc;i386;ppc64;x86_64<br />
<br />
You can also set the same named CMake cache variable on an existing binary tree. This works with both makefiles and the Xcode generator. <br />
<br />
In addition, you can also set the CMAKE_OSX_SYSROOT variable to point to the sysroot (aka Mac OS SDK) to be used. CMake will attempt to pick one on your system, but it can be changed in the cache or via an environment variable before running CMake. The 10.4u SDK or later must be used to create a Universal Binary.<br />
<br />
Universal Binaries are essentially cross compilation and so you should avoid using TRY_RUN, especially for things like testing endianess or variable size because the result will only be correct for one architecture.<br />
<br />
Lastly, note that CTest is only able to test one architecture. See bug 6157.<br />
<br />
=== How can I apply resources on Mac OS X automatically? ===<br />
Using ADD_CUSTOM_COMMAND. For example, let's say you are creating executable MyExecutable, which needs the resources file Carbon.r. All you do is add a custom rule which is executed after the executable is linked:<br />
<br />
<pre><br />
ADD_EXECUTABLE(MyExecutable ${MyExecutable_SRCS})<br />
GET_TARGET_PROPERTY(MyExecutable_PATH MyExecutable LOCATION)<br />
<br />
IF(APPLE)<br />
FIND_PROGRAM(APPLE_RESOURCE Rez /Developer/Tools)<br />
IF(APPLE_RESOURCE)<br />
ADD_CUSTOM_COMMAND(TARGET MyExecutable POST_BUILD<br />
COMMAND ${APPLE_RESOURCE} Carbon.r -o ${MyExecutable_PATH})<br />
ENDIF(APPLE_RESOURCE)<br />
ENDIF(APPLE)<br />
</pre><br />
<br />
This will execute:<br />
<br />
/Developer/Tools/Rez Carbon.r -o /binary/path/MyExecutable<br />
<br />
after MyExecutable is linked.<br />
<br />
'Rez' may be located elsewhere on disk, depending on the version of Mac OS X and Xcode. You can use 'which Rez' in Terminal to find it's full path.<br />
<br />
=== Why does FIND_LIBRARY not find .DLL libraries under WIN32? ===<br />
For those who come from a Unix background to MS Windows:<br />
<br />
You never link directly to the .dll, you have to link against the import library .lib for the .dll.<br />
<br />
Linking against dynamic libraries (.dll under Windows) is quite different from linking against ELF shared objects (.so) under platforms like Linux or NetBSD. In Windows, there are two types of library, a static library and an import library (both confusingly use the .lib extension, however). In Windows, when you build an import library (A.lib) you will get a corresponding (A.dll) that you only need at runtime. At compile time you will need the import library.<br />
<br />
Conclusion: There is no need to find a .dll for linking. You only need to find the .lib import library.<br />
<br />
Some more details can be found here: [http://xenophilia.org/winvunix.html].<br />
<br />
=== Why am I getting a linker error to _mainCRTStartup under WIN32? ===<br />
Your program is a GUI application using WinMain (/subsystem:windows) and not a console application using main. You have to use the WIN32 option with the ADD_EXECUTABLE command.<br />
<br />
ADD_EXECUTABLE(exename WIN32 source1 source2 ... sourceN)<br />
<br />
The second argument to ADD_EXECUTABLE can be WIN32. This indicates that the executable, when compiled on Windows, is a Windows app (using WinMain) and not a console app (using main). Please note that on Unix platforms, CMake ignores the WIN32 and the compiler will use "main" in any case.<br />
<br />
=== Why do I get this error: nafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv ===<br />
<br />
This is because the application is using both the static and dll versions of the MFC library.<br />
To fix the problem, you can do the following:<br />
<br />
SET(CMAKE_MFC_FLAG 2) # force the IDE to use static MFC<br />
ADD_DEFINITIONS(-D_AFXDLL) # make sure if afx.h is included the dll MFC is used<br />
<br />
=== How to use MFC with CMake ===<br />
To use MFC, the CMAKE_MFC_FLAG variable must be set as follows:<br />
<br />
0: Use Standard Windows Libraries<br />
1: Use MFC in a Static Library<br />
2: Use MFC in a Shared DLL <br />
<br />
This can be set in a CMakeLists.txt file and will enable MFC in the application. It should be set to 1 or 2. This is used in visual studio 6 and 7 project files. The CMakeSetup dialog uses MFC and the CMakeLists.txt looks like this:<br />
<br />
ADD_DEFINITIONS(-D_AFXDLL)<br />
SET(CMAKE_MFC_FLAG 2) <br />
ADD_EXECUTABLE(CMakeSetup WIN32 ${SRCS})<br />
<br />
Note that visual studio 9 project files do not appear to work with CMAKE_MFC_FLAG 1; this may be related to [http://www.cmake.org/Bug/view.php?id=7056 bug 7056].<br />
<br />
In order to use MFC with UNICODE, you must also [http://msdn.microsoft.com/en-us/library/dybsewaf.aspx specify the entry point wWinMainCRTStartup]. For example:<br />
<br />
set(CMAKE_MFC_FLAG 2)<br />
set_target_properties(MyApp PROPERTIES<br />
COMPILE_DEFINITIONS _AFXDLL,_UNICODE,UNICODE,_BIND_TO_CURRENT_CRT_VERSION,_BIND_TO_CURRENT_MFC_VERSION<br />
LINK_FLAGS "/ENTRY:\"wWinMainCRTStartup\"")<br />
<br />
See [http://stackoverflow.com/questions/59635/app-does-not-run-with-vs-2008-sp1-dlls-previous-version-works-with-rtm-versions this article] as to why _BIND_TO_CURRENT_CRT_VERSION and _BIND_TO_CURRENT_MFC_VERSION are necessary for Visual Studio 2008 SP1.<br />
<br />
=== How To Put Files in Folders in Visual Studio Projects ===<br />
The Visual Studio IDE supports putting files into folders.<br />
CMake can be used to put files in folders with the SOURCE_GROUP <br />
command. <br />
<br />
SOURCE_GROUP(name [REGULAR_EXPRESSION regex] [FILES src1 src2 ...])<br />
<br />
Defines a group into which sources will be placed in project files. This is mainly used to setup file tabs in Visual Studio. Any file whose name is listed or matches the regular expression will be placed in this group provided the source file is being passed to ADD_EXECUTABLE or ADD_LIBRARY.<br />
<br />
For example:<br />
SOURCE_GROUP(FooFiles FILES foo.cxx)<br />
SOURCE_GROUP(BarFiles FILES bar.cxx)<br />
ADD_LIBRARY(foo foo.cxx bar.cxx)<br />
<br />
In the event a file matches multiple groups, the LAST group that explicitly lists the file will be favored, if any. If no group explicitly lists the file, the LAST group whose regular expression matches the file will be favored. For backwards compatibility this command is also supports the format SOURCE_GROUP(name regex).<br />
<br />
As a convenience to developers CMake automatically adds standard header files to a "Header Files" folder and standard source files to a "Source Files" folder for Visual Studio Projects. This can be overridden via the SOURCE_GROUP method documented above.<br />
<br />
=== How to create Visual Studio 6 Projects that contain only a single build type===<br />
For Visual Studio.NET (version 7.0 and above) it is possible to set the CMAKE_CONFIGURATION_TYPES variable to the build type(s) (Debug/Release/...) that you want. This does not work for Visual Studio 6. There is however a way to achieve this. To create your own set of configurations:<br />
<br />
# Create a directory in which you copy the files *.dsptemplate and CMakeVisualStudio6Configurations.cmake from CMake's Templates directory.<br />
# Edit the .cmake file and change the SET(CMAKE_CONFIGURATION_TYPES ...) line to set the build types that you want in your set.<br />
# Edit the *Header.dsptemplate files to contain only the configuration types you want in your set.<br />
# In your CMakeLists.txt file, set the MSPROJECT_TEMPLATE_DIRECTORY to the directory that you created.<br />
<br />
<br />
That's it. Run CMake and your new configuration files will be created.<br />
<br />
Note: Editing the *Header.dsptemplates files should be done very carefully. Here are some guidelines:<br />
<br />
- You MUST remove the targets that you do not want in your set at the bottom of the file (e.g. '# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"')<br />
- You can remove the '!IF "$(CFG)" == ...' until '!ELSEIF "$(CFG)" == ...' or '!ELSEIF "$(CFG)" == ...' until '!ENDIF' lines for the configurations you do not want. Make sure that the resulting code still starts with '!IF ...' and ends with '!ENDIF' with any number of '!ELSEIF' sections in between. If you create templates for a single configuration (aka makefile), it is possible to remove everything starting from '!IF' until and including '!ENDIF' and leave only the contents of the relevant section intact.<br />
- Do not edit the lines starting with '!MESSAGE' as the changes may - and probably will - corrupt your resulting DSP files. The only thing I was able to change without corrupting the DSP is to remove the irrevant configurations from the "Possible choices for configuration are:" list.<br />
<br />
If you have only a single configuration in your set, you may want to get rid of the intermediate dir that MsDev creates. You can do that by setting:<br />
# PROP BASE Output_Dir ""<br />
# PROP BASE Intermediate_Dir ""<br />
# PROP Intermediate_Dir ""<br />
# PROP Output_Dir "LIBRARY_OUTPUT_PATH"<br />
or<br />
# PROP Output_Dir "EXECUTABLE_OUTPUT_PATH"<br />
<br />
Additionally you should then also edit the '# ADD LINK32' line in the DLLHeader.dsptemplate file. Change for example '/out:"LIBRARY_OUTPUT_PATHDebug/OUTPUT_LIBNAMEDEBUG_POSTFIX.dll"' into '/out:"LIBRARY_OUTPUT_PATHOUTPUT_LIBNAMEDEBUG_POSTFIX.dll"' (Note that the configuration name and also the slash are removed).<br />
<br />
It is even possible to rename the pre-defined configurations of CMake in this way. Let's say you prefer 'PreProduction' over 'RelWithDebInfo'. You can change the name in the *.dsptemplate files, but you should also change it in the CMakeVisualStudio6Configurations.cmake file. Be careful, however. Only entries relevant to the configuration name should be changed. Do not change the /debug options and the entries that contain the build type in capital characters. Internally in CMake the build type will still remain 'RelWithDebInfo', so also the CMAKE_BUILD_TYPE should be set to the old value. You can only change the way it is named in MSDev.<br />
<br />
Note: Apparently MsDev as command-line build tool only performs a partial check on the build type. It will match all configuration types that CONTAIN the build type in their name. (e.g. if you have renamed RelWithDebInfo to DebugRelease, Debug will build Debug and DebugRelease, Release will build Release and DebugRelease. This may be exactly what you want, but be warned.)<br />
<br />
=== Can CMake set the Debugging/Working Directory property in Visual Studio projects? ===<br />
<br />
No. The value of this property is not stored in the project files. It is stored in extra files created by the IDE when a solution is loaded (VS .NET 2003 uses a hidden .suo file next to the .sln solution file). The format of these files is not known to CMake and cannot be generated. In some versions of VS the files are binary and not human readable.<br />
<br />
=== Why does CMakeSetup with the message "LINK : fatal error LNK1104: cannot open file 'user32.lib'" while configuring a project? ===<br />
<br />
The path to the SDK libs (user32.lib) must be added by the IDE when the<br />
project generator "Visual Studio 8 2005" is used, because cmake uses<br />
VCExpress.exe and on the fly generated project files to check<br />
for compiling (VCExpress.exe reads some config files for the<br />
compiler/linker options)<br />
<br />
So add the sdk lib path (...\Microsoft Platform SDK\Lib) at Tools->Options->Projects and Solutions->VC++ Directories->Library files<br />
<br />
See also:<br />
*http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/<br />
<br />
=== How can I avoid the error "Arg list too long" when running make? ===<br />
This error is sometimes encountered when building a static library with many object files using Unix make command. It typically looks something like this:<br />
<br />
<pre><br />
gmake[2]: execvp: /bin/sh: Arg list too long<br />
</pre><br />
<br />
When make tries to run the archiver program to build the static library the shell it uses complains that the argument list is too long. In some shells this can be fixed by setting an environment variable such as <tt>ARG_MAX</tt> to extend the length of the command line it will allow.<br />
<br />
The error can also happen when linking shared libraries, and can be solved by upping the sysconf parameter MAX_ARG. <br />
<br />
On AIX this can be done with the command:<br />
<br />
<pre><br />
chdev -l sys0 -a ncargs='30'<br />
</pre><br />
<br />
=== How can I find out platforms definitions, search paths, etc. from gcc ?===<br />
<br />
The following is really the best if not only way to get information about predefined macros with a GNU compiler:<br />
<pre><br />
$ touch empty.c<br />
$ gcc -v -dD -E empty.c <br />
</pre><br />
This will give you all you might want to know about the preprocessor, the builtin include search dirs and all<br />
predefined definitions, so you can check whether it's __LINUX or _LINUX_ or _APPLE_ or __APPLE etc. <br />
The empty file and all these parameters are really required. You probably want to pipe the output (both stdout and stderr) to a file.<br />
If you want the information for C++, use a C++ file suffix for the empty file.<br />
<br />
This is how you can get the builtin library search paths:<br />
<pre><br />
$ gcc --print-search-dirs<br />
</pre><br />
<br />
=== How can I get a windows registry key ?===<br />
<br />
The only thing to know is that you can't use just the "SET" command in place of "GET" command.<br />
CMake read the value from the registry only when you "get" it from the cache. For instance :<br />
<br />
<pre><br />
GET_FILENAME_COMPONENT(SDK_ROOT_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\PACKAGE;Install_Dir]" ABSOLUTE CACHE)<br />
</pre><br />
<br />
If a key name (ex: Install_Dir in this case) was not specified , the Default key value will be get.<br />
Now you could use the SDK_ROOT_PATH to add include and lib path to your project :<br />
<br />
<pre><br />
INCLUDE_DIRECTORIES(<br />
${SDK_ROOT_PATH}/include<br />
)<br />
<br />
LINK_DIRECTORIES(<br />
${SDK_ROOT_PATH}/lib<br />
)<br />
</pre><br />
<br />
You can also read a registry key in the PATHS section of a FIND_LIBRARY, FIND_PATH, FIND_PROGRAM, or FIND_FILE command<br />
FIND_FILE(BOOT_DOT_INI boot.ini PATHS [HKEY_CURRENT_USER\\Environment;HOMEDRIVE])<br />
<br />
For other examples have a look in the CMake Modules folder :<br />
- FindJava.cmake<br />
- FindPythonLibs.cmake<br />
- ..<br />
<br />
=== How can I build my MSVC application with a static runtime? ===<br />
<br />
Here are three options you could employ to compile your MSVC application with /MT instead of /MD.<br />
<br />
==== Manual Replace ====<br />
<br />
You can rely on the user to manually modify CMAKE_C_FLAGS_DEBUG, CMAKE_C_FLAGS_RELEASE, CMAKE_CXX_FLAGS_DEBUG, CMAKE_CXX_FLAGS_RELEASE, etc. within the cache editor. After an initial configure of your software they would have to replace /MD entries with /MT.<br />
<br />
==== Make Override Files ====<br />
<br />
If you intend to build the entire source tree using /MT and you don't<br />
need this ever to be configurable via the CMake GUI, the best approach<br />
is to create an override file which initializes the starting cache<br />
values for the compile flags.<br />
<br />
First create a c_flag_overrides.cmake & cxx_flag_overrides.cmake file which<br />
contain something like this... (or whatever flags you wish to use per compiler).<br />
<br />
c_flag_overrides.cmake<br />
if(MSVC)<br />
set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")<br />
set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")<br />
set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")<br />
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")<br />
endif()<br />
<br />
cxx_flag_overrides.cmake<br />
if(MSVC)<br />
set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")<br />
set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")<br />
set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")<br />
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")<br />
endif()<br />
<br />
'''NOTE:''' These files are only evaluated on the first run of CMake so they can't be dependent on a CMake option() meant to be toggled from the GUI, for example. They could be dependent on a command line -D option or an environment variable if desired.<br />
<br />
Then enable them by setting the following variables prior to the project() command.<br />
<br />
set(CMAKE_USER_MAKE_RULES_OVERRIDE<br />
${CMAKE_CURRENT_SOURCE_DIR}/c_flag_overrides.cmake)<br />
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX<br />
${CMAKE_CURRENT_SOURCE_DIR}/cxx_flag_overrides.cmake)<br />
project(Bar)<br />
<br />
==== Dynamic Replace ====<br />
<br />
Alternatively, if you need dynamic control of /MT via some configure option you could use the following technique. Note: CMAKE_CXX_FLAGS_<FOO> is a directory level option, however. Also, this option has the downside of leaving /MD visible in the cache editor although it has no effect.<br />
<br />
foreach(flag_var<br />
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE<br />
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)<br />
if(${flag_var} MATCHES "/MD")<br />
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")<br />
endif(${flag_var} MATCHES "/MD")<br />
endforeach(flag_var)<br />
<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake/Testing_With_CTest&diff=23130CMake/Testing With CTest2010-05-05T14:54:17Z<p>Shdwjk: /* Running Individual Tests */ fixed typo (ommit -> omit) and incorrect command line switch for omitting tests (-R -> -E)</p>
<hr />
<div>==Introduction==<br />
<br />
CTest is a testing tool distributed as a part of CMake. It can be used to<br />
automate updating (using CVS for example), configuring, building, testing,<br />
performing memory checking, performing coverage, and submitting results to a [http://www.cdash.org CDash] or <br />
[http://public.kitware.com/Dart Dart] dashboard system. This tutorial will<br />
introduce the testing with CTest.<br />
<br />
==Simple Testing==<br />
<br />
The easiest way to create CTest input files is using CMake. It has support for<br />
adding tests in the project. To do that, insert the following command in the<br />
CMakeLists.txt file:<br />
<br />
ENABLE_TESTING()<br />
<br />
From that point on, you can add tests in the project using ADD_TEST command:<br />
<br />
ADD_TEST(SimpleTest ${EXECUTABLE_OUTPUT_PATH}/SimpleTest Hello)<br />
<br />
After building the project, you should be able to run CTest on the project.<br />
<br />
1. When using Makefile generators, such as Unix Makefiles, Borland Makefiles,<br />
or NMake Makefiles, the CTest can simply be run by running:<br />
<br />
make test<br />
<br />
2. On GUI development environments such as Visual Studio rebuilding the target<br />
RUN_TESTS will run tests on the project.<br />
<br />
For more information about ENABLE_TESTING and ADD_TEST, Look at<br />
[http://www.cmake.org/HTML/Documentation.html CMake Documentation] or run:<br />
<br />
cmake --help<br />
cmake --help-full<br />
cmake --help-command-list<br />
<br />
or<br />
<br />
cmake --help-command ENABLE_TESTING<br />
cmake --help-command ADD_TEST<br />
<br />
Internally "make test" or "RUN_TESTS" runs CTest. CTest is a program that actually performs the testing.<br />
The default behavior of CTest is to read "DartTestfile.txt" and runs tests that are in the file.<br />
<br />
==Dashboards==<br />
<br />
Testing Dashboards are web pages that display overview of the project testing.<br />
The testing clients update, configure, and build the project, as well as run<br />
some number of tests. The results of these operations are then submitted to the<br />
central server, which prepares the overview pages. Examples of Testing<br />
Dashboards are:<br />
[http://www.vtk.org/Testing/Dashboard/MostRecentResults-Nightly/Dashboard.html VTK],<br />
[http://www.itk.org/Testing/Dashboard/MostRecentResults-Nightly/Dashboard.html ITK], and<br />
[http://www.paraview.org/Testing/Dashboard/MostRecentResults-Nightly/Dashboard.html ParaView].<br />
More dashboards can be found on [http://www.cdash.org/CDash/index.php www.cdash.org] and [http://my.cdash.org my.cdash.org].<br />
<br />
There are three types of dashboard submissions. Experimental submission is<br />
submission of the current state of the project. It can be performed at any time<br />
and will appear on the dashboard on the next roll-up. Nightly submission is<br />
similar to experimental, except that the extra update will be performed using<br />
the last nightly time. This way all nightly dashboard submissions correspond to<br />
the state of the project at the same point in time. Finally, Continuous<br />
submissions are similar to Experimental submissions, except that an update is<br />
performed and if any files were modified, the full dashboard testing is<br />
performed.<br />
<br />
===Dashboard Preparation Using CMake===<br />
<br />
To enable submission to Dart Testing Dashboard, include the following in<br />
CMakeLists.txt:<br />
<br />
INCLUDE(CTest)<br />
<br />
When you include the '''CTest''' module, it will give you an option ''BUILD_TESTING'', which is enabled by default.<br />
In this case it will setup everything required for testing and also call ENABLE_TESTING(), so you don't have to do this in your cmake files.<br />
<br />
By default the settings will be to submit to [http://www.kitware.com Kitware's]<br />
[http://public.kitware.com/Public/Dashboard/MostRecentResults-Nightly/Dashboard.html Public Dashboard]. In order to submit<br />
to some other dashboard, create a file "CTestConfig.cmake" in the toplevel source directory and set the dashboard preferences.<br />
Instead of manually creating this file you can also download a project specific CTestConfig.cmake from the respective project page on CDash.<br />
<br />
'''CTestConfig.cmake''' file is not necessary if all you want is to submit to the [http://public.kitware.com/Public/Dashboard/MostRecentResults-Nightly/Dashboard.html '''Public Dashboard'''].<br />
<br />
Example of this file is:<br />
<br />
<pre><br />
# Dashboard is opened for submissions for a 24 hour period starting at<br />
# the specified NIGHLY_START_TIME. Time is specified in 24 hour format.<br />
SET (CTEST_NIGHTLY_START_TIME "23:00:00 EDT")<br />
<br />
# Dart server to submit results (used by client)<br />
IF(CTEST_DROP_METHOD MATCHES http)<br />
SET (CTEST_DROP_SITE "public.kitware.com")<br />
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")<br />
ELSE(CTEST_DROP_METHOD MATCHES http)<br />
SET (CTEST_DROP_SITE "public.kitware.com")<br />
SET (CTEST_DROP_LOCATION "/incoming")<br />
SET (CTEST_DROP_SITE_USER "ftpuser")<br />
SET (CTEST_DROP_SITE_PASSWORD "public")<br />
ENDIF(CTEST_DROP_METHOD MATCHES http)<br />
<br />
SET (CTEST_TRIGGER_SITE <br />
"http://${DROP_SITE}/cgi-bin/Submit-vtk-TestingResults.pl")<br />
</pre><br />
<br />
This will submit testing results to the<br />
[http://www.vtk.org/Testing/Dashboard/MostRecentResults-Nightly/Dashboard.html VTK dashboard].<br />
<br />
===CTest - Client for Dart Dashboard Server===<br />
<br />
CTest started as a simple tool to run some number of tests in the project, but<br />
has evolved in the full ''Dart'' compatible client. It can perform simple task<br />
of running a set of tests but it can also generate and submit Dart compatible<br />
Dashboard results. The good thing about CTest is that it is self sustained. All<br />
you need to do testing is CTest. Also, if you use CMake, you already have<br />
CTest. Detailed description of CTest option can be seen by running:<br />
<br />
ctest --help<br />
<br />
or<br />
<br />
ctest --help-full<br />
<br />
A simple way to submit Experimental dashboard is:<br />
<br />
ctest -D Experimental<br />
<br />
This will configure project, build project and check for any warnings or<br />
errors, run tests if any tests are specified, run coverage if any coverage<br />
files are specified, and submit to the specified ''Dart'' server. <br />
<br />
To convert existing Dart Client run from the project, find lines like:<br />
<br />
<pre><br />
cd ProjectNightlyBuildDirectory<br />
tclsh /location/of/Dart/Source/Client/DashboardManager.tcl DartConfiguration.tcl \<br />
Nightly Start Update Configure Build Test Submit<br />
</pre><br />
<br />
and convert them to CTest style:<br />
<br />
cd ProjectNightlyBuildDirectory<br />
ctest -D Nightly<br />
<br />
Dashboard can be also generated in stages. This way partial testing results can be submitted and seen before long operations are completed:<br />
<br />
cd ProjectNightlyBuildDirectory<br />
ctest -D NightlyStart<br />
ctest -D NightlyUpdate<br />
ctest -D NightlyConfigure<br />
ctest -D NightlyBuild<br />
ctest -D NightlySubmit<br />
ctest -D NightlyTest<br />
ctest -D NightlyCoverage<br />
ctest -D NightlySubmit<br />
ctest -D NightlyMemCheck<br />
ctest -D NightlySubmit<br />
<br />
To show what targets are available, run:<br />
<br />
ctest -D Help<br />
<br />
Actually, any word other than <tt>Help</tt> may be used.<br />
<br />
==Advanced CTest==<br />
<br />
CTest has several additional features that include:<br />
<br />
# FTP/HTTP/SCP/XMLRPC submission support<br />
# Run individual tests, subset of tests, exclude tests, etc.<br />
# Dynamic analysis using Valgrind or Purify<br />
# Customization of the testing by providing:<br />
#* Custom build error/warning regular expressions<br />
#* Ability to suppress some tests from being tested or memory checked and ability to run subset of tests<br />
#* Ability to run commands before and after tests are run<br />
# Ability to run whole testing process described in a single script<br />
<br />
===Submission Of Tests===<br />
<br />
CTest currently supports four methods directly and any other indirectly. Direct methods are HTTP, FTP, SCP and XML-RPC. Both HTTP and FTP methods require extra trigger mechanism, while SCP method relies on the fact that files are on the right place. To set the appropriate submission method, set CTEST_DROP_METHOD variable in CTestConfig.cmake. <br />
<br />
Example for HTTP submission would be:<br />
<pre><br />
SET (CTEST_DROP_METHOD http)<br />
SET (CTEST_DROP_SITE "public.kitware.com")<br />
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")<br />
SET (CTEST_TRIGGER_SITE <br />
"http://${DROP_SITE}/cgi-bin/Submit-CMake-TestingResults.pl")<br />
</pre><br />
where ''<nowiki>http://public.kitware.com/cgi-bin/HTTPUploadDartFile.cgi</nowiki>'' is a submit script and ''<nowiki>http://public.kitware.com/cgi-bin/Submit-CMake-TestingResults.pl</nowiki>'' is a trigger script.<br />
<br />
For FTP submission:<br />
<pre><br />
SET (CTEST_DROP_METHOD ftp) <br />
SET (CTEST_DROP_SITE "public.kitware.com")<br />
SET (CTEST_DROP_LOCATION "/incoming")<br />
SET (CTEST_DROP_SITE_USER "ftpuser")<br />
SET (CTEST_DROP_SITE_PASSWORD "public")<br />
SET (CTEST_TRIGGER_SITE <br />
"http://${DROP_SITE}/cgi-bin/Submit-CMake-TestingResults.pl")<br />
</pre><br />
where ''/incoming'' is a location on the FTP site ''public.kitware.com'' with user ''ftpuser'' and password ''public''. The trigger scrip is the same as with the http submit.<br />
<br />
For XML-RPC submission (Dart2):<br />
<pre><br />
SET (CTEST_DROP_METHOD xmlrpc) <br />
SET (CTEST_DROP_SITE "www.na-mic.org:8081")<br />
SET (CTEST_DROP_LOCATION "PublicDashboard")<br />
</pre><br />
where XML-RPC submission is on the server ''www.na-mic.org'' with the port ''8081''. The project name is ''PublicDashboard''. XML-RPC submission does not require the trigger script.<br />
<br />
===Running Individual Tests===<br />
<br />
CTest supports two different ways of specifying subset of tests to run.<br />
<br />
The first way is to specify the regular expression using -R and -E. -R specifies tests to be included and -E specifies the tests to be removed. For example, when running ctest in show-only mode, where no tests are run, we may see something like:<br />
<br />
Test project<br />
1/ 13 Testing PythonDataDesc <br />
2/ 13 Testing VTKTest <br />
3/ 13 Testing SystemInformation <br />
4/ 13 Testing TestVTKWriters <br />
5/ 13 Testing TestVTKPython <br />
6/ 13 Testing VTKPythonMultiGrid <br />
7/ 13 Testing IronImage <br />
8/ 13 Testing IronImageMagic <br />
9/ 13 Testing IronImageStrideMagic <br />
10/ 13 Testing IronRectMagic <br />
11/ 13 Testing IronRectStrideMagic <br />
12/ 13 Testing IronStructMagic <br />
13/ 13 Testing IronStructStrideMagic<br />
<br />
If we now run<br />
<br />
ctest -R Python<br />
<br />
We will only see tests that contain string ''Python'':<br />
<br />
Test project<br />
1/ 3 Testing PythonDataDesc <br />
2/ 3 Testing TestVTKPython <br />
3/ 3 Testing VTKPythonMultiGrid<br />
<br />
We can also omit tests using -E, for example:<br />
<br />
ctest -E Iron<br />
<br />
will produce:<br />
<br />
Test project<br />
1/ 6 Testing PythonDataDesc <br />
2/ 6 Testing VTKTest <br />
3/ 6 Testing SystemInformation <br />
4/ 6 Testing TestVTKWriters <br />
5/ 6 Testing TestVTKPython <br />
6/ 6 Testing VTKPythonMultiGrid<br />
<br />
Both -R and -E can be used at the same time.<br />
<br />
To determine what tests are avilable, you can always run:<br />
<br />
ctest -N<br />
<br />
which will display the list of tests but not actually run them.<br />
<br />
The second way of specifying tests is using explicit test number option -I:<br />
<br />
ctest -I 3,5<br />
<br />
will run tests:<br />
<br />
Test project<br />
Running tests: 3 4 5 <br />
3/ 13 Testing SystemInformation <br />
4/ 13 Testing TestVTKWriters <br />
5/ 13 Testing TestVTKPython<br />
<br />
We can also specify stride:<br />
<br />
ctest -I ,,3<br />
<br />
will run tests:<br />
<br />
Test project<br />
Running tests: 1 4 7 10 13 <br />
1/ 13 Testing PythonDataDesc <br />
4/ 13 Testing TestVTKWriters <br />
7/ 13 Testing IronImage <br />
10/ 13 Testing IronRectMagic <br />
13/ 13 Testing IronStructStrideMagic<br />
<br />
Or run individual tests:<br />
<br />
ctest -I 4,4,,4,7,13<br />
<br />
will run tests:<br />
<br />
Test project<br />
Running tests: 4 7 13<br />
4/ 13 Testing TestVTKWriters<br />
7/ 13 Testing IronImage<br />
13/ 13 Testing IronStructStrideMagic<br />
<br />
Make sure that the first and second argument are the index of the first test<br />
<br />
===Dynamic Analysis===<br />
<br />
Software development can be significantly hindered when memory leaks are introduced in the code. Both Purify and Valgrind can catch most of them. Setting up both is extremely easy.<br />
<br />
For example, to setup purify, all you have to do is to add:<br />
<br />
PURIFYCOMMAND:FILEPATH=c:/Progra~1/Rational/common/purify.exe<br />
<br />
To your cmake cache. Same way to setup valgrind, you add:<br />
<br />
MEMORYCHECK_COMMAND:FILEPATH=/home/kitware/local/bin/valgrind<br />
<br />
You can add additional options by specifying MEMORYCHECK_COMMAND_OPTIONS and MEMORYCHECK_SUPPRESSIONS_FILE.<br />
<br />
Make sure to run:<br />
<br />
ctest -D NightlyMemoryCheck<br />
<br />
or<br />
<br />
ctest -D NightlyStart<br />
ctest -D NightlyUpdate<br />
ctest -D NightlyConfigure<br />
ctest -D NightlyBuild<br />
ctest -D NightlyTest<br />
ctest -D NightlyMemCheck<br />
ctest -D NightlySubmit<br />
<br />
===Customizing CTest===<br />
<br />
CTest can be customized by providing CTestCustom.ctest or CTestCustom.cmake file in the ''build'' tree. If both<br />
files exist, CTestCustom.cmake will be preferred. If the CTestCustom.cmake/.ctest file is distributed <br />
with the sources of the project, e.g. CONFIGURE_FILE() can be used to put it in the build tree.<br />
The file may contain any SET command for any CMake variable, but the following ones will be used:<br />
<br />
{|border="1"<br />
|- bgcolor="#abcdef"<br />
! Variable !! Description<br />
|-<br />
| CTEST_CUSTOM_ERROR_MATCH || Regular expression for errors during build process<br />
|-<br />
| CTEST_CUSTOM_ERROR_EXCEPTION || Regular expression for error exceptions during build process<br />
|-<br />
| CTEST_CUSTOM_WARNING_MATCH || Regular expression for warnings during build process<br />
|-<br />
| CTEST_CUSTOM_WARNING_EXCEPTION || Regular expression for warning exception during build process<br />
|-<br />
| CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS || Maximum number of errors to display<br />
|-<br />
| CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS || Maximum number of warnings to display<br />
|- <br />
| CTEST_CUSTOM_TESTS_IGNORE || List of tests to ignore during the ''Test'' stage<br />
|-<br />
| CTEST_CUSTOM_MEMCHECK_IGNORE || List of tests to ignore during the ''MemCheck'' stage<br />
|-<br />
| CTEST_CUSTOM_PRE_TEST || Command to execute before any tests are run during ''Test'' stage<br />
|-<br />
| CTEST_CUSTOM_POST_TEST || Command to execute after any tests are run during ''Test'' stage<br />
|-<br />
| CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE || Maximum size of passed test output<br />
|-<br />
| CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE || Maximum size of failed test output<br />
|-<br />
| CTEST_CUSTOM_PRE_MEMCHECK || Command to execute before any tests are run during ''MemCheck'' stage<br />
|-<br />
| CTEST_CUSTOM_POST_MEMCHECK || Command to execute after any tests are run during ''MemCheck'' stage<br />
|-<br />
| CTEST_CUSTOM_COVERAGE_EXCLUDE || Regular expression for excluding files from coverage testing<br />
|}<br />
<br />
Example of CTestCustom.cmake file would be:<br />
<br />
<pre><br />
SET(CTEST_CUSTOM_MEMCHECK_IGNORE<br />
${CTEST_CUSTOM_MEMCHECK_IGNORE}<br />
TestSetGet<br />
otherPrint-ParaView<br />
Example-vtkLocal<br />
Example-vtkMy<br />
<br />
# These tests do not actually run any VTK code<br />
HeaderTesting-Common<br />
HeaderTesting-Filtering<br />
HeaderTesting-Graphics<br />
HeaderTesting-Imaging<br />
HeaderTesting-IO<br />
<br />
# this one runs python which then runs two<br />
# program so no memory checking there<br />
Sockets-image<br />
)<br />
<br />
SET(CTEST_CUSTOM_WARNING_MATCH<br />
${CTEST_CUSTOM_WARNING_MATCH}<br />
"{standard input}:[0-9][0-9]*: Warning: "<br />
)<br />
<br />
IF("@CMAKE_SYSTEM@" MATCHES "OSF")<br />
SET(CTEST_CUSTOM_WARNING_EXCEPTION<br />
${CTEST_CUSTOM_WARNING_EXCEPTION}<br />
"XdmfDOM"<br />
"XdmfExpr"<br />
"vtkKWApplication"<br />
"vtkKWObject"<br />
)<br />
ENDIF("@CMAKE_SYSTEM@" MATCHES "OSF")<br />
<br />
SET(CTEST_CUSTOM_WARNING_EXCEPTION<br />
${CTEST_CUSTOM_WARNING_EXCEPTION}<br />
"tcl8.4.5/[^/]+/../[^/]+/[^.]+.c[:\"]"<br />
"tk8.4.5/[^/]+/[^/]+.c[:\"]"<br />
"VTK/Utilities/vtktiff/"<br />
"Utilities/vtkmpeg2/"<br />
"Utilities/hdf5/"<br />
"xtree.[0-9]+. : warning C4702: unreachable code"<br />
"warning LNK4221"<br />
"variable .var_args[2]*. is used before its value is set"<br />
)<br />
</pre><br />
<br />
===CTest Scripting===<br />
<br />
For an example of how CTest can run the whole testing process described in a<br />
single script, look at how CMake dashboards are created with the<br />
[http://www.cmake.org/HTML/Testing.html CTest -S script].<br />
<br />
==Conclusion==<br />
<br />
Performing tests on the project is a great software development practice and can result in significant improvement on the quality of the project. CTest provides a simple and reliable way of performing nightly, continuous, and experimental tests.<br />
<br />
More information about CTest can be found in<br />
[http://www.kitware.com/products/cmakebook.html Mastering CMake].<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake:Component_Install_With_CPack&diff=23087CMake:Component Install With CPack2010-05-04T17:40:03Z<p>Shdwjk: /* Building Binary Installers with CPack */ Changed out [here] note to point to CMake:CPackConfiguration</p>
<hr />
<div>= Component-Based Installers with CPack =<br />
<br />
CPack builds binary installers for a variety of platforms using<br />
CMake's existing installation infrastructure. Augmented by a set of<br />
CPack-specific macros, a program built with CMake can easily be<br />
distributed via a user-friendly installer.<br />
<br />
By default, CPack's installers consider all of the files installed by<br />
a project as a single, monolithic unit: either the whole set of files<br />
is installed, or none of the files are installed. However, with many<br />
projects it makes sense for the installation to be subdivided into<br />
distinct, user-selectable components: some users may want to install<br />
only the comand-line tools for a project, while other users might want<br />
the GUI or the header files.<br />
<br />
This document describes how to configure CPack to generate<br />
component-based installers that allow users to select the set of<br />
project components that they wish to install. In this document, we<br />
will develop a simple installer for a simple library that has three<br />
components: a library binary, a sample application, and a C++ header<br />
file. When we have finished, these resulting installers will looks<br />
like the customizable installers below, shown for Mac OS X and<br />
Windows:<br />
<br />
[[Image:CPackComponentsFinalWindows.JPG]] [[Image:CPackComponentsFinalMac.jpg]]<br />
<br />
== Prerequisites ==<br />
<br />
To begin, you should be able to build graphical installers using CPack<br />
either on Windows (using the NullSoft Installation System, NSIS) or<br />
Mac OS X (using PackageMaker). Also, as of the time of this writing,<br />
the extensions to CPack required to build component-based installers are only available via CMake CVS.<br />
<br />
As our primary example, we will use a simple library called "MyLib"<br />
that builds a single library (`mylib`) and an application based on<br />
that library (`mylibapp`). The file [[Image:ComponentExampleStart.zip]] contains<br />
the skeleton of such a library, with the following build and<br />
installation commands in `CMakeLists.txt`:<br />
<br />
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)<br />
project(MyLib)<br />
<br />
add_library(mylib mylib.cpp)<br />
<br />
add_executable(mylibapp mylibapp.cpp)<br />
target_link_libraries(mylibapp mylib)<br />
<br />
install(TARGETS mylib <br />
ARCHIVE<br />
DESTINATION lib)<br />
install(TARGETS mylibapp<br />
RUNTIME<br />
DESTINATION bin)<br />
install(FILES mylib.h<br />
DESTINATION include)<br />
<br />
You should be able to configure, build, and (optionally) install this<br />
project using CMake with its library, application, and header file.<br />
<br />
== Building Binary Installers with CPack ==<br />
<br />
To build binary installers with CPack, first add the following to the<br />
end of `CMakeLists.txt`:<br />
<br />
set(CPACK_PACKAGE_NAME "MyLib")<br />
set(CPACK_PACKAGE_VENDOR "CMake.org")<br />
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example")<br />
set(CPACK_PACKAGE_VERSION "1.0.0")<br />
set(CPACK_PACKAGE_VERSION_MAJOR "1")<br />
set(CPACK_PACKAGE_VERSION_MINOR "0")<br />
set(CPACK_PACKAGE_VERSION_PATCH "0")<br />
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")<br />
<br />
# This must always be last!<br />
include(CPack)<br />
<br />
More information about CPack and its configuration macros can be found<br />
[[CMake:CPackConfiguration|here]], but this boilerplate suffices to enable the packaging target<br />
in a CMake build. From here, makefile users can invove `make package`<br />
to build a binary installer (e.g., on Mac OS X) and Visual Studio<br />
users can build the PACKAGE target.<br />
<br />
Throughout this tutorial, we will be setting more `CPACK_` macros in<br />
`CMakeLists.txt` to communicate with CPack. It is very important that<br />
the SET commands for these macros come before the include of the<br />
`CPack` module!<br />
<br />
== Identifying Components ==<br />
<br />
The first step in building a component-based installation is to<br />
identify the set of installable components. In our example library, we<br />
have decided on three components: the library binary, the application,<br />
and the header file. This decision is arbitrary and project-specific,<br />
but be sure to identify the components that correspond to units of<br />
functionality important to your user rather than basing the components<br />
on the internal structure of your program.<br />
<br />
For each of these components, we need to identify which installed<br />
files are part of the component. For each INSTALL command in<br />
`CMakeLists.txt`, add an appropriate COMPONENT argument stating which<br />
component the installed files will be associated with:<br />
<br />
install(TARGETS mylib <br />
ARCHIVE<br />
DESTINATION lib<br />
COMPONENT libraries)<br />
install(TARGETS mylibapp<br />
RUNTIME<br />
DESTINATION bin<br />
COMPONENT applications)<br />
install(FILES mylib.h<br />
DESTINATION include<br />
COMPONENT headers)<br />
<br />
Note that the COMPONENT argument to the INSTALL command is not new; it<br />
has been a part of CMake's INSTALL command to allow installation of<br />
only part of a project. If you are using any of the older installation<br />
commands (INSTALL_TARGETS, INSTALL_FILES , etc.), you will need to<br />
convert them to INSTALL commands to add the COMPONENT argument.<br />
<br />
Finally, notify CPack of the names of all of the components in your<br />
project by setting the CPACK_COMPONENTS_ALL variables:<br />
<br />
set(CPACK_COMPONENTS_ALL applications libraries headers)<br />
<br />
At this point, you can build a component-based installer with CPack<br />
that will allow one to independently install the applications,<br />
libraries, and headers of MyLib.<br />
<br />
[[Image:CPackComponentBasicWindows.JPG]][[Image:CPackComponentBasicMac.jpg]]<br />
<br />
== Component Descriptions ==<br />
<br />
If you have built a binary installer at this point, you may have noted<br />
that the names of the actual components in the installer are not very<br />
descriptive: they just say "applications", "libraries", or "headers",<br />
as in the component names. We can improve on these names by setting<br />
several additional CPack variables:<br />
<br />
set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "MyLib Application")<br />
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")<br />
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")<br />
<br />
Any macro prefixed with CPACK_COMPONENT_${COMPNAME}, where ${COMPNAME}<br />
is the uppercase name of a component, is used to set a particular<br />
property of that component in the installer. Here, we set the<br />
DISPLAY_NAME property of each of our components, so that we get<br />
human-readable names. These names will be listed in the selection box<br />
rather than the internal component names "applications", "libraries",<br />
"headers". <br />
<br />
[[Image:CPackComponentNamesWindows.JPG]] [[Image:CPackComponentNamesMac.jpg]]<br />
<br />
There are several other properties associated with components,<br />
including the ability to make a component hidden, required, or<br />
disabled by default, to provide additional descriptive information,<br />
etc. We will encounter some of these other properties later; see the<br />
macro reference for a complete list.<br />
<br />
Of particular note is the DESCRIPTION property, which provides some<br />
descriptive text for the component. This descriptive text will show up<br />
in a separate "description" box in the installer, and will be updated<br />
either when the user's mouse hovers over the name of the corresponding<br />
component (Windows) or when the user clicks on a component (Mac OS<br />
X). Here, we add a description for each of our components:<br />
<br />
set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION <br />
"An extremely useful application that makes use of MyLib")<br />
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION<br />
"Static libraries used to build programs with MyLib")<br />
set(CPACK_COMPONENT_HEADERS_DESCRIPTION<br />
"C/C++ header files for use with MyLib")<br />
<br />
Generally, descriptions should provide enough information for the user<br />
to make a decision whether to include the component, but should not<br />
themselves be more than a few lines long (because the "Description"<br />
box in the installers tends to be small).<br />
<br />
[[Image:CPackComponentDescWindows.JPG]][[Image:CPackComponentDescMac.jpg]]<br />
<br />
== Intercomponent Dependencies ==<br />
<br />
With most projects, the various components are not completely<br />
independent. For example, an application component may depend on the<br />
shared libraries in another component to execute properly, such that<br />
installing the application component without the corresponding shared<br />
libraries would result in an unusable installation. CPack allows you<br />
to express the dependencies between components, so that a component<br />
will only be installed if all of the other components it depends on<br />
are also installed. <br />
<br />
To illustrate component dependencies, we will place a simple<br />
restriction on our component-based installer. Since we do not provide<br />
source code in our installer, the C++ header files we distribute can<br />
only actually be used if the user also installs the library binary to<br />
link her program against. Thus, the "headers" component depends on the<br />
availability of the "libraries" component. We can express this notion<br />
by setting the DEPENDS property for the HEADERS component as such:<br />
<br />
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)<br />
<br />
The DEPENDS property for a component is actually at list, and as such a<br />
component can depend on several other components. By expressing all of<br />
the component dependencies in this manner, you can ensure that users<br />
will not be able to select an incomplete set of components at<br />
installation time.<br />
<br />
== Grouping Components ==<br />
<br />
When the number of components in your project grows large, you may<br />
need to provide additional organization for the list of components. To<br />
help with this organization, CPack includes the notion of component<br />
groups. A component group is, simply, a way to provide a name for a<br />
group of related components. Within the user interface, a component<br />
group has its own name, and underneath that group come all of the<br />
names of the components within the group. Users will have the option<br />
to (de-)select installation of all components in the group with a<br />
single click, or expand the group to select individual components.<br />
<br />
We will expand our example by categorizing its three components,<br />
"applications", "libraries", and "headers", into "Runtime" and<br />
"Development" groups. We place a component into a group by setting the<br />
GROUP property of the component to the name of the group as follows:<br />
<br />
set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")<br />
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")<br />
set(CPACK_COMPONENT_HEADERS_GROUP "Development")<br />
<br />
Like components, component groups have various properties that can be<br />
customized, including the DISPLAY_NAME and DESCRIPTION. To customization<br />
a component group, set the appropriate CPack macro with the prefix<br />
CPACK_COMPONENT_GROUP_${GROUPNAME}, where ${GROUPNAME} is the<br />
uppercase name of the group to modify. For example, the following code<br />
adds a description to the "Development" group:<br />
<br />
set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION<br />
"All of the tools you'll ever need to develop software")<br />
<br />
Once you have customized the component groups to your liking, rebuild<br />
the binary installer to see the new organization: the MyLib<br />
application will show up under the new "Runtime" group, while the<br />
MyLib library and C++ header will show up under the new "Development"<br />
group. One can easily turn on/off all of the components within a group<br />
using the installer GUI. Some additional customizations of component<br />
groups are possible; please see the macro reference for a complete<br />
list.<br />
<br />
[[Image:CPackComponentGroupsWindows.JPG]][[Image:CPackComponentGroupsMac.jpg]]<br />
<br />
== Installation Types (NSIS Only) ==<br />
<br />
When a project contains a large number of components, it is common for<br />
a Windows installer to provide pre-selected sets of components based<br />
on specific user needs. For example, a user wanting to develop<br />
software against a library will want one set of components, while an<br />
end user might use an entirely different set. CPack supports this<br />
notion of pre-selected component sets via installation types. An<br />
installation type is, simply, a set of components. When the user<br />
selects an installation type, exactly that set of components is<br />
selected---then the user is permitted to further customize the<br />
installation as desired.<br />
<br />
For our simple example, we will create only two installation types: a<br />
"Full" installation type, which contains all of the components, and a<br />
"Developer" installation type, which includes only the libraries and<br />
headers. To do so, we first tell CPack which installation types we're<br />
using:<br />
<br />
set(CPACK_ALL_INSTALL_TYPES Full Developer)<br />
<br />
Like components and component groups, installation types have some<br />
properties (e.g., DISPLAY_NAME), which can be set via variables with<br />
prefix CPACK_INSTALL_TYPE_${INSTNAME}, where ${INSTNAME} is the<br />
uppercase name of the installation type. See the macro reference for<br />
additional information.<br />
<br />
Next, we set the INSTALL_TYPES property of each component to state<br />
which installation types will include that component:<br />
<br />
set(CPACK_COMPONENT_LIBRARIES_INSTALL_TYPES Developer Full)<br />
set(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)<br />
set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full)<br />
<br />
Components can be in any number of installation types. If you now<br />
rebuild the Windows installer, the components page will contain a<br />
combo box that allows you to select the installation type and<br />
therefore its corresponding set of components.<br />
<br />
[[Image:CPackComponentsFinalWindows.JPG]]<br />
<br />
== Next Steps ==<br />
<br />
From here, you should be able to turn your existing CPack-generated<br />
binary installers into component-based installers to provide your<br />
users with more-flexible installation options. The complete example<br />
constructed by this tutorial is available as [[Image:ComponentExample.zip]]. For<br />
a more advanced example of a component-based installer build with<br />
CPack, please visit the Boost-CMake project.<br />
<br />
= Macro Reference =<br />
<br />
In this reference, ${COMPNAME} refers to a component, ${GROUPNAME}<br />
refers to a component group, and ${INSTNAME} refers to an installation<br />
type, all of which are uppercase.<br />
<br />
{|<br />
|- bgcolor="#abcdef"<br />
! Variable Name || Description<br />
|-<br />
| CPACK_COMPONENTS_ALL || A list containing the names of all components that should be installed. The presence of this macro indicates that CPack should build a component-based installer. Files associated with any components not listed here or any installation commands not associated with any component will not be installed.<br />
|- <br />
|CPACK_COMPONENT_${COMPNAME}_DISPLAY_NAME || The displayed name of the component ${COMPNAME}, used in graphical installers to display the component name. This value can be any string.<br />
|-<br />
|CPACK_COMPONENT_${COMPNAME}_DESCRIPTION || An extended description of the component ${COMPNAME}, used in graphical installers to give the user additional information about the component. Descriptions can span multiple lines using "\n" as the line separator.<br />
|-<br />
|CPACK_COMPONENT_${COMPNAME}_HIDDEN || Flag that indicates that this component will be hidden in the graphical installer, and therefore cannot be selected or installed. Only available with NSIS.<br />
|-<br />
|CPACK_COMPONENT_${COMPNAME}_REQUIRED || Flag that indicates that this component is required, and therefore will always be installed. It will be visible in the graphical installer, but it cannot be unselected.<br />
|-<br />
|CPACK_COMPONENT_${COMPNAME}_DISABLED || Flag that indicates that this component should be disabled (unselected) by default. The user is free to select this component for installation.<br />
|-<br />
| CPACK_COMPONENT_${COMPNAME}_DEPENDS || Lists the components on which this component depends. If this component is selected, then each of the components listed must also be selected.<br />
|-<br />
| CPACK_COMPONENT_${COMPNAME}_GROUP || Names the component group of which this component is a part. If not provided, the component will be a standalone component, not part of any component group.<br />
|-<br />
| CPACK_COMPONENT_${COMPNAME}_INSTALL_TYPES || Lists the installation types of which this component is a part. When one of these installations types is selected, this component will automatically be selected. Only available with NSIS.<br />
|-<br />
|CPACK_COMPONENT_GROUP_${GROUPNAME}_DISPLAY_NAME || The displayed name of the component group ${GROUPNAME}, used in graphical installers to display the component group name. This value can be any string.<br />
|-<br />
| CPACK_COMPONENT_GROUP_${GROUPNAME}_DESCRIPTION || An extended description of the component group ${GROUPNAME}, used in graphical installers to give the user additional information about the components contained within this group. Descriptions can span multiple lines using "\n" as the line separator.<br />
|-<br />
| CPACK_COMPONENT_GROUP_${GROUPNAME}_BOLD_TITLE || Flag indicating whether the group title should be in bold. Only available with NSIS.<br />
|-<br />
| CPACK_COMPONENT_GROUP_${GROUPNAME}_EXPANDED || Flag indicating whether the group should start out "expanded", showing its components. Otherwise only the group name itself will be shown until the user clicks on the group. Only available with NSIS.<br />
|-<br />
| CPACK_INSTALL_TYPE_${INSTNAME}_DISPLAY_NAME || The displayed name of the installation type. This value can be any string.<br />
|}<br />
<br />
<br />
<br />
= Ideas for Future Development =<br />
* Add support for other binary installer generators, such as RPM and Deb. The installer will then create a set of RPM or Deb files, with appropriate dependencies. A key question here is granularity: RPMs and Debs tend to have a coarser granularity than graphical installers.<br />
* CPack RPM generator component support: This is true that RPM has coarser granularity, however one may build 1 RPM by component and embbed appropriate dependencies between each generated RPM. For building several RPM at once you may either generate a spec file for each component or generate a single spec file which may contain sub-packages [[http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html]]. --[[User:Erk|Erk]] 04:36, 28 August 2008 (EDT)<br />
<br />
* Graphviz output of components and their dependencies?<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake:CPackWin32NewbiesChecklist&diff=23080CMake:CPackWin32NewbiesChecklist2010-05-04T16:21:49Z<p>Shdwjk: fixed typo: "any ways" -> "anyway"</p>
<hr />
<div>I just wanted to jot down some notes that I took during my "learning curve" of CPack on Windows XP.<br><br />
<br />
<br>First, what would seem like obvious things to do but worth mentioning.<br />
<br />
= Pre-requisite Software =<br />
# Download and install the NSIS installer from [http://nsis.sourceforge.net/Download NSIS Downloads page]<br />
# Download and install a Zip package. I used 7zip from [http://www.7-zip.org/download.html 7Zip Downloads page]<br />
::<b>After you install 7zip (or what ever package you want for zip compression) be sure to add that program to the "PATH" variable for windows.<br />
::Instructions for that can be found at Microsoft's web site [http://support.microsoft.com/kb/310519 How To Manage Environment Variables in Windows XP]</b><br />
<br />
Now you should be ready to start writing some CPack Code.<br />
<br />
= Bumps in the Road =<br />
Early on I had some trouble getting some support libraries to show up in the installer. This was because of a <b>bug</b> in my own cmake code which I thought might be good to show here so that others do not make the same mistake.<br />
<br />
<B> WRONG CMAKE CODE </B><br />
INSTALL(FILES MyLibrary.dll <br />
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin <br />
CONFIGURATIONS Debug <br />
COMPONENT Runtime)<br />
<br />
Note the <tt>${CMAKE_INSTALL_PREFIX}</tt> in the Destination property. Having this was a bug and caused all sorts of problems. Basically CPack runs the "install" command first and then does the packaging. By using an Absolute path in the "Destination" property CMake was dutifully copying the files into the installation directory and NOT the staging area for CPack. OOPS. Here is the corrected code.<br />
<br />
<B> CORRECT CMAKE CODE </B><br />
INSTALL(FILES MyLibrary.dll <br />
DESTINATION bin <br />
CONFIGURATIONS Debug <br />
COMPONENT Runtime)<br />
Also note that I am using a "CONFIGURATION" property because I actually name outputs based on the build configuration. Both the "CONFIGURATION" and the "COMPONENT" are optional. Using the COMPONENT Property will allow you to eventually do component based installs. See [[CMake:Component Install With CPack]] for more information.<br />
<br />
There are ways to use Absolute file paths but there seems to be lots of issues with this approach and the approach is not supported on NSIS anyway. For more information on the subject take a look [http://www.cmake.org/pipermail/cmake/2008-May/021638.html At this post] on the CMake mailing list.</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=User:Shdwjk&diff=16432User:Shdwjk2009-09-04T18:23:27Z<p>Shdwjk: New page: Hi. I'm new to CMake, but I love it already. I work as a C++ programmer at Thomson Reuters. I'm trying to add things to the wiki as I find resources helpful, and make small grammatica...</p>
<hr />
<div>Hi. <br />
<br />
I'm new to CMake, but I love it already. I work as a C++ programmer at Thomson Reuters.<br />
<br />
I'm trying to add things to the wiki as I find resources helpful, and make small grammatical corrections as I can. I hope that all my additions are acceptable, but please let me know if I need to adjust my habits.<br />
<br />
--aaron</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake&diff=16431CMake2009-09-04T18:20:59Z<p>Shdwjk: /* Primary Resources - Look here first! */ -- Added link to Screencasts</p>
<hr />
<div>http://www.cmake.org/cmake/img/CMake-logo-download.jpg<br />
<br />
<!-- documentation manual man information help tutorial --><br />
Welcome to CMake, the cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. CMake is quite sophisticated: it is possible to support complex environments requiring system configuration, pre-processor generation, code generation, and template instantiation.<br />
<br />
You will find here not only documentation for CMake, but also for CPack and CTest.<br />
<br />
=CMake=<br />
<br />
==Primary Resources - Look here first! ==<br />
* Where can I [http://www.cmake.org/HTML/Download.html download CMake]?<br />
* [http://www.cmake.org/HTML/Documentation.html CMake Documentation]<br />
* [[CMake Useful Variables|Useful CMake Variables]]<br />
* [[CMake FAQ| FAQ (Frequently asked questions)]]<br />
* [http://www.cmake.org/mailman/listinfo/cmake CMake Mailing List] (for searchable archives see [[CMake_FAQ#Where_can_I_find_searchable_CMake_Mailing_Archives | CMake FAQ ]])<br />
* [[CMake_2.6_Notes|CMake 2.6 Notes]]<br />
* ''Getting Started With CMake'' Screencasts @[http://playcontrol.net/ewing/screencasts/getting_started_with_cmake_.html PlayControl.net]<br />
<br />
==Development Topics==<br />
* [[CMake Cross Compiling| Cross compiling]]<br />
* [[CMake RPATH handling|RPATH handling]]<br />
* [[CMake/Assembler|Assembler Support]]<br />
* [[CMake Editors Support|Editors/IDEs with CMake syntax support]]<br />
* [[CMake Generator Specific Information|Docs for Specific Project Generators]] (Eclipse, KDevelop3, CodeBlocks, Makefile)<br />
* [[CMake User Contributed Macros| Contributed macros]]<br />
* [[CMake:Module Maintainers|Module Maintainers]]<br />
* [[CMake Platform Dependent Issues|Platform Dependent Information]]<br />
* [[CMake Released Versions|Documentation for previous releases]]<br />
<br />
==Tutorials==<br />
<br />
===Basic Introductions===<br />
* [http://www.cmake.org/HTML/Examples.html A Simple CMake Example]<br />
* [http://www.linuxjournal.com/article/6700 Cross-Platform Software Development Using CMake]<br />
* [http://clubjuggler.livejournal.com/138364.html CMake: The Cross Platform Build System]<br />
* [http://www.elpauer.org/stuff/learning_cmake.pdf "Learning CMake"] - Slides of a CMake workshop, including CPack, CTest and CDash<br />
* Syntax of the CMake language<br />
** [http://www.cmake.org/HTML/syntax.html A quick introduction to CMake syntax]<br />
** [[CMake/Language Syntax | Language syntax]] (wiki page)<br />
** [[CMake:VariablesListsStrings| On variables, lists, strings, maps, regexps, etc.]]<br />
<br />
===Specific Topics===<br />
* [[CMake:MatlabMex | How to use CMake to create Matlab MEX files]] <br> Describes how to use CMake when developing Matlab Executable (MEX) files for use with The Mathworks Matlab scripting language.<br />
* [[CMake:Eclipse_UNIX_Tutorial | How to use CMake with Eclipse CDT]] <br> Describes how to use CMake with Eclipse CDT.<br />
* [[CMake HowToDoPlatformChecks| How to write platform checks with CMake]]<br>Describes how to implement platform or configure checks with CMake.<br />
<br />
* [[CMake:How_To_Find_Libraries | How to find libraries]] <br>Describes how to use external libraries in a CMake project and how to write your own find modules for libraries that don't already have one.<br />
<br />
* [[CMake HowToFindInstalledSoftware| How to find installed software with CMake]]<br>Describes how to search for and then use software packages with CMake. (should be merged with the page above)<br />
<br />
* [[CMake:HowToUseExistingOSXFrameworks | How to find and use existing frameworks on OS X]]<br> A quick example to help OS X users find frameworks automatically.<br />
<br />
* [[CMake:How To Build Qt4 Software | How to build Qt4 software with CMake]]<br />
<br />
* [[CMake:How To Build KDE4 Software | How to build KDE4 software with CMake]]<br />
<br />
* [[CMake:How To Process Lots Of Input Files | How to process lots of input files with a processor built by CMake]]<br />
<br />
* [http://qtnode.net/wiki?title=Qt_with_cmake Qt with CMake] <br>Explains how to use CMake to build software with Qt4, Qt3 and KDE3.<br />
<br />
* [http://www.wxwidgets.org/wiki/index.php/CMake How to use CMake for building software with wxWidgets ]<br />
<br />
* [http://www.linuxdevices.com/articles/AT6762290643.html Building eCos applications with CMake]<br />
<br />
* [[CMakeForFLTK| Using CMake to build an FLTK application]]<br />
<br />
* [[BuildingWinDLL| How to export symbols from a Windows DLL for the non-Windows Developer]]<br />
<br />
* [[VSConfigSpecificSettings| Configuration Specific Settings for Visual Studio Generated Project Files]]<br />
<br />
* [[BundleUtilitiesExample| How to use the 'BundleUtilities' to deploy your OS X Application. Example uses Qt 4.]]<br />
<br />
* [[CMakeForFortranExample|How to write a simple CMakeLists.txt for Fortran code]]<br />
<br />
* [[CMakeEmulateMakeCheck|How to emulate GNU Autotools 'make check']]<br />
<br />
==Converters from other buildsystems to CMake==<br />
<br />
All converters listed here are not "complete", i.e. the generated CMake files are not 100% finished, in all cases some work is left for the developer.<br />
<br />
====automake/autotools/autoconf====<br />
* [http://websvn.kde.org/trunk/KDE/kdesdk/cmake/scripts/ am2cmake (requires Ruby) ] Converts automake/autotools/libtool based projects to CMake, specialized in converting from KDE 3 to KDE 4, should also work for others. This one has been used for converting the KDE buildsystem to CMake.<br />
<br />
* [http://emanuelgreisen.dk/stuff/kdevelop_am2cmake.php.tgz Alternative Automake2CMake (requires PHP)] Converts KDevelop projects that use automake to CMake.<br />
<br />
* [[GccXmlAutoConfHints|Converting autoconf tests]]<br />
<br />
====qmake====<br />
* [[CMake:ConvertFromQmake | qmake converter (requires Ruby)]] Converts projects that use Qt's qmake.<br />
<br />
====Visual Studio====<br />
* [http://www.eskilson.se/vcproj2cmake.rb vcproj2cmake.rb (requires Ruby)] Creates CMakeLists.txt files by extracting info from Visual Studio project files.<br />
* Updated version here [http://dgwarp.hd.free.fr/vcproj2cmake.rb vcproj2cmake.rb], see:[[User_talk:Dweeves]] for details<br />
<br />
====Basic CMakeLists.txt from-scratch-generator====<br />
* [http://websvn.kde.org/trunk/KDE/kdesdk/cmake/scripts/ gencmake (requires Ruby) ] Creates basic CMakeLists.txt files from looking at the existing files.<br />
<br />
<br />
==Success Stories==<br />
<br />
* What are some [[CMake Projects|projects using CMake]]?<br />
* [[CMake:Articles|Articles about CMake]]<br />
* [[Really Cool CMake Features]]<br />
<br />
<br />
==More Topics==<br />
<br />
* [[CMake Fortran Issues|Fortran Issues]]<br />
* [[CMake:For CMake Hackers|For CMake Hackers]]<br />
* [[CMake:Experiments With Lua|Experiments With Lua]]<br />
* [[CMake Performance Tips|Performance Tips]]<br />
* [[CMake:Install Commands| Replacing deprecated INSTALL_FILES, INSTALL_PROGRAMS and INSTALL_TARGETS commands]]<br />
* [[CMake:GNU style example | GNU style directory layout with CMake]]<br />
* [[CMake:OpenTasks| CMake TODO]]<br />
* [[CMake:CreateQtAssistantDocs| Creating Qt Assistant Docs]]<br />
* [[CMake:Static libraries| Writing FindXXX.cmake modules that work with static libraries]]<br />
* [[CMake:Multiple versions| Writing FindXXX.cmake modules that work when multiple versions of packages are installed]]<br />
* [[CMake:Improving Find* Modules ]]<br />
* [[/C Plugins for Loadable Commands/]]<br>For anyone who wonders what the <tt>load_command</tt> command is for.<br />
* [[PC-Lint]] support for CMake<br />
<br />
=CTest=<br />
<br />
===Tutorials===<br />
* [[CMake Testing With CTest|Testing With CTest]]<br>Introduces to testing with CTest, submitting dashboards, and using CMake to add tests to the test system.<br />
<br />
* [[CMake Scripting Of CTest|CTest Scripting]]<br>Describes the scripting with CTest which can significantly simplify and automate testing and submitting dashboards.<br />
<br />
* [[CMake Generating Testing Files|Generating Input Files For CTest]]<br>Describe more in details the concepts behind testing with CTest and also explans how to use CTest without using CMake.<br />
<br />
===More Information===<br />
* [[CTest:Submission Issues|Configuring CTest Submission Methods]]<br />
* [[CTest:Nightly, Experimental, Continuous|CTest Nightly, Experimental, Continuous, ...]]<br />
* [[CTest:Coverage]]<br />
* [[Media:CTest Running Modes.pdf]]<br />
* [[CTest:FAQ|CTest Frequently asked questions]]<br />
<br />
===More Topics===<br />
* [[CTest:OpenTasks| CTest TODO]]<br />
<br />
=CPack=<br />
===Tutorials===<br />
* [[CMake:Packaging With CPack|Packaging with CPack]]<br>Introduction to CPack, installing and packaging of software.<br />
* [[CMake:CPackConfiguration|CPack Variables]]<br><br />
* [[CMake:CPackPackageGenerators|Supported package formats]]<br><br />
* [[CMake:CPackWin32NewbiesChecklist|CPack Win32 Newbie Checklist]] <br><br />
* [[CMake:Component_Install_With_CPack|Component Install With CPack]] <br><br />
<br />
===More Information===<br />
* [[CPack:Generator Information|CPack Generator Information]]<br />
<br />
==CDash==<br />
* [http://public.kitware.com/Wiki/CDash CDash Wiki].<br />
* [http://public.kitware.com/Wiki/CDash:FAQ CDash FAQ].<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake:How_To_Write_Platform_Checks&diff=16288CMake:How To Write Platform Checks2009-08-18T18:58:25Z<p>Shdwjk: corrected so => to</p>
<hr />
<div>If you want to write software which compiles and runs on different operating systems, you have to take care for the special properties of the different platforms. On different operating systems there are subtle differences, e.g. on FreeBSD you should not use malloc.h, while it is perfectly ok to use it on Linux. These differences are typically handled by providing a header file which contains a bunch of define-statements according to the platform properties, usually named config.h:<br />
<br />
<pre><br />
#define HAVE_MALLOC_H 1<br />
/* #undef HAVE_SYS_MNTTAB_H 1 */<br />
/* #undef HAVE_SYS_MNTENT_H 1 */<br />
#define HAVE_SYS_MOUNT_H 1<br />
</pre><br />
<br />
This header file is then included in the source files and handled appropriately:<br />
<br />
foo.c:<br />
<pre><br />
#include "config.h"<br />
<br />
#ifdef HAVE_MALLOC_H<br />
#include <malloc.h><br />
#else<br />
#include <stdlib.h><br />
#endif<br />
<br />
void do_something() <br />
{<br />
void *buf=malloc(1024);<br />
...<br />
}<br />
</pre><br />
<br />
The contents of config.h depend on the platform where the sources are compiled, so there needs to be a way to generate this header file before the actual compilation process starts. If you are using autotools-based software, you probably know the <tt>./configure</tt> step, which has to be executed before starting <tt>make</tt>. The <tt>./configure</tt> script does some system introspection and generates from the gathered information the <tt>config.h</tt> header file.<br />
CMake is able to do the same, and I'll show you how to do it.<br />
<br />
Additionally to the builtin commands, cmake offers more commands implemented by cmake script files, called modules. These files are located in the cmake module directory, on UNIX systems is this by default <tt>/usr/local/share/CMake/Modules </tt>.<br />
<br />
To use commands from these modules, they have to be included in the CMakeLists.txt. CMake comes with several modules for checking the system, they all follow the same style, as an example here CHECK_INCLUDE_FILES:<br />
<br />
<pre><br />
INCLUDE (CheckIncludeFiles)<br />
# usage: CHECK_INCLUDE_FILES (<header> <RESULT_VARIABLE> )<br />
<br />
CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)<br />
CHECK_INCLUDE_FILES ("sys/param.h;sys/mount.h" HAVE_SYS_MOUNT_H)<br />
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)<br />
</pre><br />
<br />
The CMake module CheckIncludeFiles offers the command CHECK_INCLUDE_FILES(). The first argument to this command is the header you want to check for. The second argument is the variable which will contain the result. If the given header was found, it is set to 1, otherwise it is empty.<br />
If another header is required to use the header you are looking for, you have to list the header files separated by semicolons, as you can see above. To see what CHECK_INCLUDE_FILES() exactly does, have a look at the implementation: <tt>/usr/local/share/CMake/Modules/CheckIncludeFiles.cmake</tt> . <br />
There you'll see that it tries to compile a simple source file which includes the specified header files. The results of the tests are stored in the file CMakeCache.txt, so if you want to check later whether the test succeeded or not look in the CMakeCache.txt file :<br />
<pre><br />
//Have include HAVE_MALLOC_H<br />
HAVE_MALLOC_H:INTERNAL=1<br />
</pre><br />
As long as the result is in the cache, the test won't be executed again. If you want it to be executed again, either delete the file CMakeCache.txt, then all tests will be executed again, or just remove the entries for the variables you want to have tested again. This can save some time. If the test failed, and you want to find out why, open <tt>CMakeFiles/CMakeError.log</tt> and search for the header name (or function, etc.) you were testing for. There you should see the code which failed to compile or link, the compile command and the error message.<br />
Together with the implementation of the test in CheckIncludeFiles.cmake you should be able to figure out what went wrong.<br />
<br />
Ok, now that we have tested whether e.g. malloc.h exists and have the result in the cmake variable HAVE_MALLOC_H, we still have to create a header <tt>config.h</tt>. To do this, we use the cmake command <tt>CONFIGURE_FILE()</tt>, as you have seen above. This copies a source file to a target file and edits it while doing so, see the man page for details.<br />
So we write a source file named <tt>config.h.in</tt>, but you could give it any name you want (with autotools it's also usually named <tt>config.h.in</tt>):<br />
<pre><br />
#cmakedefine HAVE_MALLOC_H 1<br />
#cmakedefine HAVE_SYS_MOUNT_H<br />
</pre><br />
<br />
Now when cmake runs, it will replace <tt>#cmakedefine</tt>. If HAVE_MALLOC_H and HAVE_SYS_MOUNT_H are true, it will produce a <tt>config.h</tt>:<br />
<pre><br />
#define HAVE_MALLOC_H 1<br />
#define HAVE_SYS_MOUNT_H<br />
</pre><br />
If both are false, it will produce:<br />
<pre><br />
/* #undef HAVE_MALLOC_H 1 */<br />
/* #define HAVE_SYS_MOUNT_H */<br />
</pre><br />
<br />
By including this header into your source files you can check these properties using <tt>#ifdef</tt>.<br />
You can insert such checks in any of the CMakeLists.txt in your project, not only in the top-level CMakeLists.txt. If you have several ''configured'' headers, you shouldn't name them all <tt>config.h</tt>, this might lead to problems with the include path. Better give them names like <tt>config.h</tt>, <tt>config-foo.h</tt> for the configure header in the subdirectory <tt>foo/</tt> and <tt>config-bar.h</tt> in the <tt>bar/</tt> subdirectory, etc.<br />
<br />
The other commands coming with cmake to do system checks follow this style, so we can handle them much shorter now.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckIncludeFiles)<br />
;Usage: CHECK_INCLUDE_FILES(headers variable)<br />
;Example: CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)<br />
<br />
As just discussed lengthy, this can be used to check for the existence of a header.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckFunctionExists)<br />
;Usage: CHECK_FUNCTION_EXISTS(function variable)<br />
;Example: CHECK_FUNCTION_EXISTS(madvise HAVE_MADVISE)<br />
<br />
Checks whether the given function exists. This is done by linking a small program, which may not result in undefined references.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckSymbolExists)<br />
;Usage: CHECK_SYMBOL_EXISTS(symbol headers variable)<br />
;Example: CHECK_SYMBOL_EXISTS((LC_MESSAGES "locale.h" HAVE_LC_MESSAGES)<br />
<br />
Checks whether the given symbol exists if the specified headers are included.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckLibraryExists)<br />
;Usage: CHECK_LIBRARY_EXISTS(library function location variable)<br />
;Example: CHECK_LIBRARY_EXISTS(volmgt volmgt_running "" HAVE_VOLMGT)<br />
<br />
Checks whether the given library exists and contains the given function. This is done by linking a small program which uses the function and links to the library. In the location parameter an additional link directory (-Ldir) can be given if required.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckTypeSize)<br />
;Usage: SET(CMAKE_EXTRA_INCLUDE_FILES header)<br> CHECK_TYPE_SIZE(type variable)<br> SET(CMAKE_EXTRA_INCLUDE_FILES)<br />
;Example: SET(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)<br> CHECK_TYPE_SIZE("struct ucred" STRUCT_UCRED)<br> SET(CMAKE_EXTRA_INCLUDE_FILES)<br />
<br />
Checks whether the specified type exists and returns the size of the type. In the variable the size of the type will be returned, additionally a variable HAVE_STRUCT_UCRED will be set to true if the type exists. Please not that you have to set CMAKE_EXTRA_INCLUDE_FILES to the required headers for this type, and you should reset it after calling CHECK_TYPE_SIZE. If you are not really interested in the size of the type, but only whether it exists or not, you can also use STRUCT_UCRED directly, if the type doesn't exist, it will be empty and so also evaluate to FALSE (as will HAVE_STRUCT_UCRED).<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckPrototypeExists)<br />
;Usage: CHECK_PROTOTYPE_EXISTS(function headers variable)<br />
;Example: CHECK_PROTOTYPE_EXISTS(mkstemps "stdlib.h;unistd.h" HAVE_MKSTEMPS_PROTO)<br />
<br />
Checks whether the ''headers'' provide the declaration for the given ''function'', i.e. it does not check whether using ''function'' will lead to undefined references.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckCXXSourceCompiles)<br> INCLUDE (CheckCSourceCompiles)<br />
;Usage: CHECK_CXX_SOURCE_COMPILES(source variable)<br> CHECK_C_SOURCE_COMPILES(source variable)<br />
<br />
Checks whether the code given in ''source'' will compile and link. You can set CMAKE_REQUIRED_LIBRARIES, CMAKE_REQUIRED_FLAGS and CMAKE_REQUIRED_INCLUDES accordingly if additional libraries or compiler flags are required.<br />
<br />
{{CMake/Template/Footer}}<br />
<br />
[[Category:Tutorials]]</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake:How_To_Write_Platform_Checks&diff=16287CMake:How To Write Platform Checks2009-08-18T18:56:14Z<p>Shdwjk: removed unneccessary interjection, 'well'</p>
<hr />
<div>If you want to write software which compiles and runs on different operating systems, you have to take care for the special properties of the different platforms. On different operating systems there are subtle differences, e.g. on FreeBSD you should not use malloc.h, while it is perfectly ok to use it on Linux. These differences are typically handled by providing a header file which contains a bunch of define-statements according to the platform properties, usually named config.h:<br />
<br />
<pre><br />
#define HAVE_MALLOC_H 1<br />
/* #undef HAVE_SYS_MNTTAB_H 1 */<br />
/* #undef HAVE_SYS_MNTENT_H 1 */<br />
#define HAVE_SYS_MOUNT_H 1<br />
</pre><br />
<br />
This header file is then included in the source files and handled appropriately:<br />
<br />
foo.c:<br />
<pre><br />
#include "config.h"<br />
<br />
#ifdef HAVE_MALLOC_H<br />
#include <malloc.h><br />
#else<br />
#include <stdlib.h><br />
#endif<br />
<br />
void do_something() <br />
{<br />
void *buf=malloc(1024);<br />
...<br />
}<br />
</pre><br />
<br />
The contents of config.h depend on the platform where the sources are compiled, so there needs to be a way to generate this header file before the actual compilation process starts. If you are using autotools-based software, you probably know the <tt>./configure</tt> step, which has to be executed before starting <tt>make</tt>. The <tt>./configure</tt> script does some system introspection and generates from the gathered information the <tt>config.h</tt> header file.<br />
CMake is able to do the same, and I'll show you how to do it.<br />
<br />
Additionally to the builtin commands, cmake offers more commands implemented by cmake script files, called modules. These files are located in the cmake module directory, on UNIX systems is this by default <tt>/usr/local/share/CMake/Modules </tt>.<br />
<br />
To use commands from these modules, they have to be included in the CMakeLists.txt. CMake comes with several modules for checking the system, they all follow the same style, as an example here CHECK_INCLUDE_FILES:<br />
<br />
<pre><br />
INCLUDE (CheckIncludeFiles)<br />
# usage: CHECK_INCLUDE_FILES (<header> <RESULT_VARIABLE> )<br />
<br />
CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)<br />
CHECK_INCLUDE_FILES ("sys/param.h;sys/mount.h" HAVE_SYS_MOUNT_H)<br />
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)<br />
</pre><br />
<br />
The CMake module CheckIncludeFiles offers the command CHECK_INCLUDE_FILES(). The first argument to this command is the header you want to check for. The second argument is the variable which will contain the result. If the given header was found, it is set to 1, otherwise it is empty.<br />
If another header is required to use the header you are looking for, you have to list the header files separated by semicolons, as you can see above. To see what CHECK_INCLUDE_FILES() exactly does, have a look at the implementation: <tt>/usr/local/share/CMake/Modules/CheckIncludeFiles.cmake</tt> . <br />
There you'll see that it tries to compile a simple source file which includes the specified header files. The results of the tests are stored in the file CMakeCache.txt, so if you want to check later whether the test succeeded or not look in the CMakeCache.txt file :<br />
<pre><br />
//Have include HAVE_MALLOC_H<br />
HAVE_MALLOC_H:INTERNAL=1<br />
</pre><br />
As long as the result is in the cache, the test won't be executed again. If you want it to be executed again, either delete the file CMakeCache.txt, then all tests will be executed again, or just remove the entries for the variables you want to have tested again. This can save some time. If the test failed, and you want so find out why, open <tt>CMakeFiles/CMakeError.log</tt> and search for the header name (or function, etc.) you were testing for. There you should see the code which failed to compile or link, the compile command and the error message.<br />
Together with the implementation of the test in CheckIncludeFiles.cmake you should be able to figure out what went wrong.<br />
<br />
Ok, now that we have tested whether e.g. malloc.h exists and have the result in the cmake variable HAVE_MALLOC_H, we still have to create a header <tt>config.h</tt>. To do this, we use the cmake command <tt>CONFIGURE_FILE()</tt>, as you have seen above. This copies a source file to a target file and edits it while doing so, see the man page for details.<br />
So we write a source file named <tt>config.h.in</tt>, but you could give it any name you want (with autotools it's also usually named <tt>config.h.in</tt>):<br />
<pre><br />
#cmakedefine HAVE_MALLOC_H 1<br />
#cmakedefine HAVE_SYS_MOUNT_H<br />
</pre><br />
<br />
Now when cmake runs, it will replace <tt>#cmakedefine</tt>. If HAVE_MALLOC_H and HAVE_SYS_MOUNT_H are true, it will produce a <tt>config.h</tt>:<br />
<pre><br />
#define HAVE_MALLOC_H 1<br />
#define HAVE_SYS_MOUNT_H<br />
</pre><br />
If both are false, it will produce:<br />
<pre><br />
/* #undef HAVE_MALLOC_H 1 */<br />
/* #define HAVE_SYS_MOUNT_H */<br />
</pre><br />
<br />
By including this header into your source files you can check these properties using <tt>#ifdef</tt>.<br />
You can insert such checks in any of the CMakeLists.txt in your project, not only in the top-level CMakeLists.txt. If you have several ''configured'' headers, you shouldn't name them all <tt>config.h</tt>, this might lead to problems with the include path. Better give them names like <tt>config.h</tt>, <tt>config-foo.h</tt> for the configure header in the subdirectory <tt>foo/</tt> and <tt>config-bar.h</tt> in the <tt>bar/</tt> subdirectory, etc.<br />
<br />
The other commands coming with cmake to do system checks follow this style, so we can handle them much shorter now.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckIncludeFiles)<br />
;Usage: CHECK_INCLUDE_FILES(headers variable)<br />
;Example: CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)<br />
<br />
As just discussed lengthy, this can be used to check for the existence of a header.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckFunctionExists)<br />
;Usage: CHECK_FUNCTION_EXISTS(function variable)<br />
;Example: CHECK_FUNCTION_EXISTS(madvise HAVE_MADVISE)<br />
<br />
Checks whether the given function exists. This is done by linking a small program, which may not result in undefined references.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckSymbolExists)<br />
;Usage: CHECK_SYMBOL_EXISTS(symbol headers variable)<br />
;Example: CHECK_SYMBOL_EXISTS((LC_MESSAGES "locale.h" HAVE_LC_MESSAGES)<br />
<br />
Checks whether the given symbol exists if the specified headers are included.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckLibraryExists)<br />
;Usage: CHECK_LIBRARY_EXISTS(library function location variable)<br />
;Example: CHECK_LIBRARY_EXISTS(volmgt volmgt_running "" HAVE_VOLMGT)<br />
<br />
Checks whether the given library exists and contains the given function. This is done by linking a small program which uses the function and links to the library. In the location parameter an additional link directory (-Ldir) can be given if required.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckTypeSize)<br />
;Usage: SET(CMAKE_EXTRA_INCLUDE_FILES header)<br> CHECK_TYPE_SIZE(type variable)<br> SET(CMAKE_EXTRA_INCLUDE_FILES)<br />
;Example: SET(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)<br> CHECK_TYPE_SIZE("struct ucred" STRUCT_UCRED)<br> SET(CMAKE_EXTRA_INCLUDE_FILES)<br />
<br />
Checks whether the specified type exists and returns the size of the type. In the variable the size of the type will be returned, additionally a variable HAVE_STRUCT_UCRED will be set to true if the type exists. Please not that you have to set CMAKE_EXTRA_INCLUDE_FILES to the required headers for this type, and you should reset it after calling CHECK_TYPE_SIZE. If you are not really interested in the size of the type, but only whether it exists or not, you can also use STRUCT_UCRED directly, if the type doesn't exist, it will be empty and so also evaluate to FALSE (as will HAVE_STRUCT_UCRED).<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckPrototypeExists)<br />
;Usage: CHECK_PROTOTYPE_EXISTS(function headers variable)<br />
;Example: CHECK_PROTOTYPE_EXISTS(mkstemps "stdlib.h;unistd.h" HAVE_MKSTEMPS_PROTO)<br />
<br />
Checks whether the ''headers'' provide the declaration for the given ''function'', i.e. it does not check whether using ''function'' will lead to undefined references.<br />
<br />
----<br />
<br />
;Module: INCLUDE (CheckCXXSourceCompiles)<br> INCLUDE (CheckCSourceCompiles)<br />
;Usage: CHECK_CXX_SOURCE_COMPILES(source variable)<br> CHECK_C_SOURCE_COMPILES(source variable)<br />
<br />
Checks whether the code given in ''source'' will compile and link. You can set CMAKE_REQUIRED_LIBRARIES, CMAKE_REQUIRED_FLAGS and CMAKE_REQUIRED_INCLUDES accordingly if additional libraries or compiler flags are required.<br />
<br />
{{CMake/Template/Footer}}<br />
<br />
[[Category:Tutorials]]</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake/Language_Syntax&diff=16286CMake/Language Syntax2009-08-18T18:42:10Z<p>Shdwjk: /* Join a list with semicolons. */ Added missing word 'have' to last sentence.</p>
<hr />
<div>'''CMake has its own basic scripting language.''' A new user of CMake, learning this language, mostly needs to know about commands like SET, IF and MESSAGE. Sometimes, the details become lost. How does one manipulate variables? How do quotes and escapes work? Why do FOREACH and MACRO parameters behave strangely? What is the syntax?<br />
<br />
[http://cmake.org/Bug/view.php?id=6295 CMake bug 6295] asked for documentation of the core syntax. Thus the CMake web site now has [http://www.cmake.org/HTML/syntax.html a quick introduction to CMake syntax].<br />
<br />
This wiki page (formerly [http://kernigh.pbwiki.com/CMake]) contains an overview of the CMake language, its quirks and its limitations. Anyone may contribute to this page. ''You'' may edit, rewrite, refactor, correct or otherwise improve this page. Help other CMake users understand the language and avoid mistakes, contribute to this wiki.<br />
<br />
There is another wiki page, [[CMake:VariablesListsStrings]], that has more details about variables and regular expressions.<br />
<br />
== cmake -P ==<br />
The script mode <tt>cmake -P &lt;script&gt;</tt> allows you to run arbitrary CMake scripts (except that all commands related to Makefile generation or the CMake cache will fail). You may use this tool to experiment with the language, or to help create examples for this page. Write your script in a text editor and test your script with <tt>cmake -P ''something.cmake''</tt>.<br />
<br />
If your system is Unix, then <tt>cmake -P /dev/stdin</tt> is a good way to play with language: you type your script, type Control-D for end-of-file, and the script runs.<br />
The Windows equivalent is to run <tt>cmake -P con</tt>, and to use Control-Z (on a new line, followed by return) for end-of-file.<br />
<br />
== Listfiles contain comments and commands. ==<br />
We refer to each CMake script or <tt>CMakeLists.txt</tt> file as a ''listfile''. The basic syntax of a listfile is extremely simple: a listfile may contain only ''commands'' and ''comments''. Comments start with a <tt>#</tt> character and stop at the end of a line. You may freely mix comments with commands; comments may between or amid commands:<br />
<br />
# This is a comment.<br />
COMMAND( arguments go here )<br />
ANOTHER_COMMAND() # this command has no arguments<br />
YET_ANOTHER_COMMAND( these<br />
arguments are spread # another comment<br />
over several lines )<br />
<br />
The names of commands are case ''insensitive''; the usual convention is to type the command names in uppercase. However, the arguments are case ''sensitive''. Thus MESSAGE and message and Message and mESsAgE are the same command:<br />
<br />
MESSAGE( hi ) # displays "hi"<br />
message( hi ) # displays "hi" again<br />
message( HI ) # displays "HI"<br />
<br />
The whitespace around the ( and ) parens is optional, all of these commands are the same:<br />
<br />
MESSAGE(hi)<br />
MESSAGE (hi)<br />
MESSAGE( hi )<br />
MESSAGE (hi )<br />
<br />
Commands are procedure calls and cannot return values. However, you may pass the name of a global variable to some commands, and those commands will store the result there. For example, the <tt>MATH( EXPR ... )</tt> command takes three arguments; the third argument is the expression, and the second argument is the variable to store the result:<br />
<br />
MATH( EXPR x "3 + 3" ) # stores the result of 3 + 3 in x<br />
MESSAGE( "x is ${x}" ) # displays "x is 6"<br />
# using quotes so MESSAGE receives only one argument<br />
<br />
== CMake variables ==<br />
In versions of CMake<=2.4, almost all variables have global scope within a directory (and in that directory's subdirectories); a notable exception is the FOREACH command, the loop variable of which is local only to the FOREACH body. Also, the parameters (including ARG0, ARG1, ARG2, ARGC, ARGN, and ARGV) of user defined [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:macro macros] are not variables, per se; their values must always be used directly: IF(${some_parameter}) instead of IF(some_parameter).<br />
<br />
CMake 2.6 introduces [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:function functions], which are essentially macros that have local scope and use real variables (even ARG0, ARG1, ARGC, ARGN, and ARGV are treated as real variables); IF(some_parameter) is perfectly acceptable. Most importantly, global variables are read-only within functions. Whenever a variable is set within a function body, that variable only has local scope, masking any similarly named global variable; outside of the function body, the global variables remain unchanged.<br />
<br />
See [[CMake:VariablesListsStrings]] about how the ADD_SUBDIRECTORY or SUBDIRS command affects variables in a CMake project.<br />
<br />
=== Values ===<br />
''Variables always contain strings.'' Sometimes, we use the string to store a boolean, a path to a file, an integer, or a list.<br />
<br />
=== SET and substitution ===<br />
Use the SET command to set the value of a variable to some string. The SET command takes two arguments: the name of the variable and its new value, SET(variable value). To access the value of a variable, you perform a ''substitution''. To perform a substitution, use the syntax <tt>${''variablename''}</tt>:<br />
<br />
SET( x 3 )<br />
SET( y 1 )<br />
MESSAGE( ${x}${y} ) # displays "31"<br />
<br />
If more than one value is specified, each value is concatenated into one string in which semicolons serve to separate the indivual values. This kind of string is called a list in CMake and can be used with the LIST command. You may use quoting to avoid this:<br />
<br />
SET( x a b c ) # stores "a;b;c" in x (without quotes)<br />
SET( y "a b c" ) # stores "a b c" in y (without quotes)<br />
MESSAGE( a b c ) # prints "abc" to stdout (without quotes)<br />
MESSAGE( ${x} ) # prints "abc" to stdout (without quotes)<br />
MESSAGE("${x}") # prints "a;b;c" to stdout (without quotes)<br />
MESSAGE( ${y} ) # prints "a b c" to stdout (without quotes)<br />
MESSAGE("${y}") # prints "a b c" to stdout (without quotes)<br />
<br />
In fact, the following are equivalent:<br />
<br />
SET( x a b c )<br />
SET( x a;b;c )<br />
SET( x "a;b;c" )<br />
SET( x;a;b;c )<br />
<br />
However, this does 'not' work:<br />
<br />
SET( "x;a;b;c" )<br />
<br />
Of course, the arguments to SET itself can come from substitutions:<br />
<br />
SET( x y A B C ) # stores "y;A;B;C" in x (without quote)<br />
SET( ${x} ) # => SET( y;A;B;C ) => SET( y A B C)<br />
MESSAGE( ${y} ) # prints "ABC" to stdout (without quotes)<br />
SET( y x ) # stores "x" in y (without quotes)<br />
SET( ${y} y = x ) # => SET( x y )<br />
MESSAGE( "\${x} = '${x}'" ) # prints "${x} = 'y;=;x'" to stdout (without quotes)<br />
SET( y ${x} ) # => SET( y y = x ) => stores "y;=;x" in y (without quotes)<br />
MESSAGE( ${y} ) # prints "y=x" to stdout (without quotes)<br />
<br />
The value can be the empty string, "":<br />
<br />
SET( x "" )<br />
<br />
If there is no value specified, then the variable is UNSET, so that it is like the variable never existed:<br />
<br />
SET( x )<br />
IF(DEFINED x)<br />
MESSAGE("This will never be printed")<br />
ENDIF(DEFINED x)<br />
<br />
However, this is more obviously performed with the UNSET command:<br />
<br />
UNSET( x )<br />
<br />
=== Substitution of command names ===<br />
Substitution only works within arguments to commands. In particular, the name of a command cannot include a substitution; so you cannot store the name of a command in a variable, then run that command. For example, this does not work:<br />
<br />
SET( command MESSAGE )<br />
${command}( hi )<br />
# syntax error<br />
<br />
If you insist, the available workaround is to write the command to a temporary file, then INCLUDE the file to run the command.<br />
<br />
SET( command MESSAGE )<br />
<br />
# ${command}( hi )<br />
FILE( WRITE temp "${command}( hi )" ) # writes "MESSAGE( hi )" to ./temp<br />
INCLUDE( temp ) # ./temp is an unsafe temporary file...<br />
FILE( REMOVE temp )<br />
<br />
== CMake splits arguments unless you use quotation marks or escapes. ==<br />
Each command in a listfile takes zero or more arguments. CMake separates arguments by whitespace, performs substitutions, then separates arguments by semicolons. That is, if you are just typing literal arguments, then you may use either whitespace or semicolons to separate them. However, if you want a variable substitution to produce multiple arguments, then you need to use semicolons in the variable.<br />
<br />
To shell script hackers, this is not the same as setting <tt>IFS=\;</tt> in a Bourne shell that follows POSIX. (Because <tt>;</tt> is also a shell operator, we escape it with a backslash.) The difference is that the Bourne shell will only use the <tt>;</tt> delimeter within substitutions, while CMake will use it everywhere:<br />
<br />
# shell script<br />
countargs() {<br />
echo $?<br />
}<br />
IFS=\;<br />
countargs a\;b\;c # displays "1"<br />
ARGS=a\;b\;c<br />
countargs $ARGS # displays "3"<br />
<br />
# CMake<br />
MACRO( COUNTARGS )<br />
MESSAGE ( ${ARGC} )<br />
ENDMACRO( COUNTARGS )<br />
COUNTARGS( a;b;c ) # displays "3"<br />
SET( ARGS a;b;c )<br />
COUNTARGS( ${ARGS} ) # displays "3"<br />
<br />
Importantly, the MESSAGE command has the habit of concatenating all of its arguments! (This is why many examples on this page use quoting so that MESSAGE takes only one argument.) The following three commands are effectively the same:<br />
<br />
MESSAGE(This is practice.) # prints "Thisispractice."<br />
MESSAGE( This is practice. ) # prints "Thisispractice."<br />
MESSAGE( This;is;practice. ) # prints "Thisispractice."<br />
<br />
=== Quoting ===<br />
You can preserve whitespace, semicolons and parens by quoting entire arguments, as if they were strings in C:<br />
<br />
MESSAGE( "This is practice." ) # prints "This is practice."<br />
MESSAGE( "This;is;practice." ) # prints "This;is;practice."<br />
MESSAGE( "Hi. ) MESSAGE( x )" ) # prints "Hi. ) MESSAGE( x )"<br />
<br />
You can also quote ''parts'' of arguments. CMake has to decide whether or not the quotes or quoting syntax (as in shell script) or literal quotes. The rules in CMake 2.4 are:<br />
<br />
# If the argument begins with a quote, then the quotes are ''quoting syntax''.<br />
# Otherwise, if the quotes surround whitespace, semicolons or parens to preserve, then the quotes are ''quoting syntax''.<br />
# Otherwise, the quotes are ''literal quotes''.<br />
<br />
{| border="1"<br />
|| Input || Output<br />
|-<br />
|| <tt>MESSAGE( "Welc"ome ) # rule 1</tt> || <tt>Welcome</tt><br />
|-<br />
|| <tt>MESSAGE( Welc"ome" ) # rule 3</tt> || <tt>Welc"ome"</tt><br />
|-<br />
|| <tt>MESSAGE( Welc"ome)" ) # rule 2</tt> || <tt>Welcome)</tt><br />
|-<br />
|| <tt>MESSAGE( ""Thanks ) # rule 1</tt> || <tt>Thanks</tt><br />
|-<br />
|| <tt>MESSAGE( Thanks"" ) # rule 3</tt> || <tt>Thanks""</tt><br />
|}<br />
<br />
Quoting does not prevent substitutions. It does, however, prevent CMake from splitting arguments at the semicolons, and allows you to pass empty strings as arguments:<br />
<br />
SET( SOURCES back.c io.c main.c )<br />
MESSAGE( ${SOURCES} ) # three arguments, prints "back.cio.cmain.c"<br />
MESSAGE( "${SOURCES}" ) # one argument, prints "back.c;io.c;main.c"<br />
MESSAGE( "" ) # one argument, prints "" an empty line<br />
MESSAGE( "${EMPTY_STRING}" ) # one argument, prints "" an empty line<br />
MESSAGE( ${EMPTY_STRING} ) # zero arguments, causes CMake Error<br />
# "MESSAGE called with incorrect number of arguments"<br />
<br />
=== Escapes ===<br />
A backslash <tt>\</tt> in the arguments to a command will start an escape sequence. To use literally any of <tt>"()#$^</tt>, escape the character with a backslash. You may also escape a space (instead of quoting it) and you may use <tt>\\</tt> for a literal backslash.<br />
<br />
MESSAGE( \\\"\ \(\)\#\$\^ ) # this message contains literal characters<br />
<br />
MESSAGE( \# not a comment )<br />
MESSAGE( \${NotAnExpansion} )<br />
SET( rightparen \) )<br />
<br />
There are a few other escape sequences, including <tt>\n</tt> for newline, and possibly others that I forgot. All other escape sequences are invalid and cause a CMake error.<br />
<br />
== CMake supports boolean variables. ==<br />
CMake considers an empty string, "FALSE", "OFF", "NO", or any string ending in "-NOTFOUND" to be false. (This happens to be case-insensitive, so "False", "off", "no", and "something-NotFound" are all false.) Other values are true. Thus it matters not whether you use TRUE and FALSE, ON and OFF, or YES and NO for your booleans.<br />
<br />
Many scripts expect a string to either be false or contain a useful value, often a path to a directory or a file. You have a potential but rare problem if one of the useful values coincides with falseness. Avoid giving nonsensical names like <tt>/tmp/ME-NOTFOUND</tt> to your files, executables or libraries.<br />
<br />
== IF and WHILE control the flow. ==<br />
Any scripting language provides conditionals and loops. In CMake, the IF command provides conditionals, while the WHILE command provides a loop. These two commands also provide the way to evaluate boolean expressions.<br />
<br />
When CMake sees an IF command, then it checks the arguments to the IF command. Is the condition is true, then it runs the command between the IF and matching ENDIF commands, else it skips them.<br />
<br />
The WHILE command works like the IF command except that it is a loop: after CMake runs the commands between the WHILE and ENDWHILE commands, CMake jumps back to the WHILE command to check whether to run the loop again. Here is an example:<br />
<br />
SET( number 4 )<br />
# if ${number} is greater than 10<br />
IF( number GREATER 10 )<br />
MESSAGE( "The number ${number} is too large." )<br />
ENDIF( number GREATER 10 )<br />
<br />
# while ${number} is between 0 and 11<br />
WHILE( number GREATER 0 AND number LESS 11 )<br />
MESSAGE( "hi ${number}")<br />
MATH( EXPR number "${number} - 1" ) # decrement number<br />
ENDWHILE( number GREATER 0 AND number LESS 11 )<br />
<br />
If number is too large, this listfile complains. Otherwise, the loop counts down toward zero and says hi to each number. If number starts at 4, then the messages are "hi 4", "hi 3", "hi 2", "hi 1".<br />
<br />
Note that CMake is very strict, and requires the matching IF and ENDIF (or WHILE and ENDWHILE) commands to have the same arguments. This strictness is not necessary to the language (because CMake may count IF and ENDIF commands to determine the nesting of conditions, similar to how ShellScript counts <tt>if</tt> and <tt>then</tt> and <tt>fi</tt> commands) but it catches programmer errors. There is a way in CMake to disable this strictness, so that a simple <tt>ENDIF()</tt> works.<br />
<br />
The arguments to IF and WHILE commands may contain substitutions, as any other command:<br />
<br />
SET( number 4 )<br />
SET( operation GREATER )<br />
SET( limit 10 )<br />
IF( number ${operation} ${limit} )<br />
MESSAGE( "Oops, ${number} is ${operation} than ${limit}." )<br />
ENDIF( number ${operation} ${limit} )<br />
<br />
The syntax for boolean expressions is given in the CMake manual page, in the section for the IF command. This includes the order of operations (for example, <tt>GREATER</tt> and <tt>LESS</tt> have higher precedence than AND). Note that the operations are case sensitive, because they are arguments: <tt>GREATER</tt> is an operation, <tt>greater</tt> is not.<br />
<br />
== Join a list with semicolons. ==<br />
A SET command with more than two arguments will join the second and after arguments with semicolons:<br />
<br />
SET( letters a b c d ) # sets letters to "a;b;c;d"<br />
<br />
A string that contains semicolons is a list. An empty string "" is a list of zero elements, while a nonempty string that contains zero semicolons is a list of one element. For example, you might have a list of source files for a particular target. CMake does not have arrays like Perl or shell script, or linked lists like Lisp; the expectation is that your CMake scripts will use semicolon delimiters in lists.<br />
<br />
CMake provides a LIST command that performs basic operations with list.<br />
<br />
CMake splits arguments at semicolons, thus a list will split into multiple arguments. You may store arguments in a list and use them with a later command:<br />
<br />
SET( expression 4 LESS 10 ) # ${expression} is now "4;LESS;10"<br />
IF( ${expression} ) # expands to IF( 4;LESS;10 )<br />
MESSAGE( "CMake believes that 4 is less than 10." )<br />
ENDIF( ${expression} )<br />
<br />
In a CMake project, you might have a variable <tt>sources</tt> for a list of source files. When you call ADD_EXECUTABLE or ADD_LIBRARY to create a target, you may pass <tt>${sources}</tt>.<br />
<br />
== When CMake wants a variable name, when it wants a substitution. ==<br />
Does <tt>IF( number GREATER 10 )</tt> mean the same as <tt>IF( ${number} GREATER 10 )</tt>? Actually it does, if <tt>number</tt> is a variable. Some operations in boolean expressions will accept either a variable name or a value. If the name matches a variable name, then CMake uses that variable's value; but if the name does not match a variable name, then CMake uses the direct value.<br />
<br />
Suppose the variable <tt>number</tt> contains 4. Then <tt>IF( number GREATER 10 )</tt> will notice that <tt>number</tt> is the name of a variable, and CMake tests if 4 is greater than 10. (The test is false.) But <tt>IF( ${number} GREATER 10 )</tt> expands to <tt>IF( 4 GREATER 10 )</tt>, and we hope that <tt>4</tt> is not the name of a variable, so CMake tests if 4 is greater than 10.<br />
<br />
The first argument to the SET command is a variable name, not a substitution. SET wants to know the name of the variable to set, not the variable's current value. (This is different from Perl, which does not perform substitution.) It remains legitimate to use a substitution if the name of the variable that you want to set is the value of another variable:<br />
<br />
SET( varname number ) # sets varname to "number"<br />
SET( ${varname} 4 ) # sets number to "4"<br />
<br />
== CMake may access environment variables. ==<br />
You can also substitute the value of an environment variable. The syntax is $ENV{''name''}.<br />
<br />
MESSAGE( "Your Unix home directory is $ENV{HOME}." )<br />
<br />
Note that "ENV" is the only permitted hash (or map or dictionary, or your name for a set of key-value pairs). If you attempt to access another hash, then CMake will give an error:<br />
<br />
MESSAGE( $hi{there} )<br />
# causes error "Key hi is not used yet. For now only $ENV{..} is allowed"<br />
<br />
Yes, it is possible to set an environment variable:<br />
<br />
SET( ENV{PATH} /bin:/usr/bin ) # use a minimal PATH<br />
<br />
== Recursive subsitutions permit indirect variables. ==<br />
CMake can handle recursive substitutions, so that you may let one variable contain the name (or part of the name) of another variable:<br />
<br />
SET( varname x )<br />
SET( x 6 )<br />
MESSAGE( "${varname} is ${${varname}}" ) # displays "x is 6"<br />
<br />
It is not necessary to employ a workaround like "STRING( CONFIGURE ... )".<br />
<br />
== TODO ==<br />
* Describe ELSE and ELSEIF.<br />
* Describe FOREACH and MACRO on this page. These commands provide constant parameters, not variables; demonstrate that you cannot SET them. Explain the important rule, ''constant expansion happens before variable expansion''. This rule has consequences when your parameter contains "${" somewhere.<br />
<br />
== History ==<br />
[[User:Kernigh|Kernigh]] began to write about the syntax of the language of CMake. At first, the information appeared in a wiki page "The Scripting Language of CMake", http://kernigh.pbwiki.com/CMake. Then Kernigh moved the syntax information to this page at the Kitware Public Wiki.</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake/Language_Syntax&diff=16272CMake/Language Syntax2009-08-14T20:33:17Z<p>Shdwjk: /* SET and substitution */ -- Fixed spelling of prints in Set examples. Fixed alignment of comments</p>
<hr />
<div>'''CMake has its own basic scripting language.''' A new user of CMake, learning this language, mostly needs to know about commands like SET, IF and MESSAGE. Sometimes, the details become lost. How does one manipulate variables? How do quotes and escapes work? Why do FOREACH and MACRO parameters behave strangely? What is the syntax?<br />
<br />
[http://cmake.org/Bug/view.php?id=6295 CMake bug 6295] asked for documentation of the core syntax. Thus the CMake web site now has [http://www.cmake.org/HTML/syntax.html a quick introduction to CMake syntax].<br />
<br />
This wiki page (formerly [http://kernigh.pbwiki.com/CMake]) contains an overview of the CMake language, its quirks and its limitations. Anyone may contribute to this page. ''You'' may edit, rewrite, refactor, correct or otherwise improve this page. Help other CMake users understand the language and avoid mistakes, contribute to this wiki.<br />
<br />
There is another wiki page, [[CMake:VariablesListsStrings]], that has more details about variables and regular expressions.<br />
<br />
== cmake -P ==<br />
The script mode <tt>cmake -P &lt;script&gt;</tt> allows you to run arbitrary CMake scripts (except that all commands related to Makefile generation or the CMake cache will fail). You may use this tool to experiment with the language, or to help create examples for this page. Write your script in a text editor and test your script with <tt>cmake -P ''something.cmake''</tt>.<br />
<br />
If your system is Unix, then <tt>cmake -P /dev/stdin</tt> is a good way to play with language: you type your script, type Control-D for end-of-file, and the script runs.<br />
The Windows equivalent is to run <tt>cmake -P con</tt>, and to use Control-Z (on a new line, followed by return) for end-of-file.<br />
<br />
== Listfiles contain comments and commands. ==<br />
We refer to each CMake script or <tt>CMakeLists.txt</tt> file as a ''listfile''. The basic syntax of a listfile is extremely simple: a listfile may contain only ''commands'' and ''comments''. Comments start with a <tt>#</tt> character and stop at the end of a line. You may freely mix comments with commands; comments may between or amid commands:<br />
<br />
# This is a comment.<br />
COMMAND( arguments go here )<br />
ANOTHER_COMMAND() # this command has no arguments<br />
YET_ANOTHER_COMMAND( these<br />
arguments are spread # another comment<br />
over several lines )<br />
<br />
The names of commands are case ''insensitive''; the usual convention is to type the command names in uppercase. However, the arguments are case ''sensitive''. Thus MESSAGE and message and Message and mESsAgE are the same command:<br />
<br />
MESSAGE( hi ) # displays "hi"<br />
message( hi ) # displays "hi" again<br />
message( HI ) # displays "HI"<br />
<br />
The whitespace around the ( and ) parens is optional, all of these commands are the same:<br />
<br />
MESSAGE(hi)<br />
MESSAGE (hi)<br />
MESSAGE( hi )<br />
MESSAGE (hi )<br />
<br />
Commands are procedure calls and cannot return values. However, you may pass the name of a global variable to some commands, and those commands will store the result there. For example, the <tt>MATH( EXPR ... )</tt> command takes three arguments; the third argument is the expression, and the second argument is the variable to store the result:<br />
<br />
MATH( EXPR x "3 + 3" ) # stores the result of 3 + 3 in x<br />
MESSAGE( "x is ${x}" ) # displays "x is 6"<br />
# using quotes so MESSAGE receives only one argument<br />
<br />
== CMake variables ==<br />
In versions of CMake<=2.4, almost all variables have global scope within a directory (and in that directory's subdirectories); a notable exception is the FOREACH command, the loop variable of which is local only to the FOREACH body. Also, the parameters (including ARG0, ARG1, ARG2, ARGC, ARGN, and ARGV) of user defined [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:macro macros] are not variables, per se; their values must always be used directly: IF(${some_parameter}) instead of IF(some_parameter).<br />
<br />
CMake 2.6 introduces [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:function functions], which are essentially macros that have local scope and use real variables (even ARG0, ARG1, ARGC, ARGN, and ARGV are treated as real variables); IF(some_parameter) is perfectly acceptable. Most importantly, global variables are read-only within functions. Whenever a variable is set within a function body, that variable only has local scope, masking any similarly named global variable; outside of the function body, the global variables remain unchanged.<br />
<br />
See [[CMake:VariablesListsStrings]] about how the ADD_SUBDIRECTORY or SUBDIRS command affects variables in a CMake project.<br />
<br />
=== Values ===<br />
''Variables always contain strings.'' Sometimes, we use the string to store a boolean, a path to a file, an integer, or a list.<br />
<br />
=== SET and substitution ===<br />
Use the SET command to set the value of a variable to some string. The SET command takes two arguments: the name of the variable and its new value, SET(variable value). To access the value of a variable, you perform a ''substitution''. To perform a substitution, use the syntax <tt>${''variablename''}</tt>:<br />
<br />
SET( x 3 )<br />
SET( y 1 )<br />
MESSAGE( ${x}${y} ) # displays "31"<br />
<br />
If more than one value is specified, each value is concatenated into one string in which semicolons serve to separate the indivual values. This kind of string is called a list in CMake and can be used with the LIST command. You may use quoting to avoid this:<br />
<br />
SET( x a b c ) # stores "a;b;c" in x (without quotes)<br />
SET( y "a b c" ) # stores "a b c" in y (without quotes)<br />
MESSAGE( a b c ) # prints "abc" to stdout (without quotes)<br />
MESSAGE( ${x} ) # prints "abc" to stdout (without quotes)<br />
MESSAGE("${x}") # prints "a;b;c" to stdout (without quotes)<br />
MESSAGE( ${y} ) # prints "a b c" to stdout (without quotes)<br />
MESSAGE("${y}") # prints "a b c" to stdout (without quotes)<br />
<br />
In fact, the following are equivalent:<br />
<br />
SET( x a b c )<br />
SET( x a;b;c )<br />
SET( x "a;b;c" )<br />
SET( x;a;b;c )<br />
<br />
However, this does 'not' work:<br />
<br />
SET( "x;a;b;c" )<br />
<br />
Of course, the arguments to SET itself can come from substitutions:<br />
<br />
SET( x y A B C ) # stores "y;A;B;C" in x (without quote)<br />
SET( ${x} ) # => SET( y;A;B;C ) => SET( y A B C)<br />
MESSAGE( ${y} ) # prints "ABC" to stdout (without quotes)<br />
SET( y x ) # stores "x" in y (without quotes)<br />
SET( ${y} y = x ) # => SET( x y )<br />
MESSAGE( "\${x} = '${x}'" ) # prints "${x} = 'y;=;x'" to stdout (without quotes)<br />
SET( y ${x} ) # => SET( y y = x ) => stores "y;=;x" in y (without quotes)<br />
MESSAGE( ${y} ) # prints "y=x" to stdout (without quotes)<br />
<br />
The value can be the empty string, "":<br />
<br />
SET( x "" )<br />
<br />
If there is no value specified, then the variable is UNSET, so that it is like the variable never existed:<br />
<br />
SET( x )<br />
IF(DEFINED x)<br />
MESSAGE("This will never be printed")<br />
ENDIF(DEFINED x)<br />
<br />
However, this is more obviously performed with the UNSET command:<br />
<br />
UNSET( x )<br />
<br />
=== Substitution of command names ===<br />
Substitution only works within arguments to commands. In particular, the name of a command cannot include a substitution; so you cannot store the name of a command in a variable, then run that command. For example, this does not work:<br />
<br />
SET( command MESSAGE )<br />
${command}( hi )<br />
# syntax error<br />
<br />
If you insist, the available workaround is to write the command to a temporary file, then INCLUDE the file to run the command.<br />
<br />
SET( command MESSAGE )<br />
<br />
# ${command}( hi )<br />
FILE( WRITE temp "${command}( hi )" ) # writes "MESSAGE( hi )" to ./temp<br />
INCLUDE( temp ) # ./temp is an unsafe temporary file...<br />
FILE( REMOVE temp )<br />
<br />
== CMake splits arguments unless you use quotation marks or escapes. ==<br />
Each command in a listfile takes zero or more arguments. CMake separates arguments by whitespace, performs substitutions, then separates arguments by semicolons. That is, if you are just typing literal arguments, then you may use either whitespace or semicolons to separate them. However, if you want a variable substitution to produce multiple arguments, then you need to use semicolons in the variable.<br />
<br />
To shell script hackers, this is not the same as setting <tt>IFS=\;</tt> in a Bourne shell that follows POSIX. (Because <tt>;</tt> is also a shell operator, we escape it with a backslash.) The difference is that the Bourne shell will only use the <tt>;</tt> delimeter within substitutions, while CMake will use it everywhere:<br />
<br />
# shell script<br />
countargs() {<br />
echo $?<br />
}<br />
IFS=\;<br />
countargs a\;b\;c # displays "1"<br />
ARGS=a\;b\;c<br />
countargs $ARGS # displays "3"<br />
<br />
# CMake<br />
MACRO( COUNTARGS )<br />
MESSAGE ( ${ARGC} )<br />
ENDMACRO( COUNTARGS )<br />
COUNTARGS( a;b;c ) # displays "3"<br />
SET( ARGS a;b;c )<br />
COUNTARGS( ${ARGS} ) # displays "3"<br />
<br />
Importantly, the MESSAGE command has the habit of concatenating all of its arguments! (This is why many examples on this page use quoting so that MESSAGE takes only one argument.) The following three commands are effectively the same:<br />
<br />
MESSAGE(This is practice.) # prints "Thisispractice."<br />
MESSAGE( This is practice. ) # prints "Thisispractice."<br />
MESSAGE( This;is;practice. ) # prints "Thisispractice."<br />
<br />
=== Quoting ===<br />
You can preserve whitespace, semicolons and parens by quoting entire arguments, as if they were strings in C:<br />
<br />
MESSAGE( "This is practice." ) # prints "This is practice."<br />
MESSAGE( "This;is;practice." ) # prints "This;is;practice."<br />
MESSAGE( "Hi. ) MESSAGE( x )" ) # prints "Hi. ) MESSAGE( x )"<br />
<br />
You can also quote ''parts'' of arguments. CMake has to decide whether or not the quotes or quoting syntax (as in shell script) or literal quotes. The rules in CMake 2.4 are:<br />
<br />
# If the argument begins with a quote, then the quotes are ''quoting syntax''.<br />
# Otherwise, if the quotes surround whitespace, semicolons or parens to preserve, then the quotes are ''quoting syntax''.<br />
# Otherwise, the quotes are ''literal quotes''.<br />
<br />
{| border="1"<br />
|| Input || Output<br />
|-<br />
|| <tt>MESSAGE( "Welc"ome ) # rule 1</tt> || <tt>Welcome</tt><br />
|-<br />
|| <tt>MESSAGE( Welc"ome" ) # rule 3</tt> || <tt>Welc"ome"</tt><br />
|-<br />
|| <tt>MESSAGE( Welc"ome)" ) # rule 2</tt> || <tt>Welcome)</tt><br />
|-<br />
|| <tt>MESSAGE( ""Thanks ) # rule 1</tt> || <tt>Thanks</tt><br />
|-<br />
|| <tt>MESSAGE( Thanks"" ) # rule 3</tt> || <tt>Thanks""</tt><br />
|}<br />
<br />
Quoting does not prevent substitutions. It does, however, prevent CMake from splitting arguments at the semicolons, and allows you to pass empty strings as arguments:<br />
<br />
SET( SOURCES back.c io.c main.c )<br />
MESSAGE( ${SOURCES} ) # three arguments, prints "back.cio.cmain.c"<br />
MESSAGE( "${SOURCES}" ) # one argument, prints "back.c;io.c;main.c"<br />
MESSAGE( "" ) # one argument, prints "" an empty line<br />
MESSAGE( "${EMPTY_STRING}" ) # one argument, prints "" an empty line<br />
MESSAGE( ${EMPTY_STRING} ) # zero arguments, causes CMake Error<br />
# "MESSAGE called with incorrect number of arguments"<br />
<br />
=== Escapes ===<br />
A backslash <tt>\</tt> in the arguments to a command will start an escape sequence. To use literally any of <tt>"()#$^</tt>, escape the character with a backslash. You may also escape a space (instead of quoting it) and you may use <tt>\\</tt> for a literal backslash.<br />
<br />
MESSAGE( \\\"\ \(\)\#\$\^ ) # this message contains literal characters<br />
<br />
MESSAGE( \# not a comment )<br />
MESSAGE( \${NotAnExpansion} )<br />
SET( rightparen \) )<br />
<br />
There are a few other escape sequences, including <tt>\n</tt> for newline, and possibly others that I forgot. All other escape sequences are invalid and cause a CMake error.<br />
<br />
== CMake supports boolean variables. ==<br />
CMake considers an empty string, "FALSE", "OFF", "NO", or any string ending in "-NOTFOUND" to be false. (This happens to be case-insensitive, so "False", "off", "no", and "something-NotFound" are all false.) Other values are true. Thus it matters not whether you use TRUE and FALSE, ON and OFF, or YES and NO for your booleans.<br />
<br />
Many scripts expect a string to either be false or contain a useful value, often a path to a directory or a file. You have a potential but rare problem if one of the useful values coincides with falseness. Avoid giving nonsensical names like <tt>/tmp/ME-NOTFOUND</tt> to your files, executables or libraries.<br />
<br />
== IF and WHILE control the flow. ==<br />
Any scripting language provides conditionals and loops. In CMake, the IF command provides conditionals, while the WHILE command provides a loop. These two commands also provide the way to evaluate boolean expressions.<br />
<br />
When CMake sees an IF command, then it checks the arguments to the IF command. Is the condition is true, then it runs the command between the IF and matching ENDIF commands, else it skips them.<br />
<br />
The WHILE command works like the IF command except that it is a loop: after CMake runs the commands between the WHILE and ENDWHILE commands, CMake jumps back to the WHILE command to check whether to run the loop again. Here is an example:<br />
<br />
SET( number 4 )<br />
# if ${number} is greater than 10<br />
IF( number GREATER 10 )<br />
MESSAGE( "The number ${number} is too large." )<br />
ENDIF( number GREATER 10 )<br />
<br />
# while ${number} is between 0 and 11<br />
WHILE( number GREATER 0 AND number LESS 11 )<br />
MESSAGE( "hi ${number}")<br />
MATH( EXPR number "${number} - 1" ) # decrement number<br />
ENDWHILE( number GREATER 0 AND number LESS 11 )<br />
<br />
If number is too large, this listfile complains. Otherwise, the loop counts down toward zero and says hi to each number. If number starts at 4, then the messages are "hi 4", "hi 3", "hi 2", "hi 1".<br />
<br />
Note that CMake is very strict, and requires the matching IF and ENDIF (or WHILE and ENDWHILE) commands to have the same arguments. This strictness is not necessary to the language (because CMake may count IF and ENDIF commands to determine the nesting of conditions, similar to how ShellScript counts <tt>if</tt> and <tt>then</tt> and <tt>fi</tt> commands) but it catches programmer errors. There is a way in CMake to disable this strictness, so that a simple <tt>ENDIF()</tt> works.<br />
<br />
The arguments to IF and WHILE commands may contain substitutions, as any other command:<br />
<br />
SET( number 4 )<br />
SET( operation GREATER )<br />
SET( limit 10 )<br />
IF( number ${operation} ${limit} )<br />
MESSAGE( "Oops, ${number} is ${operation} than ${limit}." )<br />
ENDIF( number ${operation} ${limit} )<br />
<br />
The syntax for boolean expressions is given in the CMake manual page, in the section for the IF command. This includes the order of operations (for example, <tt>GREATER</tt> and <tt>LESS</tt> have higher precedence than AND). Note that the operations are case sensitive, because they are arguments: <tt>GREATER</tt> is an operation, <tt>greater</tt> is not.<br />
<br />
== Join a list with semicolons. ==<br />
A SET command with more than two arguments will join the second and after arguments with semicolons:<br />
<br />
SET( letters a b c d ) # sets letters to "a;b;c;d"<br />
<br />
A string that contains semicolons is a list. An empty string "" is a list of zero elements, while a nonempty string that contains zero semicolons is a list of one element. For example, you might have a list of source files for a particular target. CMake does not have arrays like Perl or shell script, or linked lists like Lisp; the expectation is that your CMake scripts will use semicolon delimiters in lists.<br />
<br />
CMake provides a LIST command that performs basic operations with list.<br />
<br />
CMake splits arguments at semicolons, thus a list will split into multiple arguments. You may store arguments in a list and use them with a later command:<br />
<br />
SET( expression 4 LESS 10 ) # ${expression} is now "4;LESS;10"<br />
IF( ${expression} ) # expands to IF( 4;LESS;10 )<br />
MESSAGE( "CMake believes that 4 is less than 10." )<br />
ENDIF( ${expression} )<br />
<br />
In a CMake project, you might a variable <tt>sources</tt> for a list of source files. When you call ADD_EXECUTABLE or ADD_LIBRARY to create a target, you may pass <tt>${sources}</tt>.<br />
<br />
== When CMake wants a variable name, when it wants a substitution. ==<br />
Does <tt>IF( number GREATER 10 )</tt> mean the same as <tt>IF( ${number} GREATER 10 )</tt>? Actually it does, if <tt>number</tt> is a variable. Some operations in boolean expressions will accept either a variable name or a value. If the name matches a variable name, then CMake uses that variable's value; but if the name does not match a variable name, then CMake uses the direct value.<br />
<br />
Suppose the variable <tt>number</tt> contains 4. Then <tt>IF( number GREATER 10 )</tt> will notice that <tt>number</tt> is the name of a variable, and CMake tests if 4 is greater than 10. (The test is false.) But <tt>IF( ${number} GREATER 10 )</tt> expands to <tt>IF( 4 GREATER 10 )</tt>, and we hope that <tt>4</tt> is not the name of a variable, so CMake tests if 4 is greater than 10.<br />
<br />
The first argument to the SET command is a variable name, not a substitution. SET wants to know the name of the variable to set, not the variable's current value. (This is different from Perl, which does not perform substitution.) It remains legitimate to use a substitution if the name of the variable that you want to set is the value of another variable:<br />
<br />
SET( varname number ) # sets varname to "number"<br />
SET( ${varname} 4 ) # sets number to "4"<br />
<br />
== CMake may access environment variables. ==<br />
You can also substitute the value of an environment variable. The syntax is $ENV{''name''}.<br />
<br />
MESSAGE( "Your Unix home directory is $ENV{HOME}." )<br />
<br />
Note that "ENV" is the only permitted hash (or map or dictionary, or your name for a set of key-value pairs). If you attempt to access another hash, then CMake will give an error:<br />
<br />
MESSAGE( $hi{there} )<br />
# causes error "Key hi is not used yet. For now only $ENV{..} is allowed"<br />
<br />
Yes, it is possible to set an environment variable:<br />
<br />
SET( ENV{PATH} /bin:/usr/bin ) # use a minimal PATH<br />
<br />
== Recursive subsitutions permit indirect variables. ==<br />
CMake can handle recursive substitutions, so that you may let one variable contain the name (or part of the name) of another variable:<br />
<br />
SET( varname x )<br />
SET( x 6 )<br />
MESSAGE( "${varname} is ${${varname}}" ) # displays "x is 6"<br />
<br />
It is not necessary to employ a workaround like "STRING( CONFIGURE ... )".<br />
<br />
== TODO ==<br />
* Describe ELSE and ELSEIF.<br />
* Describe FOREACH and MACRO on this page. These commands provide constant parameters, not variables; demonstrate that you cannot SET them. Explain the important rule, ''constant expansion happens before variable expansion''. This rule has consequences when your parameter contains "${" somewhere.<br />
<br />
== History ==<br />
[[User:Kernigh|Kernigh]] began to write about the syntax of the language of CMake. At first, the information appeared in a wiki page "The Scripting Language of CMake", http://kernigh.pbwiki.com/CMake. Then Kernigh moved the syntax information to this page at the Kitware Public Wiki.</div>Shdwjkhttps://public.kitware.com/Wiki/index.php?title=CMake_FAQ&diff=16249CMake FAQ2009-08-13T12:21:29Z<p>Shdwjk: /* How do I generate an executable, then use the executable to generate a file? */ -- corrected spelling of accepts</p>
<hr />
<div>== General information and availability ==<br />
=== What is CMake? ===<br />
CMake is a cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform-independent and compiler-independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. CMake is quite sophisticated: it is possible to support complex environments requiring system configuration, preprocessor generation, code generation, and template instantiation. Please go to http://www.cmake.org/HTML/About.html to learn more about CMake.<br />
<br />
=== What is the current release? ===<br />
The latest release of CMake is always available at: http://www.cmake.org/HTML/Download.html<br />
<br />
From there, you can fetch CMake binaries for Windows or several Unix variants, or you can download the source code of CMake.<br />
<br />
You can also access nightly development through CVS; see http://www.cmake.org/HTML/Download.html for more information. You may also browse the [http://www.cmake.org/cgi-bin/viewcvs.cgi/?root=CMake cvs repository online].<br />
<br />
=== I found a Bug! What should I do? ===<br />
Please report the bug in our bug tracker: http://www.cmake.org/Bug<br />
<br />
Please make sure to look at the old bugs not to include duplicates, include detailed instructions of the bug and how to reproduce it.<br />
<br />
=== I want a new feature in CMake. What should I do? ===<br />
Report a feature request in our Bug tracker http://www.cmake.org/Bug<br />
<br />
Please make sure to look at the old feature requests not to include duplicates, include detailed instructions of the feature and proposed implementation.<br />
<br />
=== What is the most recent version covered by the Mastering CMake book? ===<br />
A new edition of the [http://www.kitware.com/products/cmakebook.html Mastering CMake] book has been released which documents CMake 2.6.<br />
<br />
The following features have been added since printing the book:<br />
<br />
* New INSTALL command (cmake --help-command INSTALL)<br />
* New LIST command (cmake --help-command LIST)<br />
* Updated FIND_PATH, FIND_PROGRAM, and FIND_FILE commands to be more powerful (cmake --help-command FIND_PATH)<br />
* RPATH and Mac OS X install_name support (cmake --help-command SET_TARGET_PROPERTIES)<br />
* CPack Beta (not finished or documented)<br />
* EXECUTE_PROCESS was added and replaces EXEC_PROGRAM<br />
* Other changes have been bug fixes and internal CMake restructuring<br />
<br />
=== Where can I find searchable CMake Mailing Archives? ===<br />
There exists at list those ones:<br />
* [http://dir.gmane.org/gmane.comp.programming.tools.cmake.user cmake on Gmane]<br />
* [http://www.mail-archive.com/cmake@cmake.org/ http://www.mail-archive.com/cmake@cmake.org/]<br />
* [http://marc.info/?l=cmake http://marc.info/?l=cmake]<br />
* Use google ''site'' keyword in order to search directly in the CMake browsable ML:<br />
site:http://www.cmake.org/pipermail/cmake/ <search terms><br />
<br />
== Running CMake ==<br />
<br />
=== Is there an option to produce more 'verbose' compiling? ===<br />
Set CMAKE_VERBOSE_MAKEFILE to ON. This will make generator to produce all outputs, including compiler lines.<br />
<br />
If you are on Windows using Borland or NMake Makefiles, then you will see lines like:<br />
<br />
cl @c:\DOCUME~1\ANDY~1.KIT\LOCALS~1\Temp\nma03504<br />
<br />
The reason for this is that Borland and Microsoft Visual Studio make programs have limitation on the length of command strings. They overcome this limitation by writing arguments to the file and then pass file to the program.<br />
<br />
If you actually want to see what the command looks like, set CMAKE_START_TEMP_FILE and CMAKE_END_TEMP_FILE to "".<br />
<br />
On Makefile generators, there is a shortcut by setting Makefile variable VERBOSE to 1. For example on UNIX:<br />
<br />
make VERBOSE=1<br />
<br />
and Windows:<br />
nmake /S force silent mode, overrides (CMAKE_VERBOSE_MAKFILE)<br />
<br />
=== Is there a way to skip checking of dependent libraries when compiling? ===<br />
<br />
'''Using the Makefile Generator'''<br />
<br />
When using the Makefile generator under *nix you can append "/fast" to your target name. For example:<br />
<br />
make target_name/fast<br />
<br />
Under Windows use a backslash instead:<br />
<br />
make target_name\fast<br />
<br />
'''Using Visual Studio >= 7.1'''<br />
<br />
If you have Visual Studio .NET 7.1 or greater you can use the native option to right click on a project and choose to build just that project.<br />
<br />
'''Using Visual Studio <= 7.0'''<br />
<br />
CMake doesn't try to compile all dependent libraries when you compile a library but it will do so for binary targets. You can't avoid this however you can take advantage of CTRL+F7 to manually compile a source file for the affected target and then relink the target by right clicking on it and choosing Link. You'll have to ensure that all dependent libraries are made up-to-date however or suffer through Visual's slow check.<br />
<br />
=== I set a cmake variable in my environment, but it didn't change anything. Why? ===<br />
CMake build settings are stored in the CMake cache corresponding to a project's build tree. They are called CMake "cache entries" and have no relation to your command shell's environment variables. Use a CMake GUI (CMakeSetup on Windows or ccmake on UNIX) or the wizard mode (cmake -i) to edit cache entries. Initial values may also be specified for a build by using the -D command line argument to cmake when it is first run to produce a new build tree.<br />
<br />
=== I change CMAKE_C_COMPILER in the GUI but it changes back on the next configure step. Why? ===<br />
Once a build tree is created with a given compiler it cannot be changed. There are a variety of implementation reasons for this policy. In order to choose a different compiler create a new build tree and set the CC and CXX environment variables to the compiler you want before running CMake.<br />
<br />
NOTE: While I don't know what the preferred method of doing it is, I do know that the advice above (to set CC and CXX env vars) is in direct conflict with advice somewhere else that says not to use env vars to control CMAKE... Hopefully someone that knows a little more than I will fix this discrepancy.<br />
<br />
NOTE2: You could pass in e.g. <tt>-D CMAKE_C_COMPILER_INIT:STRING=mycc</tt> on the command line, or set the same variable inside a listfile (before any PROJECT() or ENABLE_LANGUAGE() command). Might that be what you're getting at?<br />
<br />
=== In CCMake, typing full paths is tedious. Is there a better way? ===<br />
Since CMake 1.6, you can use tab completion in the path entries in CCMake. All you do is type first couple of characters and press <TAB> key. CCMake will examine the current typed path and try to expand it to some existing path. If that is possible, it will do it. If not, it will not do anything.<br />
<br />
For example:<br />
<br />
/usr/loc<TAB><br />
<br />
will expand to<br />
<br />
/usr/local/<br />
<br />
<br />
<br />
== Out-of-source build trees ==<br />
<br />
=== What is an "out-of-source" build? ===<br />
When your build generates files, they have to go somewhere. An in-source build puts them in your source tree. An out-of-source build puts them in a completely separate directory, so that your source tree is unchanged.<br />
<br />
In the first example, an in-place build is performed, i.e., the binaries are placed in the same directory as the source code.<br />
<br />
cd Hello<br />
ccmake .<br />
make<br />
<br />
In the second example, an out-of-place build is performed, i.e., the source code, libraries, and executables are produced in a directory separate from the source code directory(ies).<br />
<br />
mkdir HelloBuild<br />
cd HelloBuild<br />
ccmake ../Hello<br />
make<br />
<br />
Out-of-source builds are recommended, as you can build multiple variants in separate directories, e.g., HelloBuildDebug, HelloBuildRelease.<br />
<br />
Note: Before performing an out-of-source build ensure that any possible CMake generated in-source build information is removed from the source directory, e.g., CMakeFiles directory, and CMakeCache.txt.<br />
<br />
=== I run an out-of-source build but CMake generates in-source anyway. Why? ===<br />
This means that there is a CMakeCache.txt file in the source tree, possibly as part of an existing in-source build. If CMake is given the path to a directory with a CMakeCache.txt file, it assumes the directory is a build tree. Therefore if one runs "cmake ../mysrc" to build out-of-source but there is a mysrc/CMakeCache.txt file then cmake will treat mysrc as the build tree.<br />
<br />
This is a side-effect of the feature that allows "cmake ." to be used to regenerate a build tree. The behavior will not be changed because mixing in-source and out-of-source builds is not safe anyway (configured headers may be found in the wrong place).<br />
<br />
=== Why does CMake use full paths, or can I copy my build tree? ===<br />
CMake uses full paths because:<br />
<br />
# configured header files may have full paths in them, and moving those files without re-configuring would cause upredictable behavior.<br />
# because cmake supports out of source builds, if custom commands used relative paths to the source tree, they would not work when they are run in the build tree because the current directory would be incorrect.<br />
# on Unix systems rpaths might be built into executables so they can find shared libraries at run time. If the build tree is moved old executables may use the old shared libraries, and not the new ones.<br />
<br />
Can the build tree be copied or moved?<br />
<br />
The short answer is NO. The reason is because full paths are used in CMake, see above. The main problem is that cmake would need to detect when the binary tree has been moved and rerun. Often when people want to move a binary tree it is so that they can distribute it to other users who may not have cmake in which case this would not work even if cmake would detect the move.<br />
<br />
The workaround is to create a new build tree without copying or moving the old one.<br />
<br />
<br />
=== CMake does not generate a "make distclean" target. Why? ===<br />
Some build trees created with GNU autotools have a "make distclean" target that cleans the build and also removes Makefiles and other parts of the generated build system. CMake does not generate a "make distclean" target because CMakeLists.txt files can run scripts and arbitrary commands; CMake has no way of tracking exactly which files are generated as part of running CMake. Providing a distclean target would give users the false impression that it would work as expected. (CMake does generate a "make clean" target to remove files generated by the compiler and linker.)<br />
<br />
A "make distclean" target is only necessary if the user performs an in-source build. CMake supports in-source builds, but we strongly encourage users to adopt the notion of an out-of-source build. Using a build tree that is separate from the source tree will prevent CMake from generating any files in the source tree. Because CMake does not change the source tree, there is no need for a distclean target. One can start a fresh build by deleting the build tree or creating a separate build tree.<br />
<br />
(If a CMakeLists.txt uses ADD_CUSTOM_COMMAND to generate source files in the source tree, not the build tree, then in CMake 2.2 or higher "make clean" will remove them. See next question.)<br />
<br />
=== Running "make clean" does not remove custom command outputs. Why? ===<br />
In CMake 2.2 and higher custom command outputs should be removed by make clean. Make sure you are using at least this version. Prior to CMake 2.2 custom command outputs were not automatically added to the list of files to clean. In CMake 2.0 the developer can specify a list of files to be deleted. This can be done using SET_DIRECTORY_PROPERTIES setting property ADDITIONAL_MAKE_CLEAN_FILES to the list of files.<br />
<br />
We however strongly recommend using an "out-of-source" build which never writes any files to the source tree. Using a separate source and build tree greatly reduces the need for "make clean" and "make distclean" targets to clean away files that differ between builds.<br />
<br />
<br />
== Writing CMakeLists.txt ==<br />
<br />
=== How to have backward and forward compatibility? ===<br />
<br />
As of CMake 2.6 we employ a "Policy" mechanism to provide backwards compatibility.<br />
The basic requirement for projects is to include one line at the top of the highest CMakeLists.txt file:<br />
<br />
cmake_minimum_required(VERSION 2.6) # or other version<br />
<br />
This tells versions of CMake older than that specified that they are too old to build the project.<br />
They will report this information to the user.<br />
It also tells versions of CMake newer than that specified that the project may not be aware of policies introduced in later versions, which enables additional compatibility.<br />
For futher documentation, see<br />
<br />
* [[CMake_Policies|CMake Policy Mechanism]]<br />
* [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:cmake_policy cmake_policy() command]<br />
* [http://www.cmake.org/cmake/help/cmake2.6docs.html#section_Policies CMake 2.6 Policies]<br />
<br />
=== How do I get the current source or binary directory? ===<br />
The variable CMAKE_CURRENT_SOURCE_DIR contains the absolute path to your current source directory, while CMAKE_CURRENT_BINARY_DIR points to the equivalent binary directory.<br />
<br />
=== Why are my CMake variables not updated in the GUI after a SET command? ===<br />
The cache variables listed in the GUI when you press "Configure" are used to initialize the values seen by the code in CMakeLists.txt files.<br />
<br />
Changes made by the code are used during the configure step and seen by the generators but are not stored back into the cache. For example:<br />
<br />
SET(BUILD_SHARED_LIBS ON)<br />
<br />
will turn on building of shared libraries for the directory containing the command and all subdirectories, but the change will not appear in the GUI.<br />
<br />
You can use the CACHE and FORCE options on the SET command to change variables in a way that will be reflected in the GUI. Run<br />
<br />
cmake --help-command SET<br />
<br />
to see full instructions for the command.<br />
<br />
<br />
=== How can I change the default build mode and see it reflected in the GUI? ===<br />
Adapt the following commands in your CMakeList.txt (this example sets the Release<br />
With Debug Information mode):<br />
<pre><br />
IF(NOT CMAKE_BUILD_TYPE)<br />
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING<br />
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."<br />
FORCE)<br />
ENDIF(NOT CMAKE_BUILD_TYPE)<br />
</pre><br />
<br />
=== How do I generate an executable, then use the executable to generate a file? ===<br />
<br />
Create the generator executable by just adding a target:<br />
<br />
ADD_EXECUTABLE(generate generate.c)<br />
<br />
The rest of the process is simpler in CMake 2.6 and above than in previous versions.<br />
<br />
Use <code>ADD_CUSTOM_COMMAND</code> to specify a custom build rule for the file.<br />
(In this example we assume <code>generate</code> accepts the input and output files as arguments.)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT someoutput.txt<br />
COMMAND generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt<br />
)<br />
<br />
This tells CMake how to build the file but does not actually add a rule to the build system.<br />
Another target must require it.<br />
One may create a custom target explicitly for this rule:<br />
<br />
ADD_CUSTOM_TARGET(driver ALL DEPENDS someoutput.txt)<br />
<br />
or the file may be added as part of some other target:<br />
<br />
ADD_EXECUTABLE(product product.c someoutput.txt)<br />
<br />
<font color=#555555><br />
In CMake 2.4 and below the <code>generate</code> target may not be specified directly in the <code>COMMAND</code> option of <code>add_custom_command</code><br />
(but it can still be used in the <code>DEPENDS</code> option as of CMake 2.4).<br />
Instead use GET_TARGET_PROPERTY to obtain the location of the generated executable.<br />
Additionally, the output must always be specified by full path.<br />
<br />
GET_TARGET_PROPERTY(GENERATE_EXE generate LOCATION)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
COMMAND ${GENERATE_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt<br />
DEPENDS generate<br />
)<br />
</font><br />
<br />
=== How can I generate a source file during the build? ===<br />
The ADD_CUSTOM_COMMAND command lets you generate a source file that you can then include in another target. For example:<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c<br />
)<br />
ADD_EXECUTABLE(foo foo.c)<br />
<br />
This will create an executable by copying bar.c to foo.c and then compiling foo.c to produce foo. CMake allows you to put generate source files in the current source or binary directory, so we were careful to output foo.c to the current binary directory. When we add foo.c to foo, CMake will look in either directory for it. Even if foo.c does not yet exist, CMake is smart enough to notice that a custom command creates it. (For the file named as the OUTPUT, CMake has its GENERATED source file property set to true.)<br />
<br />
You can also use ADD_CUSTOM_COMMAND when the<br />
[[CMake_FAQ#How_do_I_generate_an_executable.2C_then_use_the_executable_to_generate_a_file.3F|generator command is another executable in the same project]].<br />
<br />
Sometimes, the program doing the generation may generate multiple output files that each need to be part of the build. CMake 2.4 or higher supports having multiple files listed in the OUTPUT section. For example, suppose you had a program that read input.txt and generated three files output1.cpp, output2.h, and output3.cpp, and that those three files needed to be compiled into an executable program. The cmake list file for that would look like this:<br />
<br />
PROJECT(FOO)<br />
# make sure cmake addes the binary directory for the project to the include path<br />
INCLUDE_DIRECTORIES(${FOO_BINARY_DIR})<br />
# add the executable that will do the generation<br />
ADD_EXECUTABLE(my_generator my_generator.cxx)<br />
GET_TARGET_PROPERTY(MY_GENERATOR_EXE my_generator LOCATION)<br />
# add the custom command that will generate all three files<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp<br />
COMMAND ${MY_GENERATOR_EXE} ${FOO_BINARY_DIR} ${FOO_SOURCE_DIR}/input.txt<br />
DEPENDS my_generator<br />
MAIN_DEPENDENCY ${FOO_SOURCE_DIR}/input.txt<br />
)<br />
# now create an executable using the generated files<br />
ADD_EXECUTABLE(generated<br />
${FOO_BINARY_DIR}/output1.cpp<br />
${FOO_BINARY_DIR}/output2.h<br />
${FOO_BINARY_DIR}/output3.cpp)<br />
<br />
CMake 2.4 allows you to generate a header file. Because generated headers often cause unnecessary rebuilds, you should try to avoid them; consider using the CONFIGURE_FILE command to prepare the header at CMake time. If you must generate a header file, use code like this:<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h<br />
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.h ${CMAKE_CURRENT_BINARY_DIR}/foo.h<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.h<br />
)<br />
ADD_EXECUTABLE(foo foo.c ${CMAKE_CURRENT_BINARY_DIR}/foo.h)<br />
<br />
This is like the first example above, except that it generates a header instead of a C file. The header might not exist when the build system scans foo.c's dependencies, so there is no way for CMake to know that this target requires foo.h unless we can tell it that foo.h may exist in the future. We give CMake this knowledge by listing the generated header file in the set of source files for the target. (This requires CMake 2.4. Previous versions of CMake required use of the OBJECT_DEPENDS source file property.)<br />
<br />
=== How can I add a dependency to a source file which is generated in a subdirectory? ===<br />
<br />
Rules created with <code>ADD_CUSTOM_COMMAND</code> as [[CMake_FAQ#How_can_I_generate_a_source_file_during_the_build.3F|above]] have scope only in the directory in which they are specified.<br />
If the generated file is needed in another directory, a target-level dependency needs to be added.<br />
Create a target in the subdirectory with the custom rule in order to drive it:<br />
<br />
# subdir/CMakeLists.txt<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c<br />
)<br />
ADD_CUSTOM_TARGET(generate_foo DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.c)<br />
<br />
Now other targets can depend on the target from the subdirectory:<br />
<br />
# CMakeLists.txt<br />
ADD_SUBDIRECTORY(subdir)<br />
# Create the executable.<br />
ADD_EXECUTABLE(generated ${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c)<br />
# Tell CMake the source won't be available until build time.<br />
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c PROPERTIES GENERATED 1)<br />
# Make sure the source is generated before the executable builds.<br />
ADD_DEPENDENCIES(generated generate_foo)<br />
<br />
=== I use EXEC_PROGRAM but the result is not set in subdirectories. Why? ===<br />
<br />
An unfortunate holdover from ancient CMake versions is that certain commands are "inherited" into subdirectories and others are not. EXEC_PROGRAM is not inherited. What this means is that when the listfile code from a parent directory executes in a subdirectory the EXEC_PROGRAM command is left out. Therefore the code executes differently. This problem was fixed in CMake 2.2, but for older versions you will have to cache the result:<br />
<br />
<pre><br />
EXEC_PROGRAM(my-program OUTPUT_VARIABLE MY_OUTPUT)<br />
SET(MY_OUTPUT "${MY_OUTPUT}" CACHE INTERNAL "")<br />
</pre><br />
<br />
This will store the result in a global location so it will be available in the subdirectory. Be sure to choose a descriptive name for MY_OUTPUT to avoid conflict in the global setting.<br />
<br />
=== How can I get or set environment variables? ===<br />
<br />
CMake names environment variables using an ENV prefix and surrounding the names in curly braces. Here is an example:<br />
<br />
<pre><br />
MESSAGE("$ENV{PATH}")<br />
</pre><br />
<br />
Reading variables will work in any version of CMake. Writing to them works in CMake 2.2 and higher using the following syntax:<br />
<br />
<pre><br />
SET(ENV{HELLO} "World")<br />
</pre><br />
<br />
Note that there is currently no way to tell apart an empty environment variable value from a variable that is not set at all.<br />
<br />
One should avoid using environment variables for controlling the flow of CMake code (such as in IF commands). The build system generated by CMake may re-run CMake automatically when CMakeLists.txt files change. The environment in which this is executed is controlled by the build system and may not match that in which CMake was originally run. If you want to control build settings on the CMake command line, you need to use cache variables set with the -D option. The settings will be saved in CMakeCache.txt so that they don't have to be repeated every time CMake is run on the same build tree.<br />
<br />
Also, environment variables SET in the CMakeLists.txt ''only'' take effect for cmake itself, so you cannot use this method to set an environment variable that a custom command might need.<br />
<br />
=== Why do I have unwanted semicolons ; in my compiler flags? ===<br />
CMake has a list data type. A list is stored as a string of semicolon-separated list elements. Whitespace separated arguments to a SET statement are interpreted as list elements. For instance, SET(var a b c d e) will give "var" a value of a;b;c;d;e and this list can be used by other CMake commands. However, if you pass ${var} to a non-CMake external tool, such as a compiler's command line, you are passing a;b;c;d;e which is not what you want. Instead you either need to pass "${var}", so that the list will be converted to a whitespace-separated string, or you need to SET(var "a b c d e") in the 1st place so that you're working with a string, not a list.<br />
<br />
=== How can I get quoting and escapes to work properly? ===<br />
If you want to escape a character in CMake, you use "\", like in C code. For example, if you wanted to have a quote embedded in a string you would do this: "\"". However, each level of CMake that processes your code will need one level of escaping to work. So, if you configure a file that is read by cmake or cpack and you want to do the same thing, you would do "\\\"". You would still need to escape the " for the first cmake that processes the string. However, this time, you would want to also escape a '\' as well. This would leave the next level of processing with "\"". Also, for custom commands that may get passed to a shell, it maybe required to do escaping for that shell.<br />
<br />
=== Isn't the "Expression" in the "ELSE (Expression)" confusing? ===<br />
Traditional CMakeLists.txt files prior to 2.6.0, require the following syntax. In the IF syntax, the ELSE section requires the same (Expression) as the IF section. This sometimes can make the script kind of hard to follow, take the short example below:<br />
<br />
IF(WIN32)<br />
...do something...<br />
ELSE(WIN32)<br />
...do something else...<br />
ENDIF(WIN32)<br />
<br />
You might think that the ELSE section, here containing "...do something else...", is for the WIN32 portion of the script. That is not so! It is actually handling the NOT WIN32 section.<br />
<br />
As of CMake 2.6.0 the ELSE() and ENDIF() constructs can be empty. The same is true for closing constructs on ENDMACRO(), ENDFUNCTION(), and ENDFOREACH(). If you require 2.4.x compatibility, you can enable the CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS option on CMake 2.4.3 or greater. This option is superfluous on CMake 2.6.0 or greater.<br />
<br />
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)<br />
<br />
IF(WIN32)<br />
...do something...<br />
ELSEIF(APPLE)<br />
...do something else...<br />
ELSE()<br />
...do something else...<br />
ENDIF()<br />
<br />
=== Which regular expressions are supported by CMake? ===<br />
When using MATCHES or MATCHALL in an IF command, or using any of the STRING(REGEX ...) commands, CMake expects regular expressions, not globs (wild cards). CMake uses the same regular expression engine above all platforms. Here are the meanings of the metacharacters:<br />
<br />
^ Matches at beginning of a line<br />
$ Matches at end of a line<br />
. Matches any single character<br />
[ ] Matches any character(s) inside the brackets<br />
[^ ] Matches any character(s) not inside the brackets<br />
- Matches any character in range on either side of a dash<br />
| Matches a pattern on either side of the |<br />
* Matches preceding pattern zero or more times<br />
+ Matches preceding pattern one or more times<br />
? Matches preceding pattern zero or once only<br />
() Saves a matched expression and uses it in a later match<br />
<br />
Example: "[-][L]([^ ;])+" matches all strings beginning with -L and ending with a space or a semicolon, the usual linkdirs under Linux.<br />
<br />
Here is how to catch a part of a string. The variable test is filled with some content, and then we want to catch the "me":<br />
<br />
SET(test "hello world ! catch: me if you can")<br />
STRING(REGEX REPLACE ".*catch: ([^ ]+).*" "\\1" result "${test}" )<br />
MESSAGE(STATUS "result= ${result}")<br />
<br />
This is slightly tricky. The part inside the brackets is available in \\1 . CMake will copy the variable test to the variable result, but then it will replace everything that the regular expression matches with \\1. This means the first regular expression has to match the whole string and the part we want to catch has to be put in parens.<br />
<br />
-- result= me<br />
<br />
For those of you who know Perl, the equivalent Perl code could be:<br />
<br />
$test = "hello world ! catch: me if you can";<br />
$result = $test;<br />
$result =~ s/.*catch: ([^ ]+).*/$1/;<br />
print "-- result= $result\n";<br />
<br />
There are other ways to do this in Perl, but this is how we do it in CMake because \\1 does not become a variable like $1 does in perl, so there is no SET(result ${\\1}) in CMake.<br />
<br />
<br />
=== How to convert a semicolon separated list to a whitespace separated string? ===<br />
<br />
set(foo<br />
abc.c<br />
abc.b<br />
abc.a<br />
)<br />
<br />
foreach(arg ${foo})<br />
set(bar "${bar} ${arg}")<br />
endforeach(arg ${foo})<br />
<br />
message("foo: ${foo}")<br />
message("bar: ${bar}")<br />
<br />
=== How can I build multiple modes without switching ? ===<br />
To build multiple modes (e.g. Debug and Release) in one shot without constantly running cmake -DCMAKE_BUILD_TYPE=Debug and cmake -DCMAKE_BUILD_TYPE=Release in source tree create a directory for builds eg.:<br />
<br />
<pre><br />
Project-directory/<br />
/Build<br />
</pre><br />
<br />
Inside you can place as many target directories for out-of-source build modes as you want, e.g.:<br />
<br />
<pre><br />
Project-directory/<br />
/Build<br />
/Debug<br />
/Release<br />
</pre><br />
<br />
In each of these directories issue a command (assuming that you have CMakeLists.txt directly in Project-directory)<br />
<br />
<pre><br />
cmake -DCMAKE_BUILD_TYPE=type_of_build ../../<br />
</pre><br />
<br />
to create a cmake cache configured for requested build type.<br />
<br />
Now you can make each build just by entering appropriate directory and executing a make command.<br />
<br />
=== How can I extend the build modes with a custom made one ? ===<br />
The following code snipet (taken from a CMakeLists.txt) adds a Maintainer mode:<br />
<pre><br />
SET( CMAKE_CXX_FLAGS_MAINTAINER "-Wall -Wabi" CACHE STRING<br />
"Flags used by the C++ compiler during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_C_FLAGS_MAINTAINER "-Wall -pedantic" CACHE STRING<br />
"Flags used by the C compiler during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER<br />
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING<br />
"Flags used for linking binaries during maintainer builds."<br />
FORCE )<br />
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER<br />
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING<br />
"Flags used by the shared libraries linker during maintainer builds."<br />
FORCE )<br />
MARK_AS_ADVANCED(<br />
CMAKE_CXX_FLAGS_MAINTAINER<br />
CMAKE_C_FLAGS_MAINTAINER<br />
CMAKE_EXE_LINKER_FLAGS_MAINTAINER<br />
CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )<br />
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs<br />
SET( CMAKE_BUILD_TYPE "" CACHE STRING<br />
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Maintainer."<br />
FORCE )<br />
</pre><br />
Notes: The flags used in this example are specific to GCC. Change them as needed for your project. Additionally the SET(CMAKE_BUILD_TYPE) command will override<br />
a CMAKE_BUILD_TYPE previously set in the CMakeLists.txt.<br />
<br />
=== Why does <code>foreach</code> skip empty values? ===<br />
<br />
The code in question is of the form<br />
<br />
set(var "a;b;;c;d") # list 'a', 'b', '', 'c', 'd'<br />
foreach(v ${var})<br />
# v=a, v=b, v=c, v=d, one at a time<br />
endforeach()<br />
<br />
and the loop variable 'v' never attains the empty-string value ''.<br />
This is because the <code>${var}</code> syntax is an unquoted argument so the CMake language expands the list and removes the empty value.<br />
The foreach command does not even see the empty value.<br />
One can verify this because the code<br />
<br />
foreach(v a b "" c d)<br />
...<br />
endforeach()<br />
<br />
will see the empty value.<br />
<br />
=== Does CMake support precompiled headers? ===<br />
<br />
Yes and no. Every platform does precompiled headers a bit differently, and there is currently no first-class interface provided by CMake and implemented on every platform.<br />
However, CMake does provide enough primitives for projects to use precompiled headers on specific platforms.<br />
Our issue tracker has a [http://www.cmake.org/Bug/view.php?id=1260 feature request] with attachements providing user-contributed helper macros for some platforms.<br />
<br />
== Writing FindXXX.cmake files ==<br />
<br />
=== What are the rules to write a FindXXX.cmake file? ===<br />
<br />
Let's follow the instructions and the advices in the <br />
Modules/readme.txt [http://www.cmake.org/cgi-bin/viewcvs.cgi/Modules/readme.txt?root=CMake&view=markup]<br />
file located in the CVS repository.<br />
<br />
=== Why does find_library look in system directories before its PATHS option? ===<br />
<br />
The code in question is often of the form<br />
<br />
find_library(FOO_LIBRARY NAMES foo PATHS /opt/foo/lib)<br />
<br />
CMake will find "<code>/usr/lib/libfoo.so</code>" instead of "<code>/opt/foo/lib/libfoo.so</code>" if both exist.<br />
The reason is that /opt/foo/lib is a <i>hard-coded guess</i> of the location.<br />
The documentation of <code>[http://www.cmake.org/cmake/help/cmake2.6docs.html#command:find_library find_library]</code> specifies the search order.<br />
User, project, and system configuration variables are always more local than hard-coded guesses and should override them, so<br />
the PATHS option is used last.<br />
<br />
Some find-modules compute probable locations based on other information <i>available from the system</i> such as a project-specific environment variable.<br />
The HINTS option (CMake 2.6 and higher) takes precedence over system directories specifically for this case:<br />
<br />
file(TO_CMAKE_PATH "$ENV{FOO_LIB_DIR}" FOO_LIB_DIR)<br />
find_library(FOO_LIBRARY NAMES foo HINTS ${FOO_LIB_DIR})<br />
<br />
CMake will find "<code>$ENV{FOO_LIB_DIR}/libfoo.so</code>" before "<code>/usr/lib/libfoo.so</code>".<br />
<br />
== Finding and using external packages ==<br />
<br />
=== How do I use CMake to generate SWIG wrapper libraries? ===<br />
<br />
CMake version 2 includes a module that supports the generation of SWIG wrapper libraries. The SWIG package defines the following macros: SWIG_ADD_MODULE and SWIG_LINK_LIBRARIES.<br />
<br />
<pre><br />
# This example shows how to use python<br />
# Currently these languages have been tested:<br />
# perl tcl ruby php4 pike<br />
<br />
FIND_PACKAGE(SWIG REQUIRED)<br />
INCLUDE(${SWIG_USE_FILE})<br />
<br />
FIND_PACKAGE(PythonLibs)<br />
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})<br />
<br />
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})<br />
<br />
SET(CMAKE_SWIG_FLAGS "")<br />
<br />
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)<br />
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")<br />
SWIG_ADD_MODULE(example python<br />
example.i example.cxx)<br />
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})<br />
<br />
</pre><br />
<br />
<pre><br />
# This example shows how to use tcl<br />
PROJECT(TCL_WRAP)<br />
SET ( MODULE_NAME project )<br />
SET ( INTERFACE_FILES project.i)<br />
SET ( SRC_FILES Vertex.h Vertex.cxx Shapes.h Shapes.cxx )<br />
<br />
FIND_PACKAGE(SWIG REQUIRED)<br />
INCLUDE(${SWIG_USE_FILE})<br />
<br />
# Look for TCL<br />
INCLUDE_DIRECTORIES(${TCL_INCLUDE_PATH})<br />
<br />
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80<br />
PATHS /usr/lib /usr/local/lib)<br />
IF (TCL_LIBRARY)<br />
TARGET_ADD_LIBRARY (${MODULE_NAME} TCL_LIBRARY)<br />
ENDIF (TCL_LIBRARY)<br />
<br />
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})<br />
<br />
SET(CMAKE_SWIG_FLAGS "-c++")<br />
<br />
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CPLUSPLUS ON)<br />
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CMAKE_SWIG_FLAGS "-includeall")<br />
SWIG_ADD_MODULE(${MODULE_NAME} tcl ${INTERFACE_FILES} ${SRC_FILES})<br />
SWIG_LINK_LIBRARIES(${MODULE_NAME} ${TCL_LIBRARIES})<br />
</pre><br />
<br />
=== How do I use CMake to build LaTeX documents? ===<br />
Use the following approach. Note that you have to set LATEX_COMPILE to LaTeX executable, DVIPDF_COMPILE to dvi to pdf converter. Also, the LaTeX source is TDocument.tex and the result is called TDocument.pdf. Note that this uses commands in CMake version 1.8 or later.<br />
<br />
PROJECT(Document)<br />
IF(LATEX_COMPILE)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.tex<br />
COMMAND ${LATEX_COMPILE} <br />
ARGS ${Document_SOURCE_DIR}/TDocument.tex <br />
)<br />
ENDIF(LATEX_COMPILE)<br />
<br />
IF(DVIPDF_COMPILE)<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi <br />
COMMAND ${DVIPDF_COMPILE}<br />
ARGS ${Document_SOURCE_DIR}/TDocument.dvi<br />
)<br />
ENDIF(DVIPDF_COMPILE)<br />
<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf<br />
)<br />
<br />
The following uses commands in CMake version 2.0 and later<br />
<br />
PROJECT(Document)<br />
# <br />
# Find LaTeX<br />
#<br />
FIND_PACKAGE(LATEX)<br />
<br />
IF(LATEX_COMPILER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS ${Document_SOURCE_DIR}/TDocument.tex<br />
DEPENDS ${Document_SOURCE_DIR}/TDocument.tex<br />
COMMENT "Tex2dvi"<br />
)<br />
<br />
IF(DVIPS_CONVERTER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.ps<br />
COMMAND ${DVIPS_CONVERTER}<br />
ARGS ${Document_BINARY_DIR}/TDocument.dvi<br />
-o ${Document_BINARY_DIR}/TDocument.ps<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi<br />
COMMENT "dvi2ps"<br />
)<br />
<br />
IF(PS2PDF_CONVERTER)<br />
ADD_CUSTOM_COMMAND( <br />
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf<br />
COMMAND ${PS2PDF_CONVERTER}<br />
ARGS ${Document_BINARY_DIR}/TDocument.ps<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.ps<br />
COMMENT "ps2pdf"<br />
)<br />
<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf<br />
)<br />
ENDIF(PS2PDF_CONVERTER)<br />
ENDIF(DVIPS_CONVERTER)<br />
ENDIF(LATEX_COMPILER)<br />
<br />
=== How do I get LaTeX references to be correct? ===<br />
When your latex document contains references (e.g. \ref{...} command) you get to run two passes of latex. In the<br />
most general case, i.e. when additionally your document uses a bibtex bibliography, you shall need three<br />
passes of latex (and one pass of bibtex):<br />
# latex (first pass: for bibtex to have an .aux file)<br />
# bibtex (for generating the .bbl file)<br />
# latex (second pass)<br />
# latex (third pass)<br />
<br />
The following code snippet illustrates how you can "pervert" the bibtex and latex generated<br />
auxilary files (.aux, .log, .dvi, .bbl...) to create an "artificial" set of CMake dependencies.<br />
The side-effect of those dependencies should hopefully be the above described sequence of calls<br />
to latex and bibtex<br />
<pre><br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux<br />
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/UsersManual.tex<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (first pass)"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux<br />
COMMAND ${BIBTEX_COMPILER}<br />
ARGS -terse ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Bibtex"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (second pass)"<br />
)<br />
<br />
ADD_CUSTOM_COMMAND(<br />
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl<br />
${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi<br />
COMMAND ${LATEX_COMPILER}<br />
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual<br />
COMMENT "Latex (third pass)"<br />
)<br />
# Eventually trigger the whole process<br />
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo<br />
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log<br />
)<br />
</pre><br />
<br />
=== How can I set TEXINPUTS for a LaTeX compilation? ===<br />
First note that most often you can avoid using TEXINPUTS by copying all the necessary files (.tex source file and<br />
included graphic files e.g. .eps files) from your PROJECT_SOURCE_DIR hirarchy to your PROJECT_BINARY_DIR subdir<br />
[refer to CONFIGURE_FILE with the COPYONLY flag set for copying files]. Since by default latex uses the current working directory as value for TEXINPUTS you should be all set. As expected, this trick is quick AND dirty since your<br />
concerned PROJECT_BINARY_DIR subdir now contains files that are NOT generated by CMake (in the sense that those<br />
files are not the result of a system command but were merely duplicated)... <br />
<br />
If you consider it is cleaner or easier to define a TEXINPUTS environment variable [the latex command probably<br />
misses a -I flag] you can find an example in the InsightDocuments cvs archive (refer to the section "cvs access"<br />
near the bottom of Kitware's ITK download page) or use google with keywords "ITK_TEXINPUTS CONFIGURE_FILE".<br />
Look at InsightDocuments/CourseWare/Training/Vis2003/Latex/CMakeLists.txt and search for e.g. "LaTeXWrapper.sh.in".<br />
<br />
Roughly the mechanism goes:<br />
* SET ITK_TEXINPUTS with the desired TEXINPUTS<br />
* CONFIGURE_FILE "InsightDocuments/CourseWare/Training/Vis2003/LaTeXWrapper.sh.in" which generates an sh shell script setting the shell variable TEXINPUTS prior to running the latex command<br />
* use ADD_CUSTOM_COMMAND to invoke this shell script<br />
This very example is Win32 portable (except that LaTeXWrapper.bat.in generates a .bat shell script)<br />
<br />
== Library questions ==<br />
<br />
=== Can I build both shared and static libraries with one ADD_LIBRARY command? ===<br />
<br />
No. Each library you build must have a unique target name, i.e. the "libname" field of the ADD_LIBRARY command. That way, CMake can track dependencies separately for each library. Libraries can have the same OUTPUT_NAME, see the SET_TARGET_PROPERTIES command, but this is not the default.<br />
<br />
=== Does that mean I have to build all my library objects twice, once for shared and once for static?! I don't like that! ===<br />
<br />
In practice, most libraries have different defines and compiler flags for the shared vs. static cases. So you would have to build all your library objects twice anyways. However, if you happen to have '''''exactly''''' the same defines and compiler flags for the shared vs. static cases...<br />
<br />
...if you're using Linux and a GCC-style linker, you could do the following. Note that for this to work correctly on linux, the zzSTATIC source files should have been compiled with "-fPIC" to ensure they will work in a shared library.<br />
<br />
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)<br />
ADD_LIBRARY(zzSTATIC STATIC -fPIC)<br />
ADD_LIBRARY(zzDYNAMIC SHARED)<br />
TARGET_LINK_LIBRARIES(zzDYNAMIC -Wl,-whole-archive zzSTATIC -Wl,-no-whole-archive)<br />
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)<br />
<br />
...if you want a cross-platform approach that works on all compilers, not just GCC or Linux, you could extract the locations of previously built object files and insert them directly into the libraries that need them. This is documented in [http://www.cmake.org/Bug/view.php?id=5155 CMake Feature Request #5155: standard way to locate object files]. Unfortunately this approach relies on CMake's internal implementation, and that implementation could change in the future, breaking your code.<br />
<br />
=== How do I make my shared and static libraries have the same root name, but different suffixes? ===<br />
Set the OUTPUT_NAME of your shared and static libraries to the same thing.<br />
<br />
ADD_LIBRARY(foo SHARED ${foo_sources})<br />
ADD_LIBRARY(foo-static STATIC ${foo_sources})<br />
// The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it.<br />
// The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it.<br />
SET_TARGET_PROPERTIES(foo-static PROPERTIES OUTPUT_NAME "foo")<br />
<br />
If you are building your shared and static libraries in the same directory, you will also need the following to keep your shared and static libraries from clobbering each other during the build.<br />
<br />
SET_TARGET_PROPERTIES(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1)<br />
SET_TARGET_PROPERTIES(foo-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)<br />
<br />
=== How do I rename a library after it has already been built? ===<br />
You don't rename it. It's been built! Its name is whatever CMakeLists.txt says it's supposed to be.<br />
<br />
Perhaps you want to copy the library to a different name. But, are you sure that's what you want to do? You could just change the name in your ADD_LIBRARY command or change its OUTPUT_NAME property using SET_TARGET_PROPERTY(). If you really really want to copy the library to a different name, try:<br />
<br />
GET_TARGET_PROPERTY(LIB_NAME Foo LOCATION)<br />
GET_TARGET_PROPERTY(Bar_prefix Foo PREFIX)<br />
GET_TARGET_PROPERTY(Bar_suffix Foo SUFFIX)<br />
SET(NEW_LIB_NAME ${Bar_prefix}Bar${Bar_suffix})<br />
<br />
ADD_CUSTOM_COMMAND(<br />
TARGET Foo<br />
POST_BUILD<br />
COMMAND ${CMAKE_COMMAND} -E copy ${LIB_NAME} ${NEW_LIB_NAME}<br />
)<br />
<br />
On Windows you may also want to copy the .dll import lib, using the same approach as above, but with IMPORT_PREFIX and IMPORT_SUFFIX. ''Problem: LOCATION only refers to 1 file, the .dll. What is a simple way to get the location of the import lib? Could provide a complicated way, but that's annoying.''<br />
<br />
=== Does CMake support "convenience" libraries? ===<br />
No. CMake does not currently support convenience libraries. A "convenience" library, as GNU libtool calls it, is an archive of objects to be mixed into other libraries. Other libraries "link" to the convenience library, but the convenience library does not export any symbols; GNU libtool never installs the convenience library; no programs ever link to the convenience library.<br />
<br />
This does '''not''' mean that a project using convenience libraries cannot be converted to CMake. Instead the source files may be listed in each target that needs them. They will be built for each target separately using all the preprocessor definitions and flags configured for that target.<br />
<br />
=== Why are libraries linked to my shared library included when something links to it? ===<br />
This question arises when one has a library B which links to some library A. When a third target, say C, links to B, CMake will automatically include C to A also. When the libraries are static, then this is always necessary. When the libraries are shared, this is the default behavior provided by CMake. CMake 2.6 and above provide the target property "LINK_INTERFACE_LIBRARIES" (http://www.cmake.org/HTML/cmake-2.6.html#prop_tgt:LINK_INTERFACE_LIBRARIES) to specify the libraries that should be transitively included in the link by CMake. CMake 2.4 and below do not support the property.<br />
<br />
Something like the following will work in CMake 2.6:<br />
<br />
<pre><br />
set_target_properties(mylibrary<br />
PROPERTIES<br />
LINK_INTERFACE_LIBRARIES ""<br />
)<br />
</pre><br />
<br />
=== CMake dependency scanner ===<br />
<br />
CMake does not preprocess source files while scanning dependencies. Code like<br />
<pre><br />
#if 0<br />
# include "bla.h"<br />
#endif<br />
</pre><br />
will result in a dependency on "bla.h". This sometimes leads to source files recompiling unnecessarily but will not break the build.<br />
<br />
== Installation questions ==<br />
<br />
=== Does CMake's "make install" support DESTDIR? ===<br />
'''Yes''', especially when the build-system generator uses CMake's builtin support for installing files: Simply define the DESTDIR environment variable during installation and CMake will treat that value as the root of the file system for all installation paths; naturally, the DESTDIR path must be absolute.<br />
<br />
For example, if the Makefile generator is used, then all of the following are example usages of DESTDIR (perhaps assuming the bash shell for the last 2):<br />
<br />
(1) make install DESTDIR="/some/absolute/path"<br />
(2) make DESTDIR="/some/absolute/path" install<br />
(3) DESTDIR="/some/absolute/path" make install<br />
(4) export DESTDIR="/some/absolute/path<br />
make install<br />
<br />
=== Can I do "make uninstall" with CMake?===<br />
By default, CMake does not provide the "make uninstall" target, so you cannot do this. We do not want "make uninstall" to remove useful files from the system.<br />
<br />
If you want an "uninstall" target in your project, then nobody prevents you from providing one. You need to delete the files listed in install_manifest.txt file. Here is how to do it. First create file cmake_uninstall.cmake.in in the top-level directory of the project:<br />
<br />
<pre><br />
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")<br />
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")<br />
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")<br />
<br />
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)<br />
STRING(REGEX REPLACE "\n" ";" files "${files}")<br />
FOREACH(file ${files})<br />
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")<br />
IF(EXISTS "$ENV{DESTDIR}${file}")<br />
EXEC_PROGRAM(<br />
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""<br />
OUTPUT_VARIABLE rm_out<br />
RETURN_VALUE rm_retval<br />
)<br />
IF(NOT "${rm_retval}" STREQUAL 0)<br />
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")<br />
ENDIF(NOT "${rm_retval}" STREQUAL 0)<br />
ELSE(EXISTS "$ENV{DESTDIR}${file}")<br />
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")<br />
ENDIF(EXISTS "$ENV{DESTDIR}${file}")<br />
ENDFOREACH(file)<br />
</pre><br />
<br />
Then in the top-level CMakeLists.txt add the following logic:<br />
<br />
<pre><br />
CONFIGURE_FILE(<br />
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"<br />
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"<br />
IMMEDIATE @ONLY)<br />
<br />
ADD_CUSTOM_TARGET(uninstall<br />
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")<br />
</pre><br />
<br />
Now you will have an "uninstall" target at the top-level directory of your build tree.<br />
<br />
Instead of creating an "uninstall" target, Unix users could enter this command in the shell:<br />
<br />
xargs rm < install_manifest.txt<br />
<br />
== Distribution questions ==<br />
<br />
=== Where is "make dist"? ===<br />
<br />
CMake doesn't create a "make dist" target.<br />
<br />
=== What is the best way to distribute source code or binaries for a cmake-based project? ===<br />
<br />
For creating source or binary packages there is now [[CMake#CPack | CPack]] coming with CMake, see the <br />
[[ CMake#CPack | documentation]].<br />
<br />
Of course you can also use any other ways to create packages.<br />
<br />
== Platform-specific questions ==<br />
=== How do I build universal binaries on Mac OS X? ===<br />
Before running CMake with an empty build tree, set the CMAKE_OSX_ARCHITECTURES environment variable. It should be set to contain a ; separated list of architectures that you want in the binary. For example, for 32-bit PowerPC and Intel you would do this:<br />
<br />
CMAKE_OSX_ARCHITECTURES=ppc;i386<br />
<br />
If you wish to build both as 32 and 64 bit, do this:<br />
<br />
CMAKE_OSX_ARCHITECTURES=ppc;i386;ppc64;x86_64<br />
<br />
You can also set the same named CMake cache variable on an existing binary tree. This works with both makefiles and the Xcode generator. <br />
<br />
In addition, you can also set the CMAKE_OSX_SYSROOT variable to point to the sysroot (aka Mac OS SDK) to be used. CMake will attempt to pick one on your system, but it can be changed in the cache or via an environment variable before running CMake. The 10.4u SDK or later must be used to create a Universal Binary.<br />
<br />
Universal Binaries are essentially cross compilation and so you should avoid using TRY_RUN, especially for things like testing endianess or variable size because the result will only be correct for one architecture.<br />
<br />
Lastly, note that CTest is only able to test one architecture. See bug 6157.<br />
<br />
=== How can I apply resources on Mac OS X automatically? ===<br />
Using ADD_CUSTOM_COMMAND. For example, let's say you are creating executable MyExecutable, which needs the resources file Carbon.r. All you do is add a custom rule which is executed after the executable is linked:<br />
<br />
<pre><br />
ADD_EXECUTABLE(MyExecutable ${MyExecutable_SRCS})<br />
GET_TARGET_PROPERTY(MyExecutable_PATH MyExecutable LOCATION)<br />
<br />
IF(APPLE)<br />
FIND_PROGRAM(APPLE_RESOURCE Rez /Developer/Tools)<br />
IF(APPLE_RESOURCE)<br />
ADD_CUSTOM_COMMAND(TARGET MyExecutable POST_BUILD<br />
COMMAND ${APPLE_RESOURCE} Carbon.r -o ${MyExecutable_PATH})<br />
ENDIF(APPLE_RESOURCE)<br />
ENDIF(APPLE)<br />
</pre><br />
<br />
This will execute:<br />
<br />
/Developer/Tools/Rez Carbon.r -o /binary/path/MyExecutable<br />
<br />
after MyExecutable is linked.<br />
<br />
'Rez' may be located elsewhere on disk, depending on the version of Mac OS X and Xcode. You can use 'which Rez' in Terminal to find it's full path.<br />
<br />
=== Why does FIND_LIBRARY not find .DLL libraries under WIN32? ===<br />
For those who come from a Unix background to MS Windows:<br />
<br />
You never link directly to the .dll, you have to link against the import library .lib for the .dll.<br />
<br />
Linking against dynamic libraries (.dll under Windows) is quite different from linking against ELF shared objects (.so) under platforms like Linux or NetBSD. In Windows, there are two types of library, a static library and an import library (both confusingly use the .lib extension, however). In Windows, when you build an import library (A.lib) you will get a corresponding (A.dll) that you only need at runtime. At compile time you will need the import library.<br />
<br />
Conclusion: There is no need to find a .dll for linking. You only need to find the .lib import library.<br />
<br />
Some more details can be found here: [http://xenophilia.org/winvunix.html].<br />
<br />
=== Why am I getting a linker error to _mainCRTStartup under WIN32? ===<br />
Your program is a GUI application using WinMain (/subsystem:windows) and not a console application using main. You have to use the WIN32 option with the ADD_EXECUTABLE command.<br />
<br />
ADD_EXECUTABLE(exename WIN32 source1 source2 ... sourceN)<br />
<br />
The second argument to ADD_EXECUTABLE can be WIN32. This indicates that the executable, when compiled on Windows, is a Windows app (using WinMain) and not a console app (using main). Please note that on Unix platforms, CMake ignores the WIN32 and the compiler will use "main" in any case.<br />
<br />
=== Why do I get this error: nafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv ===<br />
<br />
This is because the application is using both the static and dll versions of the MFC library.<br />
To fix the problem, you can do the following:<br />
<br />
SET(CMAKE_MFC_FLAG 2) # force the IDE to use static MFC<br />
ADD_DEFINITIONS(-D_AFXDLL) # make sure if afx.h is included the dll MFC is used<br />
<br />
=== How to use MFC with CMake ===<br />
To use MFC, the CMAKE_MFC_FLAG variable must be set as follows:<br />
<br />
0: Use Standard Windows Libraries<br />
1: Use MFC in a Static Library<br />
2: Use MFC in a Shared DLL <br />
<br />
This can be set in a CMakeLists.txt file and will enable MFC in the application. It should be set to 1 or 2. This is used in visual studio 6 and 7 project files. The CMakeSetup dialog uses MFC and the CMakeLists.txt looks like this:<br />
<br />
ADD_DEFINITIONS(-D_AFXDLL)<br />
SET(CMAKE_MFC_FLAG 2) <br />
ADD_EXECUTABLE(CMakeSetup WIN32 ${SRCS})<br />
<br />
Note that visual studio 9 project files do not appear to work with CMAKE_MFC_FLAG 1; this may be related to [http://www.cmake.org/Bug/view.php?id=7056 bug 7056].<br />
<br />
In order to use MFC with UNICODE, you must also [http://msdn.microsoft.com/en-us/library/dybsewaf.aspx specify the entry point wWinMainCRTStartup]. For example:<br />
<br />
set(CMAKE_MFC_FLAG 2)<br />
set_target_properties(MyApp PROPERTIES<br />
COMPILE_DEFINITIONS _AFXDLL,_UNICODE,UNICODE,_BIND_TO_CURRENT_CRT_VERSION,_BIND_TO_CURRENT_MFC_VERSION<br />
LINK_FLAGS "/ENTRY:\"wWinMainCRTStartup\"")<br />
<br />
See [http://stackoverflow.com/questions/59635/app-does-not-run-with-vs-2008-sp1-dlls-previous-version-works-with-rtm-versions this article] as to why _BIND_TO_CURRENT_CRT_VERSION and _BIND_TO_CURRENT_MFC_VERSION are necessary for Visual Studio 2008 SP1.<br />
<br />
=== How To Put Files in Folders in Visual Studio Projects ===<br />
The Visual Studio IDE supports putting files into folders.<br />
CMake can be used to put files in folders with the SOURCE_GROUP <br />
command. <br />
<br />
SOURCE_GROUP(name [REGULAR_EXPRESSION regex] [FILES src1 src2 ...])<br />
<br />
Defines a group into which sources will be placed in project files. This is mainly used to setup file tabs in Visual Studio. Any file whose name is listed or matches the regular expression will be placed in this group provided the source file is being passed to ADD_EXECUTABLE or ADD_LIBRARY.<br />
<br />
For example:<br />
SOURCE_GROUP(FooFiles FILES foo.cxx)<br />
SOURCE_GROUP(BarFiles FILES bar.cxx)<br />
ADD_LIBRARY(foo foo.cxx bar.cxx)<br />
<br />
In the event a file matches multiple groups, the LAST group that explicitly lists the file will be favored, if any. If no group explicitly lists the file, the LAST group whose regular expression matches the file will be favored. For backwards compatibility this command is also supports the format SOURCE_GROUP(name regex).<br />
<br />
As a convenience to developers CMake automatically adds standard header files to a "Header Files" folder and standard source files to a "Source Files" folder for Visual Studio Projects. This can be overridden via the SOURCE_GROUP method documented above.<br />
<br />
=== How to create Visual Studio 6 Projects that contain only a single build type===<br />
For Visual Studio.NET (version 7.0 and above) it is possible to set the CMAKE_CONFIGURATION_TYPES variable to the build type(s) (Debug/Release/...) that you want. This does not work for Visual Studio 6. There is however a way to achieve this. To create your own set of configurations:<br />
<br />
# Create a directory in which you copy the files *.dsptemplate and CMakeVisualStudio6Configurations.cmake from CMake's Templates directory.<br />
# Edit the .cmake file and change the SET(CMAKE_CONFIGURATION_TYPES ...) line to set the build types that you want in your set.<br />
# Edit the *Header.dsptemplate files to contain only the configuration types you want in your set.<br />
# In your CMakeLists.txt file, set the MSPROJECT_TEMPLATE_DIRECTORY to the directory that you created.<br />
<br />
<br />
That's it. Run CMake and your new configuration files will be created.<br />
<br />
Note: Editing the *Header.dsptemplates files should be done very carefully. Here are some guidelines:<br />
<br />
- You MUST remove the targets that you do not want in your set at the bottom of the file (e.g. '# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"')<br />
- You can remove the '!IF "$(CFG)" == ...' until '!ELSEIF "$(CFG)" == ...' or '!ELSEIF "$(CFG)" == ...' until '!ENDIF' lines for the configurations you do not want. Make sure that the resulting code still starts with '!IF ...' and ends with '!ENDIF' with any number of '!ELSEIF' sections in between. If you create templates for a single configuration (aka makefile), it is possible to remove everything starting from '!IF' until and including '!ENDIF' and leave only the contents of the relevant section intact.<br />
- Do not edit the lines starting with '!MESSAGE' as the changes may - and probably will - corrupt your resulting DSP files. The only thing I was able to change without corrupting the DSP is to remove the irrevant configurations from the "Possible choices for configuration are:" list.<br />
<br />
If you have only a single configuration in your set, you may want to get rid of the intermediate dir that MsDev creates. You can do that by setting:<br />
# PROP BASE Output_Dir ""<br />
# PROP BASE Intermediate_Dir ""<br />
# PROP Intermediate_Dir ""<br />
# PROP Output_Dir "LIBRARY_OUTPUT_PATH"<br />
or<br />
# PROP Output_Dir "EXECUTABLE_OUTPUT_PATH"<br />
<br />
Additionally you should then also edit the '# ADD LINK32' line in the DLLHeader.dsptemplate file. Change for example '/out:"LIBRARY_OUTPUT_PATHDebug/OUTPUT_LIBNAMEDEBUG_POSTFIX.dll"' into '/out:"LIBRARY_OUTPUT_PATHOUTPUT_LIBNAMEDEBUG_POSTFIX.dll"' (Note that the configuration name and also the slash are removed).<br />
<br />
It is even possible to rename the pre-defined configurations of CMake in this way. Let's say you prefer 'PreProduction' over 'RelWithDebInfo'. You can change the name in the *.dsptemplate files, but you should also change it in the CMakeVisualStudio6Configurations.cmake file. Be careful, however. Only entries relevant to the configuration name should be changed. Do not change the /debug options and the entries that contain the build type in capital characters. Internally in CMake the build type will still remain 'RelWithDebInfo', so also the CMAKE_BUILD_TYPE should be set to the old value. You can only change the way it is named in MSDev.<br />
<br />
Note: Apparently MsDev as command-line build tool only performs a partial check on the build type. It will match all configuration types that CONTAIN the build type in their name. (e.g. if you have renamed RelWithDebInfo to DebugRelease, Debug will build Debug and DebugRelease, Release will build Release and DebugRelease. This may be exactly what you want, but be warned.)<br />
<br />
=== Can CMake set the Debugging/Working Directory property in Visual Studio projects? ===<br />
<br />
No. The value of this property is not stored in the project files. It is stored in extra files created by the IDE when a solution is loaded (VS .NET 2003 uses a hidden .suo file next to the .sln solution file). The format of these files is not known to CMake and cannot be generated. In some versions of VS the files are binary and not human readable.<br />
<br />
=== Why does CMakeSetup with the message "LINK : fatal error LNK1104: cannot open file 'user32.lib'" while configuring a project? ===<br />
<br />
The path to the SDK libs (user32.lib) must be added by the IDE when the<br />
project generator "Visual Studio 8 2005" is used, because cmake uses<br />
VCExpress.exe and on the fly generated project files to check<br />
for compiling (VCExpress.exe reads some config files for the<br />
compiler/linker options)<br />
<br />
So add the sdk lib path (...\Microsoft Platform SDK\Lib) at Tools->Options->Projects and Solutions->VC++ Directories->Library files<br />
<br />
See also:<br />
*http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/<br />
<br />
=== How can I avoid the error "Arg list too long" when running make? ===<br />
This error is sometimes encountered when building a static library with many object files using Unix make command. It typically looks something like this:<br />
<br />
<pre><br />
gmake[2]: execvp: /bin/sh: Arg list too long<br />
</pre><br />
<br />
When make tries to run the archiver program to build the static library the shell it uses complains that the argument list is too long. In some shells this can be fixed by setting an environment variable such as <tt>ARG_MAX</tt> to extend the length of the command line it will allow.<br />
<br />
=== How can I find out platforms definitions, search paths, etc. from gcc ?===<br />
<br />
The following is really the best if not only way to get information about predefined macros with a GNU compiler:<br />
<pre><br />
$ touch empty.c<br />
$ gcc -v -dD -E empty.c <br />
</pre><br />
This will give you all you might want to know about the preprocessor, the builtin include search dirs and all<br />
predefined definitions, so you can check whether it's __LINUX or _LINUX_ or _APPLE_ or __APPLE etc. <br />
The empty file and all these parameters are really required. You probably want to pipe the output (both stdout and stderr) to a file.<br />
If you want the information for C++, use a C++ file suffix for the empty file.<br />
<br />
This is how you can get the builtin library search paths:<br />
<pre><br />
$ gcc --print-search-dirs<br />
</pre><br />
<br />
=== How can I get a windows registry key ?===<br />
<br />
The only thing to know is that you can't use just the "SET" command in place of "GET" command.<br />
CMake read the value from the registry only when you "get" it from the cache. For instance :<br />
<br />
<pre><br />
GET_FILENAME_COMPONENT(SDK_ROOT_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\PACKAGE;Install_Dir]" ABSOLUTE CACHE)<br />
</pre><br />
<br />
If a key name (ex: Install_Dir in this case) was not specified , the Default key value will be get.<br />
Now you could use the SDK_ROOT_PATH to add include and lib path to your project :<br />
<br />
<pre><br />
INCLUDE_DIRECTORIES(<br />
${SDK_ROOT_PATH}/include<br />
)<br />
<br />
LINK_DIRECTORIES(<br />
${SDK_ROOT_PATH}/lib<br />
)<br />
</pre><br />
<br />
You can also read a registry key in the PATHS section of a FIND_LIBRARY, FIND_PATH, FIND_PROGRAM, or FIND_FILE command<br />
FIND_FILE(BOOT_DOT_INI boot.ini PATHS [HKEY_CURRENT_USER\\Environment;HOMEDRIVE])<br />
<br />
For other examples have a look in the CMake Modules folder :<br />
- FindJava.cmake<br />
- FindPythonLibs.cmake<br />
- ..<br />
<br />
{{CMake/Template/Footer}}</div>Shdwjk