https://public.kitware.com/Wiki/api.php?action=feedcontributions&user=Bigler&feedformat=atomKitwarePublic - User contributions [en]2024-03-29T09:10:11ZUser contributionsMediaWiki 1.38.6https://public.kitware.com/Wiki/index.php?title=CMake/Git/Develop&diff=44092CMake/Git/Develop2011-12-05T23:19:21Z<p>Bigler: /* Share a Topic */ Added command to teach git about 'stage' repository</p>
<hr />
<div>__NOTOC__<br />
<br />
This page documents how to develop CMake through [http://git-scm.com Git].<br />
See our [[CMake/Git|table of contents]] for more information.<br />
<br />
<i><br />
Git is an extremely powerful version control tool that supports many different "workflows" for indivudal development and collaboration.<br />
Here we document procedures used by the CMake development community.<br />
In the interest of simplicity and brevity we do '''not''' provide an explanation of why we use this approach.<br />
Furthermore, this is '''not''' a Git tutorial.<br />
Please see our [[Git/Resources|Git resource links]] for third-party documentation, such as the [http://progit.org/book/ ProGit Book].<br />
</i><br />
<br />
==Setup==<br />
<br />
Before you begin, perform initial setup:<br />
<br />
{| style="width: 100%" cellspacing="0" cellpadding="0"<br />
|-<br />
|width=60%|<br />
1.<br />
Register [[CMake/Git/Account#Git|Git push access]].<br />
|-<br />
|<br />
2.<br />
Follow the [[CMake/Git/Download#Clone|download instructions]] to create a local CMake clone:<br />
|-<br />
|<br />
:<code>$ git clone git://cmake.org/cmake.git</code><br />
:<code>$ cd cmake</code><br />
|align="center"|<br />
[[Git/Trouble#Firewall_Blocks_Port_9418|Connection refused]]?<br />
|-<br />
|<br />
3.<br />
Introduce yourself to Git:<br />
|-<br />
|<br />
:<code>$ git config --global user.name "Your Name"</code><br />
:<code>$ git config --global user.email "you@yourdomain.com"</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-config.html <code>git help config</code>]<br />
|-<br />
|<br />
4.<br />
Follow the [[Git/Hooks#Setup|local hook setup instructions]] to get local commit hooks:<br />
|-<br />
|<br />
:<code>$ cd .git/hooks</code><br />
:<code>$ git init</code><br />
:<code>$ git pull .. remotes/origin/hooks</code><br />
:<code>$ cd ../..</code><br />
|align="center"|<br />
[http://progit.org/book/ch1-5.html Pro Git: Setup]<br />
|}<br />
<br />
==Workflow==<br />
<br />
CMake development uses a [[Git/Workflow/Topic|branchy workflow]] based on topic branches.<br />
Our collaboration workflow consists of three main steps:<br />
<br />
{| style="width: 100%" cellspacing="0" cellpadding="0"<br />
|-<br />
|width=60%|<br />
1.<br />
Local Development<br />
|-<br />
|<br />
:* [[#Update|Update]]<br />
|-<br />
|<br />
:* [[#Create_a_Topic|Create a Topic]]<br />
|-<br />
|<br />
2.<br />
Testing and Review<br />
|-<br />
|<br />
:* [[#Share_a_Topic|Share a Topic]]<br />
|-<br />
|<br />
:* [[#Merge_a_Topic_for_Testing|Merge a Topic for Testing]]<br />
|-<br />
|<br />
:* [[#Extend_a_Topic|Extend a Topic]]<br />
|-<br />
|<br />
3.<br />
Integration by Maintainers<br />
|-<br />
|<br />
:* [[#Merge_a_Topic_for_Inclusion|Merge a Topic for Inclusion]]<br />
|-<br />
|<br />
:* [[#Delete a Topic|Delete a Topic]]<br />
|}<br />
<br />
==Update==<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
Update your local '''master''' branch:<br />
|-<br />
|<br />
:<code>$ git checkout master</code><br />
:<code>$ git pull</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-checkout.html <code>git help checkout</code>]<br />
<br/><br />
[http://schacon.github.com/git/git-pull.html <code>git help pull</code>]<br />
|}<br />
<br />
==Create a Topic==<br />
<br />
All new work must be committed on topic branches.<br />
Name topics like you might name functions: concise but precise.<br />
A reader should have a general idea of the feature or fix to be developed given just the branch name.<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
To start a new topic branch:<br />
|-<br />
|<br />
:<code>$ git fetch origin</code><br />
:<code>$ git checkout -b ''my-topic'' origin/master</code><br />
:''(If you are fixing a bug in the latest release then substitute'' <code>origin/release</code> ''for'' <code>origin/master</code>''.)''<br />
|align="center"|<br />
[http://schacon.github.com/git/git-fetch.html <code>git help fetch</code>]<br />
<br/><br />
[http://schacon.github.com/git/git-checkout.html <code>git help checkout</code>]<br />
<br/><br />
[http://progit.org/book/ch3-2.html Pro Git: Basic Branching]<br />
|-<br />
|<br />
Edit files and create commits (repeat as needed):<br />
|-<br />
|<br />
:<code>$ edit ''file1'' ''file2'' ''file3''</code><br />
:<code>$ git add ''file1'' ''file2'' ''file3''</code><br />
:<code>$ git commit</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-add.html <code>git help add</code>]<br />
<br/><br />
[http://schacon.github.com/git/git-commit.html <code>git help commit</code>]<br />
<br/><br />
[http://progit.org/book/ch2-2.html Pro Git: Recording Changes]<br />
|}<br />
<br />
==Share a Topic==<br />
<br />
When a topic is ready for testing and review by others, share it by pushing it to the "[http://public.kitware.com/Wiki/Git/Workflow/Stage topic stage]".<br />
Be sure you have registered for [[CMake/Git/Account#Git|Git push access]].<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
Checkout the topic if it is not your current branch:<br />
|-<br />
|<br />
:<code>$ git checkout ''my-topic''</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-checkout.html <code>git help checkout</code>]<br />
|-<br />
|<br />
Check what commits will be pushed to the topic stage:<br />
|-<br />
|<br />
:<code>$ git log origin/master..</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-log.html <code>git help log</code>]<br />
|-<br />
|<br />
Teach git about the topic stage repository:<br />
|-<br />
|<br />
:<code>$ git remote add stage git@cmake.org:stage/cmake.git</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-remote.html <code>git help remote</code>]<br />
|-<br />
|<br />
Push commits in your topic branch to the topic stage:<br />
|-<br />
|<br />
:<code>$ git push stage HEAD</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-push.html <code>git help push</code>]<br />
|}<br />
<br />
The topic is now published on the [http://cmake.org/stage/cmake.git CMake Topic Stage] and may be (optionally) reviewed by others.<br />
<br />
==Merge a Topic for Testing==<br />
<br />
When your topic is ready, merge it to the CMake '''next''' branch for testing.<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
Ask the topic stage to automatically merge the topic to '''next''':<br />
|-<br />
|<br />
:<code>$ ssh git@cmake.org stage cmake merge -b next ''my-topic''</code><br />
:''(If the merge conflicts follow the printed instructions to resolve them.)''<br />
|align="center"|<br />
[[Git/Workflow/Topic/Conflicts#Topic-to-Topic|Topic-to-Topic Conflict Resolution]]<br />
|}<br />
<br />
The topic is now integrated into CMake's '''next''' branch and will be tested by dashboard builds.<br />
<br />
==Extend a Topic==<br />
<br />
If your topic runs cleanly after a night of dashboard builds, it is ready for the [[#Merge_a_Topic_for_Inclusion|next step]].<br />
Otherwise, extend the topic with additional commits to fix the problems.<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
Checkout the topic if it is not your current branch:<br />
|-<br />
|<br />
:<code>$ git checkout ''my-topic''</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-checkout.html <code>git help checkout</code>]<br />
|-<br />
|<br />
Edit files and create commits (repeat as needed):<br />
|-<br />
|<br />
:<code>$ edit ''file1'' ''file2'' ''file3''</code><br />
:<code>$ git add ''file1'' ''file2'' ''file3''</code><br />
:<code>$ git commit</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-add.html <code>git help add</code>]<br />
<br/><br />
[http://schacon.github.com/git/git-commit.html <code>git help commit</code>]<br />
<br/><br />
[http://progit.org/book/ch2-2.html Pro Git: Recording Changes]<br />
|-<br />
|<br />
Return to the [[#Share_a_Topic|earlier step]] to share the extended topic.<br />
|}<br />
<br />
==Merge a Topic for Inclusion==<br />
<br />
Only core maintainers have access to merge a topic to '''master'''.<br />
They meet weekly to evaluate topics in '''next''' based on dashboard results and manual review.<br />
If your topic is accepted it will be merged to '''master''' for permanent inclusion after which you may [[#Delete_a_Topic|delete it]].<br />
Otherwise the maintainers will contact you with feedback.<br />
Respond by returning to the [[#Extend_a_Topic|above step]] to address their concerns.<br />
<br />
==Delete a Topic==<br />
<br />
After a topic has been merged upstream, delete your local branch for the topic.<br />
<br />
{| style="width: 100%"<br />
|-<br />
|width=60%|<br />
Checkout and update the '''master''' branch:<br />
|-<br />
|<br />
:<code>$ git checkout master</code><br />
:<code>$ git pull</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-checkout.html <code>git help checkout</code>]<br />
<br/><br />
[http://schacon.github.com/git/git-pull.html <code>git help pull</code>]<br />
|-<br />
|<br />
Delete the local topic branch:<br />
|-<br />
|<br />
:<code>$ git branch -d ''my-topic''</code><br />
|align="center"|<br />
[http://schacon.github.com/git/git-branch.html <code>git help branch</code>]<br />
|-<br />
|<br />
The <code>branch -d</code> command works only when the topic branch has been correctly merged.<br />
Use <code>-D</code> instead of <code>-d</code> to force the deletion of an unmerged topic branch<br />
(warning - you could lose commits).<br />
|}</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake:Module_Maintainers&diff=35817CMake:Module Maintainers2010-12-20T18:49:34Z<p>Bigler: /* List */ Added FindCUDA maintainer</p>
<hr />
<div>== Introduction ==<br />
<br />
If you want to add a new module to CMake, then you must volunteer to maintain it, or find someone that will. This page contains a list of Module maintainer volunteers, and instructions on how to become a maintainer. <br />
<br />
* This mail describes the procedure how to become maintainer, and how to modify or add modules: [http://www.cmake.org/pipermail/cmake/2007-July/015258.html Call for maintainers] <br />
<br />
* Please '''DO NOT ADD a Bug Tracker''' entry for new Module request [http://www.cmake.org/pipermail/cmake/2008-November/025196.html Do not add bug report for New Module] <br />
<br />
* Maintainers should follow the guide lines for module files documented here: [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/readme.txt readme.txt]<br />
<br />
* Maintainers should subscribe to the CMake Developers mailing list and follow related threads there appropriately: [http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers CMake Developers Mailing List]<br />
<br />
In addition backwards compatibility for all existing variables in the current set<br />
of modules must be maintained strictly. <br />
<br />
If you want to become a module maintainer, please send an email with your module to the cmake mailing list.<br />
<br />
* Here is a list of "repositories" of 3rd party CMake modules, so maintainers can check for already existing modules etc.<br />
** KDE4: http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/<br />
** PlPlot: http://plplot.svn.sourceforge.net/viewvc/plplot/trunk/cmake/modules/<br />
** http://cmake-modules.googlecode.com/svn/trunk/Modules/<br />
** OpenSceneGraph http://www.openscenegraph.org/svn/osg/OpenSceneGraph/trunk/CMakeModules/<br />
** OpenSync http://svn.opensync.org/branches/3rd-party-cmake-modules/modules/<br />
** http://github.com/jedbrown/cmake-modules<br />
<br />
== List ==<br />
<br />
* NOBODY!!! Please volunteer if you are able and willing. Need new maintainers for these modules:<br />
** Any Find*.cmake module distributed with CMake that is not already listed under a maintainer below.<br />
<br />
* Dave Partyka, dave dot partyka at kitware dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindMPI.cmake FindMPI]<br />
<br />
* Miguel A. Figueroa Villanueva, miguelf at ieee dot org<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindwxWidgets.cmake FindwxWidgets]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindLATEX.cmake FindLATEX]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindImageMagick.cmake FindImageMagick]<br />
<br />
* Alan W. Irwin, irwin at beluga dot phys dot uvic dot ca<br />
** Ada<br />
<br />
* Alexey Ozeritsky, aozeritsky at gmail dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindBLAS.cmake FindBLAS]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindLAPACK.cmake FindLAPACK]<br />
<br />
* Tim Burrell (tim dot burrell at gmail dot com) (http://www.dsource.org/projects/cmaked)<br />
** D support<br />
<br />
* Philip Lowman, philip at yhbt dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindBoost.cmake FindBoost]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGTK2.cmake FindGTK2]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindOpenSceneGraph.cmake FindOpenSceneGraph]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindCxxTest.cmake FindCxxTest]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindDoxygen.cmake FindDoxygen]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeDetermineVSServicePack.cmake CMakeDetermineVSServicePack]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGnuTLS.cmake FindGnuTLS]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindFLEX.cmake FindFLEX]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindBISON.cmake FindBISON]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGTest.cmake FindGTest (Google C++ Testing Framework)]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindBullet.cmake FindBullet]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindALSA.cmake FindALSA]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindProtobuf.cmake FindProtobuf]<br />
<br />
* Eric Wing ; in the commercial domain at gmail, ewing . public<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindFreeType.cmake FindFreeType]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGDAL.cmake FindGDAL]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGIFLIB.cmake FindGIFLIB]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindLua50.cmake FindLua50]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindLua51.cmake FindLua51]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindOpenAL.cmake FindOpenAL]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindOpenThreads.cmake FindOpenThreads]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindPhysFS.cmake FindPhysFS]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindProducer.cmake FindProducer]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindQuickTime.cmake FindQuickTime]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL.cmake FindSDL]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL_image.cmake FindSDL_image]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL_mixer.cmake FindSDL_mixer]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL_net.cmake FindSDL_net]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL_sound.cmake FindSDL_sound]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSDL_ttf.cmake FindSDL_ttf]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/Findosg.cmake Findosg]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgDB.cmake FindosgDB]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgFX.cmake FindosgFX]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgGA.cmake FindosgGA]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgIntrospection.cmake FindosgIntrospection]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgManipulator.cmake FindosgManipulator]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgParticle.cmake FindosgParticle]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgProducer.cmake FindosgProducer]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgShadow.cmake FindosgShadow]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgSim.cmake FindosgSim]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgTerrain.cmake FindosgTerrain]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgText.cmake FindosgText]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgUtil.cmake FindosgUtil]<br />
*** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindosgViewer.cmake FindosgViewer]<br />
<br />
* Marcel Loose, loose at astron dot nl<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSubversion.cmake FindSubversion]<br />
<br />
* Matt Leotta, matt.leotta at gmail dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindCoin3D.cmake FindCoin3D]<br />
<br />
* Mathieu Malaterre , Mathieu.Malaterre at gmail dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindSWIG.cmake FindSWIG]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/UseSWIG.cmake UseSWIG]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindJNI.cmake FindJNI]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindJava.cmake FindJava]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindOpenSSL.cmake FindOpenSSL]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindDCMTK.cmake FindDCMTK]<br />
<br />
* Clinton Stimpson clinton at elemtech dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindQt4.cmake FindQt4]<br />
<br />
* Petr Gotthard, petr dot gotthard at honeywell dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindRTI.cmake FindRTI]<br />
<br />
* Will Dicharry, wdicharry at stellarscience dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindHDF5.cmake FindHDF5]<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/SelectLibraryConfigurations.cmake SelectLibraryConfigurations]<br />
<br />
* Kovarththanan Rajaratnam, kovarththanan.rajaratnam at gmail dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindZLIB.cmake FindZLIB]<br />
<br />
* James Bigler, nvidia.com - jbigler or jamesbigler - gmail dot com<br />
** [http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindCUDA.cmake FindCUDA]</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake:CPackPackageGenerators&diff=20911CMake:CPackPackageGenerators2010-03-01T17:55:37Z<p>Bigler: /* PackageMaker (OSX only) */ Added some brief information on the scripts' arguments and a link to more information.</p>
<hr />
<div>=CPack Package Generators=<br />
<br />
Information about CPACK_xxx variables used for CPack configuration<br />
may be found there: [http://www.itk.org/Wiki/CMake:CPackConfiguration CPackConfiguration]<br />
<br />
Currently CPack features the following package generators:<br />
<br />
==TGZ==<br />
<br />
Tar GZip compressed packages.<br />
<br />
==STGZ==<br />
<br />
Self extracting Tar GZip compressed packages (needs /bin/sh, tar, gunzip and tail for extracting).<br />
<br />
==NSIS==<br />
<br />
Nullsoft Installer. Requires [http://nsis.sourceforge.net/ NSIS] for creating the package.<br />
<br />
==ZIP==<br />
<br />
ZIP compressed packages. Requires zip, WinZip or 7Zip for creating the package. 7Zip support is only available in future version of CMake and can not be used with CMake Version earlier then 2.4.7.<br />
<br />
==TBZ2==<br />
<br />
Tar BZip2 compressed packages. Requires bzip2 for creating the package.<br />
<br />
==TZ==<br />
<br />
Tar UNIX compress compressed packages.<br />
<br />
==DragNDrop (OSX only)==<br />
<br />
Mac OSX Drag and Drop installer. Similar to the Bundle generator except that this generator doesn't create the bundle for you.<br />
To make a bundle, use the MACOSX_BUNDLE parameter in add_executable(), and to specify icon, plist, and other bundle properties, just set them with a set_target_properties() call. It also supports creating a folder that contains multiple bundles and other files.<br />
<br />
==PackageMaker (OSX only)==<br />
<br />
Mac OSX Package Maker packages. Requires Package Maker for creating the package.<br />
<br />
Some of the variables that you can use to customize the Package Maker generated package:<br />
<br />
{| border="1" cellpadding="2"<br />
|-bgcolor="#abcdef"<br />
||Variable Name <br />
||Description <br />
||Default value <br />
|-<br />
| CPACK_PREFLIGHT_SCRIPT || This script is launched just after the user clicked on the "Install" button. || - <br />
|-<br />
| CPACK_POSTFLIGHT_SCRIPT || This script is launched after the postinstall / postupgrade script or when the package has been || -<br />
|-<br />
| CPACK_POSTUPGRADE_SCRIPT || This script is launched after the files in the package have been installed. (Isn't an option for a postinstall script missing? According to Apple documentation, postinstall is executed the first time a package is installed and postupgrade all subsequent times) || -<br />
|-<br />
| CPACK_OSX_PACKAGE_VERSION || Set to the minimum OS X version you support. Choices are currently 10.3, 10.4 and 10.5 || 10.3, unless you specified features that require a higher OS X version (CPACK_DOWNLOAD_SITE, CPACK_COMPONENTS_ALL)<br />
|}<br />
<br />
This is a useful site that describes where the scripts get executed and what the arguments to the scripts are. See section "What about scripts?". http://s.sudre.free.fr/Stuff/PackageMaker_Howto.html . In summary the arguments correspond to $0 Script path, $1 Package path, $2 Target location, and $3 Target Volume.<br />
<br />
==OSXX11 (OSX only)==<br />
<br />
Mac OSX X11 Bundle. Requires hdiutil for creating the package.<br />
<br />
== Bundle (OSX only) ==<br />
<br />
=== Overview ===<br />
<br />
The Bundle generator (introduced in CMake 2.6) creates a compressed disk image containing an OSX bundle, whose contents are populated with CMake INSTALL() commands. This makes it possible to create bundles of arbitrary complexity while minimizing differences with installation on other platforms. For example, a bundle created with the bundle generator can contain multiple executable files, libraries generated by the build, third-party dependencies, etc.<br />
<br />
'''''Important Note:''''' Do '''not''' use the MACOSX_BUNDLE property on executables that will be packaged using the bundle-generator! Specifying MACOSX_BUNDLE creates a separate bundle for each individual executable at build-time; the structure of these bundles becomes redundant when the bundle generator consolidates multiple executables into a single bundle.<br />
<br />
=== Bundle Layout ===<br />
<br />
<pre><br />
${CPACK_BUNDLE_NAME}/<br />
Contents/<br />
Info.plist (copied from ${CPACK_BUNDLE_PLIST})<br />
MacOS/<br />
${CPACK_BUNDLE_NAME} (copied from ${CPACK_BUNDLE_STARTUP_COMMAND})<br />
Resources/<br />
(file contents defined by CMake INSTALL() commands)<br />
</pre><br />
<br />
* CPACK_BUNDLE_PLIST is the name of a file that becomes the Info.plist for the bundle. This could be a hard-coded file included with the program sources, a file generated with CONFIGURE_FILE, etc. Rationale: Info.plist can become arbitrarily complex, applications need to be able to specify its contents directly.<br />
<br />
* The bundle's Resources/ directory is populated with the files installed with CMake INSTALL() commands. Rationale: integrate well with CMake and other package generators (such as NSIS). Makes it easy to incorporate external dependencies (Qt, GTK) into the bundle.<br />
<br />
* CPACK_BUNDLE_STARTUP_COMMAND is the name of a file that will be executed when the user opens the bundle. It could be a binary or a script. Rationale: for most non-trivial applications, simply running a binary is not enough. The following sample script demonstrates several common startup operations:<br />
** Starts X11 (required by GTK).<br />
** Updates DYLD_LIBRARY_PATH so that the application can locate libraries that are included in the bundle. This eliminates the need to run install_name_tool on libraries in the bundle, which is messy and error-prone. Useful for either Qt or GTK.<br />
** Updates PATH so the "main" application can easily run "child" binaries included in the bundle.<br />
** Sets-up some temporary files and environment variables required by (in this case) GTK.<br />
** Passes information to the application via the command line (in this case, paths to several application resources located in the bundle).<br />
<br />
<pre><br />
#!/bin/sh<br />
#<br />
# Author: Aaron Voisine <aaron@voisine.org><br />
# Inkscape Modifications: Michael Wybrow <mjwybrow@users.sourceforge.net><br />
# K-3D Modifications: Timothy M. Shead <tshead@k-3d.com><br />
<br />
K3D_BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/K-3D//'`"<br />
K3D_RESOURCES="$K3D_BUNDLE/Contents/Resources"<br />
K3D_TEMP="/tmp/k3d/$UID"<br />
K3D_ETC="$K3D_TEMP/etc"<br />
K3D_PANGO_RC_FILE="$K3D_ETC/pango/pangorc"<br />
<br />
echo "running $0"<br />
echo "K3D_BUNDLE: $K3D_BUNDLE"<br />
<br />
# Start X11 ...<br />
ps -wx -ocommand | grep -e '[X]11.app' > /dev/null<br />
if [ "$?" != "0" -a ! -f ~/.xinitrc ]; then<br />
echo "rm -f ~/.xinitrc" > ~/.xinitrc<br />
sed 's/xterm/# xterm/' /usr/X11R6/lib/X11/xinit/xinitrc >> ~/.xinitrc<br />
fi<br />
<br />
mkdir -p $K3D_TEMP<br />
cat << __END_OF_GETDISPLAY_SCRIPT__ > "$K3D_TEMP/getdisplay.sh"<br />
#!/bin/sh<br />
mkdir -p "$K3D_TEMP"<br />
<br />
if [ "\$DISPLAY"x == "x" ]; then<br />
echo :0 > "$K3D_TEMP/display"<br />
else<br />
echo \$DISPLAY > "$K3D_TEMP/display"<br />
fi<br />
__END_OF_GETDISPLAY_SCRIPT__<br />
chmod +x "$K3D_TEMP/getdisplay.sh"<br />
rm -f $K3D_TEMP/display<br />
open-x11 $K3D_TEMP/getdisplay.sh || \<br />
open -a XDarwin $K3D_TEMP/getdisplay.sh || \<br />
echo ":0" > $K3D_TEMP/display<br />
<br />
while [ "$?" == "0" -a ! -f $K3D_TEMP/display ];<br />
do<br />
#echo "Waiting for display $K3D_TEMP/display"<br />
sleep 1;<br />
done<br />
export "DISPLAY=`cat $K3D_TEMP/display`"<br />
<br />
ps -wx -ocommand | grep -e '[X]11' > /dev/null || exit 11<br />
<br />
# Setup temporary runtime files<br />
rm -rf "$K3D_TEMP"<br />
<br />
# Because the bundle could be located anywhere at runtime, we have to<br />
# create temporary copies of the Pango configuration files that<br />
# reflect our current location<br />
mkdir -p "$K3D_ETC/pango"<br />
sed -e 's|/opt/local/etc|'"$K3D_ETC|g" "$K3D_RESOURCES/etc/pango/pangorc" > "$K3D_ETC/pango/pangorc"<br />
sed -e 's|/opt/local|\"'"$K3D_RESOURCES|g" -e "s/\.so/.so\"/g" "$K3D_RESOURCES/etc/pango/pango.modules" > "$K3D_ETC/pango/pango.modules"<br />
cp -f "$K3D_RESOURCES/etc/pango/pangox.aliases" "$K3D_ETC/pango/pangox.aliases"<br />
<br />
export "DYLD_LIBRARY_PATH=$K3D_RESOURCES/lib"<br />
export "FONTCONFIG_PATH=$K3D_RESOURCES/etc/fonts"<br />
export "PANGO_RC_FILE=$K3D_PANGO_RC_FILE"<br />
export "PATH=$K3D_RESOURCES/bin:$PATH"<br />
<br />
#export<br />
exec "$K3D_RESOURCES/bin/k3d" "--log-level=debug" "--plugins=$K3D_RESOURCES/lib/k3d/plugins" "--share=$K3D_RESOURCES/share/k3d" "--ui=$K3D_RESOURCES/lib/k3d/uiplugins/k3d-ngui.module"<br />
</pre><br />
<br />
* The bundle is then stored in a compressed disk image. Rationale: de-facto standard mechanism for distributing bundles.<br />
<br />
=== Required CMake Variables ===<br />
<br />
The prototype bundle generator uses the following variables:<br />
<br />
* CPACK_PACKAGE_FILE_NAME - provides the name of the final compressed disk image (the name of the file that is distributed).<br />
* CPACK_PACKAGE_ICON - provides the icon for the mounted disk image (appears after the user mounts the disk image).<br />
* CPACK_BUNDLE_NAME - provides the bundle name (displayed in the finder underneath the bundle icon).<br />
* CPACK_BUNDLE_ICON - provides the bundle icon (displayed in the /Applications folder, on the dock, etc).<br />
* CPACK_BUNDLE_PLIST - path to a file that will become the bundle plist.<br />
* CPACK_BUNDLE_STARTUP_COMMAND - path to a file that will be executed when the user opens the bundle. Could be a shell-script or a binary.<br />
<br />
=== Known Issues ===<br />
<br />
* [http://public.kitware.com/Bug/view.php?id=7523 0007523: CPack OSX bundle generator can fail when assigning a custom volume icon.]<br />
<br />
=== TODO ===<br />
<br />
* Detect attempts to use the bundle generator with MACOSX_BUNDLE.<br />
* Generate a default Info.plist file if CPACK_BUNDLE_PLIST is not defined.<br />
* Support fixing-up binaries with install_name_tool, eliminating the need to run a script that sets DYLD_LIBRARY_PATH.<br />
* Add arbitrary files (such as background images, READMEs, etc) to the disk image - this use-case is distinct from adding files to the bundle with INSTALL().<br />
* Provide an option or alternative to CPACK_BUNDLE_STARTUP_COMMAND that simply executes one of the files installed in the bundle. Presumably, this should be a symlink to a binary or script.<br />
<br />
==CygwinBinary (Cygwin only)==<br />
<br />
Tar Bzip2 compressed Cygwin package. Requires bzip2 for creating the package.<br />
<br />
==CygwinSource (Cygwin only)==<br />
<br />
Tar Bzip2 compressed Cygwin source package. Requires bzip2 for creating the package.<br />
<br />
==DEB (UNIX only)==<br />
<br />
Debian packages (2.0 version only, see the debian-binary file). In CMake cvs since July 2007, will be in 2.6.0. With CPack 2.4.x you can use the approach described in [[CMakeUserUseDebian]] (Requires only ar for creating the package). Warning: due to an incompatibility between GNU-ar and BSD-ar this is not a long-term recommended solution.<br />
Instead you should switch to the solution implemented in 2.6.x where a BSD-ar implementation was integrated in CPack.<br />
<br />
Reference: [libapt-inst] Should support both BSD and SysV ar formats<br />
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 <br />
<br />
Note:<br />
Only binary package are supported. source package do not really make sense since build process is cmake driven.<br />
<br />
Here are the variables needed for a binary package:<br />
<br />
=== control file (aka DEBIAN/control) for binary package ===<br />
<br />
Specific variables are needed to generate the control file for debian package. This file is created automatically using the following variables, some of which are mandatory and some are optional. <br />
See also: [http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles]<br />
<br />
'''package name'''<br />
<br />
* debian policy enforce lower case for package name<br />
* Package: (mandatory)<br />
* if CPACK_DEBIAN_PACKAGE_NAME is not set CPACK_PACKAGE_NAME (lower case will be used)<br />
<br />
'''version'''<br />
<br />
* Version: (mandatory)<br />
* if CPACK_DEBIAN_PACKAGE_VERSION is not set CPACK_PACKAGE_VERSION<br />
<br />
'''arch'''<br />
<br />
* Architecture: (mandatory)<br />
* if not set CPACK_DEBIAN_PACKAGE_ARCHITECTURE will be set to i386<br />
Notes:<br />
* should be set via: dpkg --print-architecture<br />
* There is no such thing as i686 architecture on debian, you should use i386 instead<br />
<br />
'''depends'''<br />
<br />
* Depends:<br />
* You should set: CPACK_DEBIAN_PACKAGE_DEPENDS<br />
* eg.:<br />
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6), libgcc1 (>= 1:3.4.2-12)")<br />
Notes:<br />
* have a look at GET_PROPERTY(result GLOBAL ENABLED_FEATURES), this returns the successful FIND_PACKAGE() calls, maybe this can help<br />
* TODO: automate 'objdump -p | grep NEEDED'<br />
<br />
'''maintaner'''<br />
<br />
* Maintainer: (mandatory)<br />
** valid email is required<br />
* if CPACK_DEBIAN_PACKAGE_MAINTAINER is not set, CPACK_PACKAGE_CONTACT will be used instead<br />
<br />
'''description'''<br />
<br />
* Description: (mandatory)<br />
* if CPACK_DEBIAN_PACKAGE_DESCRIPTION is not set CPACK_PACKAGE_DESCRIPTION_SUMMARY will be used instead.<br />
<br />
'''section'''<br />
<br />
* Section: (recommended)<br />
* if not set CPACK_DEBIAN_PACKAGE_SECTION will default to 'devel'<br />
<br />
'''priority'''<br />
<br />
* Priority: (recommended)<br />
* if not set CPACK_DEBIAN_PACKAGE_PRIORITY will be set to "optional"<br />
<br />
'''recommends'''<br />
<br />
* Recommends:<br />
* You should set: CPACK_DEBIAN_PACKAGE_RECOMMENDS<br />
<br />
'''Suggests'''<br />
<br />
* Suggests:<br />
* You should set: CPACK_DEBIAN_PACKAGE_SUGGESTS<br />
<br />
'''Control Extra'''<br />
* Additional control files (optional)<br />
* In order to perform pre-, or post-install configuration, certain files can be provided in the DEBIAN/ folder in the debian package (postinst, preinst, postrm, prerm)<br />
* You should set: CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA <br />
* E.g.<br />
set( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/CMake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/CMake/debian/prerm;" )<br />
<br />
=== Source (for reference only) ===<br />
<br />
Here are the variables needed for a source package (not implemented):<br />
<br />
* For debian source packages:<br />
* see also [http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-sourcecontrolfiles debian/control]<br />
<br />
* .dsc<br />
* see also [http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-debiansourcecontrolfiles]<br />
<br />
Most of them are identical with the binary package, with exception:<br />
<br />
'''builds-depends'''<br />
<br />
* DEBIAN_PACKAGE_BUILDS_DEPENDS<br />
* eg.: <br />
"debhelper (>> 5.0.0), libncurses5-dev, tcl8.4"<br />
<br />
=== External references ===<br />
<br />
* http://wiki.debian.org/HowToPackageForDebian<br />
* http://www.itk.org/Wiki/CMake:CPackConfiguration#Debian_settings<br />
<br />
==RPM (Unix Only)==<br />
<br />
Binary RPM packages are supported by CMake (more precisely by CPack) since CMake 2.6.0.<br />
If you use CMake 2.4.x (or you want to build source RPM)<br />
you may use the [[CMakeUserUseRPMTools]] module.<br />
<br />
''Note: CPack RPM generator does not [yet] support [[http://www.cmake.org/Wiki/CMake:Component_Install_With_CPack#Ideas_for_Future_Development CPack Component]]. You may monitor the following feature request [[http://public.kitware.com/Bug/view.php?id=7645 #7645]] if you are interested in this.''<br />
<br />
=== CPack RPM usage ===<br />
The CPack RPM generator is not different from other CPack generator<br />
it's execution is controlled using:<br />
* generic CPACK_xxxx variables see [[CMake:CPackConfiguration|CPack variables]]<br />
* specific CPACK_RPM_xxxx variables see generator specific wiki pages<br />
<br />
Since CMake/CPack 2.8.0, you should be able to have a detailed description of the<br />
CPACK_RPM_xxxx variables usage both on this page and from the CMake command line:<br />
<br />
cmake --help-module CPackRPM<br />
<br />
If you use [[CMake:Packaging_With_CPack#Using_CPack_with_CMake|CPack with CMake]] with the Makefile<br />
generator you usually launch:<br />
<br />
cd build_dir<br />
make package<br />
<br />
However if you want more command line control over the CPack run you may launch:<br />
<br />
cd build_dir<br />
cpack -D CPACK_RPM_PACKAGE_DEBUG=1 -D CPACK_RPM_SPEC_INSTALL_POST="/bin/true" -G RPM<br />
<br />
this will launch CPack with additionnal CPACK_RPM_xxxx variables definitions which <br />
may be used by CPack RPM generator.<br />
<br />
<br />
==== CPack RPM generators specific variables ====<br />
CPack RPM specific variables are used to generate an RPM spec file<br />
which will be processed by the ''rpmbuild'' tool.<br />
A specific variable may be<br />
* ''optional'', the variable may or may not be set and its value is not needed for building a valid spec file.<br />
* '''mandatory''', the variable must be set because we need a value for building a valid spec file.<br />
** '''mandatory with default value''', the variable must be set but a default value is provided.<br />
** '''mandatory''', the variable must be set and no default value is provided.<br />
<br />
Here is the list of CPack RPM specific variables (''some variable are not yet supported because there are some patches pending''):<br />
<br />
{| border="1" cellpadding="2"<br />
|-bgcolor="#abcdef"<br />
||Variable Name <br />
||Description <br />
||Default value <br />
|-<br />
| '''CPACK_RPM_PACKAGE_SUMMARY''' || The RPM package summary || CPACK_PACKAGE_DESCRIPTION_SUMMARY <br />
|-<br />
| '''CPACK_RPM_PACKAGE_NAME''' || The RPM package name || CPACK_PACKAGE_NAME<br />
|-<br />
| '''CPACK_RPM_PACKAGE_VERSION''' || The RPM package version || CPACK_PACKAGE_VERSION<br />
|-<br />
| ''CPACK_RPM_PACKAGE_ARCHITECTURE'' || The RPM package architecture. This may be set to "noarch" if you know you are building a noarch package. || -<br />
|-<br />
| '''CPACK_RPM_PACKAGE_RELEASE''' || The RPM package release. This is the numbering of the RPM package itself, i.e. the version of the packaging and not the version of the content (see CPACK_RPM_PACKAGE_VERSION). One may change the default value if the previous packaging was buggy and/or you want to put here a fancy Linux distro specific numbering.|| 1<br />
|-<br />
| '''CPACK_RPM_PACKAGE_LICENSE''' || The RPM package license policy. || "unknown"<br />
|-<br />
| '''CPACK_RPM_PACKAGE_GROUP''' || The RPM package group || "unknown"<br />
|-<br />
| '''CPACK_RPM_PACKAGE_VENDOR''' || The RPM package group || CPACK_PACKAGE_VENDOR if set or "unknown" if not set<br />
|-<br />
| '''CPACK_RPM_PACKAGE_DESCRIPTION''' || The RPM package description || The content of CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package description available" if not set<br />
|-<br />
| ''CPACK_RPM_PACKAGE_REQUIRES'' || May be used to set RPM dependencies. see [[http://www.rpm.org/max-rpm/s1-rpm-depend-manual-dependencies.html RPM dependencies specification]]) for precise syntax. Note that you must enclose the complete requires string between quotes, for example:<br /> set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.5.0, cmake >= 2.8")|| - <br />
|-<br />
| ''CPACK_RPM_SPEC_INSTALL_POST'' || May be used to set an RPM post-install command inside the spec file. For example setting it to "/bin/true" may be used to prevent rpmbuild to strip binaries (see [[http://public.kitware.com/Bug/view.php?id=7435 Bug7435]])|| -<br />
|-<br />
| ''CPACK_RPM_SPEC_MORE_DEFINE'' || May be used to add any %define lines to the generated spec file.|| -<br />
|-<br />
| ''CPACK_RPM_USER_BINARY_SPECFILE'' || May be used to specify a user provided spec file instead of generating one. This is an feature which currently needs a patch see [[http://public.kitware.com/Bug/view.php?id=9679 Bug9679]]|| -<br />
|-<br />
| ''CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE'' || May be used to generate a '''template''' for a user provided spec file. This is an feature which currently needs a patch see [[http://public.kitware.com/Bug/view.php?id=9679 Bug9679]]|| -<br />
|-<br />
| ''CPACK_RPM_<POST/PRE>_<UN>INSTALL_SCRIPT_FILE'' || The content of the specified files will be embedded in the RPM spec file in the appropriate sections. This is an feature which currently needs a patch see [[http://public.kitware.com/Bug/view.php?id=8988 Bug8988]] || -<br />
|-<br />
| ''CPACK_RPM_PACKAGE_DEBUG'' || May be set when invoking cpack in order to trace debug informations during CPack RPM run. For example you may launch CPack like this ''cpack -D CPACK_RPM_PACKAGE_DEBUG=1 -G RPM'' || -<br />
|}<br />
<br />
=== CPack RPM currently pending bugs/features ===<br />
Here the may-be-incomplete lists of pendings bugs/features request<br />
linked to CPackRPM:<br />
<br />
* Support for COMPONENT [[http://public.kitware.com/Bug/view.php?id=7645 Bug7645-PreliminaryPatchUnderway]] this one will need more work since it depends on [[http://public.kitware.com/Bug/view.php?id=9900 Bug9900]]<br />
* RPM Post/Pre (un)install script support [[http://public.kitware.com/Bug/view.php?id=8988 Bug8988-Fixed since 2.8.1]]<br />
* Builtin documentation with ''cmake --help-module CPackRPM'' [[http://public.kitware.com/Bug/view.php?id=9029 Bug9029-Fixed since 2.8.0]]<br />
* RPM 4.6.x support <br />
** Fedora Core 10 fix, [[http://public.kitware.com/Bug/view.php?id=8967 Bug8967-Fixed since 2.8.1]]<br />
** Mandriva 2009.1 fix, [[http://public.kitware.com/Bug/view.php?id=9031 Bug9031-Fixed since 2.8.1]]<br />
* Support USER supplied "Provides" [[http://public.kitware.com/Bug/view.php?id=9584 Bug9584-Fixed since 2.8.1]]<br />
* Related bugs<br />
** Do not include include directories in %file section [[http://public.kitware.com/Bug/view.php?id=9654 Bug9654-Fixed since 2.8.1]]<br />
** Symlink not packaged [[http://public.kitware.com/Bug/view.php?id=9927 Bug9927-Fixed since 2.8.1]]<br />
* Support of USER specified spec file [[http://public.kitware.com/Bug/view.php?id=9679 Bug9679-Fixed since 2.8.1]]<br />
* RPM 4.7.1 / Fedora 11 Issue, [[http://public.kitware.com/Bug/view.php?id=9872 Bug9872-Fixed since 2.8.1]]<br />
* RPM Generator, spaces in CPACK_PACKAGE_NAME cause error [[http://public.kitware.com/Bug/view.php?id=9932 Bug9932-Unfixable]]<br />
<br />
=== CPack RPM Historical Notes ===<br />
<br />
CPackRPM included along with CMake 2.8.1 is provided many new features and bug fixes<br />
--[[User:Erk|Erk]] 14:33, 20 February 2010 (UTC)<br />
<br />
The binary CPackRPM generator should now work for many RPM based distribution and rpmbuild version.<br />
[[User:Erk|Erk]] was granted CVS commit right for CPackRPM and he's maintaining and improving it as long<br />
as spare time is available --[[User:Erk|Erk]] 14:30, 20 February 2010 (UTC)<br />
<br />
The built-in CPack support for RPM is based on the work done in the [[CMakeUserUseRPMTools|RPM]] module.<br />
The built-in CPack 2.6.x support for RPM is for '''binary package only''' but <br />
the binary RPM package built faster using CPack than [[CMakeUserUseRPMTools]] module.<br />
This restriction is due to both a lack of time of the implementor (--[[User:Erk|Erk]] 05:01, 7 September 2007 (EDT))<br />
and some [[CMakeUserUseRPMTools#CPack_Built-in_RPM_support_design_issues|design issues]] in current CPack .<br />
<br />
<br />
The [[CMakeUserUseRPMTools]] module should be usable both with CMake 2.4.x and forthcoming CMake 2.6.x.<br />
<br />
For an enhanced version of these modules, take a look at this discussion http://www.cmake.org/pipermail/cmake/2007-July/014945.html.</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_Editors_Support&diff=15210CMake Editors Support2009-04-28T17:03:54Z<p>Bigler: /* CMake Editor Modes */ Added buffer naming hints</p>
<hr />
<div>==CMake Editor Modes==<br />
<br />
There are [[CMake]] syntax highlighting and indentation supports for many editors:<br />
<br />
* '''Eclipse''' There are two plugins for Eclipse:<br />
** The [http://cmakeed.sourceforge.net CMakeEd] plugin for Eclipse provides syntax coloring and content assist for editing CMakeLists.txt and any file ending in a .cmake extension. It also integrates the CMake command reference documentation into the Eclipse Help system. This plugin does NOT do project management for you or generate CMake files for you. You are still responsible for this part. CMakeEd just makes writing the CMakeLists.txt files easier.<br />
** The [http://www.cmakebuilder.com/ CMakeBuilder] plugin provides a user friendly interface to easily manage CMake-based projects, with the following features: advanced parser, Advanced CMake outline, CMakeBuilder perspective, symbol table and environment inspector, CMake files editor with syntax highlighting, code assist, wizard-oriented project management, Project Nature CMakeBuilder for CDT projects, and incremental project builders.<br />
<br />
* '''Emacs''' [http://www.cmake.org/CMakeDocs/cmake-mode.el combined syntax highlighting and indentation mode]. The file in the repository used to not function properly when running fill-paragraph (M-q). There was a [[CMake Emacs mode patch for comment formatting|patched version]] to fix this, but it is largely unnecessary now that the one in the repository works properly now. To enable it, add the following to your ''.emacs'' file:<br />
<br />
<pre><br />
; Add cmake listfile names to the mode list.<br />
(setq auto-mode-alist<br />
(append<br />
'(("CMakeLists\\.txt\\'" . cmake-mode))<br />
'(("\\.cmake\\'" . cmake-mode))<br />
auto-mode-alist))<br />
<br />
(autoload 'cmake-mode "~/CMake/Docs/cmake-mode.el" t)<br />
</pre><br />
<br />
I've been long irritated with having to deal with multiple buffers all name CMakeLists.txt. Emacs by default will call them CMakeLists.txt, CMakeLists.txt<2>, CMakeLists.txt<3>, etc.. This is really hard to switch back and forth when the buffer names are difficult to associate with location.<br />
<br />
I've found a couple of solutions to this problem.<br />
<br />
<ol><li>Use uniquify emacs package. This gives several options to automatically rename buffers based on their location on disk.<br />
<br />
<pre><br />
;; uniquify.el is a helper routine to help give buffer names a better unique name.<br />
(when (load "uniquify" 'NOERROR)<br />
(require 'uniquify)<br />
(setq uniquify-buffer-name-style 'forward)<br />
;(setq uniquify-buffer-name-style 'post-forward)<br />
)<br />
</pre><br />
</li><br />
<br />
<li>Rename the buffer as part of the cmake-mode<br />
<br />
<pre><br />
(defun cmake-rename-buffer ()<br />
"Renames a CMakeLists.txt buffer to cmake-<directory name>."<br />
(interactive)<br />
;(print (concat "buffer-filename = " (buffer-file-name)))<br />
;(print (concat "buffer-name = " (buffer-name)))<br />
(when (and (buffer-file-name) (string-match "CMakeLists.txt" (buffer-name)))<br />
;(setq file-name (file-name-nondirectory (buffer-file-name)))<br />
(setq parent-dir (file-name-nondirectory (directory-file-name (file-name-directory (buffer-file-name)))))<br />
;(print (concat "parent-dir = " parent-dir))<br />
(setq new-buffer-name (concat "cmake-" parent-dir))<br />
;(print (concat "new-buffer-name= " new-buffer-name))<br />
(rename-buffer new-buffer-name t)<br />
)<br />
)<br />
<br />
(add-hook 'cmake-mode-hook (function cmake-rename-buffer))<br />
</pre><br />
</li></ol><br />
<br />
I actually prefer renaming my buffers with my cmake-rename-buffer function, because the buffer names start with a lower case letter. :)<br />
<br />
* '''Enscript''' [http://tristancarel.com/pub/patches/enscript/cmake.st syntax highlighting rules]. To enable it:<br />
*# copy <tt>cmake.st</tt> in the <tt>hl/</tt> directory.<br />
*#add the following in the <tt>namerules</tt> section of the <tt>hl/enscript.st</tt> file:<br />
<br />
<pre><br />
/CMakeLists\.txt/ cmake;<br />
/\.cmake.*$/ cmake;<br />
/\.ctest.*$/ cmake;<br />
</pre><br />
<br />
* '''[http://kate.kde.org Kate]''', '''KWrite''', '''[http://www.kdevelop.org KDevelop]''' and all other [http://www.kde.org KDE] applications, which use the kate text-editing component support cmake syntax highlighting since KDE 3.4.<br />
<br />
* '''NEdit''' [http://www.cmake.org/Wiki/images/c/c6/NEditCMakeHighlighting-0001.tar.gz syntax highlighting support] was added by [http://public.kitware.com/pipermail/cmake/2007-May/014267.html Philippe Poilbarbe]<br />
<br />
* '''[http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]''' added CMake support in version 4.1<br />
<br />
* '''[http://scintilla.sourceforge.net/SciTEDownload.html SciTE]''' version 1.73 has CMake support. To enable the feature edit SciTEGlobal.Properties and remove the comment before the CMake lines.<br />
<br />
* '''[http://www.macromates.com TextMate]''' is a wonderful text editor for OS X. [http://www.bluequartz.net/software/files/CMake.tmbundle.pkg CMake Bundle]. This plugin adds syntax highlighting for CMake files and rudimentary completion for command, properties and cmake variables.<br />
<br />
* '''UltraEdit''' syntax highlighting [http://www.cmake.org/Wiki/images/5/56/UltraEditWordfile.tar.gz word file.]<br />
<br />
* '''VIM''' [http://www.cmake.org/CMakeDocs/cmake-syntax.vim syntax highlighting] and [http://www.cmake.org/CMakeDocs/cmake-indent.vim indentation mode]. To enable indentation, copy indentation file to your .vim/indent directory, syntax highlighting file to your .vim/syntax directory and add the following to your .vimrc:<br />
<br />
<pre><br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in runtime! indent/cmake.vim <br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in setf cmake<br />
:autocmd BufRead,BufNewFile *.ctest,*.ctest.in setf cmake<br />
</pre><br />
<br />
==Creating New Editor Mode==<br />
<br />
The best way to start is to check the logic in existing ones. Make sure to enable indentation for files that match the following file names:<br />
<br />
* CMakeLists.txt<br />
* *.cmake<br />
* *.cmake.in<br />
* *.ctest<br />
* *.ctest.in</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_Editors_Support&diff=15209CMake Editors Support2009-04-28T16:41:03Z<p>Bigler: /* CMake Editor Modes */ Update on fill-paragraph working in repository</p>
<hr />
<div>==CMake Editor Modes==<br />
<br />
There are [[CMake]] syntax highlighting and indentation supports for many editors:<br />
<br />
* '''Eclipse''' There are two plugins for Eclipse:<br />
** The [http://cmakeed.sourceforge.net CMakeEd] plugin for Eclipse provides syntax coloring and content assist for editing CMakeLists.txt and any file ending in a .cmake extension. It also integrates the CMake command reference documentation into the Eclipse Help system. This plugin does NOT do project management for you or generate CMake files for you. You are still responsible for this part. CMakeEd just makes writing the CMakeLists.txt files easier.<br />
** The [http://www.cmakebuilder.com/ CMakeBuilder] plugin provides a user friendly interface to easily manage CMake-based projects, with the following features: advanced parser, Advanced CMake outline, CMakeBuilder perspective, symbol table and environment inspector, CMake files editor with syntax highlighting, code assist, wizard-oriented project management, Project Nature CMakeBuilder for CDT projects, and incremental project builders.<br />
<br />
* '''Emacs''' [http://www.cmake.org/CMakeDocs/cmake-mode.el combined syntax highlighting and indentation mode]. The file in the repository used to not function properly when running fill-paragraph (M-q). There was a [[CMake Emacs mode patch for comment formatting|patched version]] to fix this, but it is largely unnecessary now that the one in the repository works properly now. To enable it, add the following to your ''.emacs'' file:<br />
<br />
<pre><br />
; Add cmake listfile names to the mode list.<br />
(setq auto-mode-alist<br />
(append<br />
'(("CMakeLists\\.txt\\'" . cmake-mode))<br />
'(("\\.cmake\\'" . cmake-mode))<br />
auto-mode-alist))<br />
<br />
(autoload 'cmake-mode "~/CMake/Docs/cmake-mode.el" t)<br />
</pre><br />
<br />
* '''Enscript''' [http://tristancarel.com/pub/patches/enscript/cmake.st syntax highlighting rules]. To enable it:<br />
*# copy <tt>cmake.st</tt> in the <tt>hl/</tt> directory.<br />
*#add the following in the <tt>namerules</tt> section of the <tt>hl/enscript.st</tt> file:<br />
<br />
<pre><br />
/CMakeLists\.txt/ cmake;<br />
/\.cmake.*$/ cmake;<br />
/\.ctest.*$/ cmake;<br />
</pre><br />
<br />
* '''[http://kate.kde.org Kate]''', '''KWrite''', '''[http://www.kdevelop.org KDevelop]''' and all other [http://www.kde.org KDE] applications, which use the kate text-editing component support cmake syntax highlighting since KDE 3.4.<br />
<br />
* '''NEdit''' [http://www.cmake.org/Wiki/images/c/c6/NEditCMakeHighlighting-0001.tar.gz syntax highlighting support] was added by [http://public.kitware.com/pipermail/cmake/2007-May/014267.html Philippe Poilbarbe]<br />
<br />
* '''[http://notepad-plus.sourceforge.net/uk/site.htm Notepad++]''' added CMake support in version 4.1<br />
<br />
* '''[http://scintilla.sourceforge.net/SciTEDownload.html SciTE]''' version 1.73 has CMake support. To enable the feature edit SciTEGlobal.Properties and remove the comment before the CMake lines.<br />
<br />
* '''[http://www.macromates.com TextMate]''' is a wonderful text editor for OS X. [http://www.bluequartz.net/software/files/CMake.tmbundle.pkg CMake Bundle]. This plugin adds syntax highlighting for CMake files and rudimentary completion for command, properties and cmake variables.<br />
<br />
* '''UltraEdit''' syntax highlighting [http://www.cmake.org/Wiki/images/5/56/UltraEditWordfile.tar.gz word file.]<br />
<br />
* '''VIM''' [http://www.cmake.org/CMakeDocs/cmake-syntax.vim syntax highlighting] and [http://www.cmake.org/CMakeDocs/cmake-indent.vim indentation mode]. To enable indentation, copy indentation file to your .vim/indent directory, syntax highlighting file to your .vim/syntax directory and add the following to your .vimrc:<br />
<br />
<pre><br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in runtime! indent/cmake.vim <br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in setf cmake<br />
:autocmd BufRead,BufNewFile *.ctest,*.ctest.in setf cmake<br />
</pre><br />
<br />
==Creating New Editor Mode==<br />
<br />
The best way to start is to check the logic in existing ones. Make sure to enable indentation for files that match the following file names:<br />
<br />
* CMakeLists.txt<br />
* *.cmake<br />
* *.cmake.in<br />
* *.ctest<br />
* *.ctest.in</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_Emacs_mode_patch_for_comment_formatting&diff=14978CMake Emacs mode patch for comment formatting2009-04-08T23:06:58Z<p>Bigler: Undo revision 14474 by Plowman (Talk) The version of cmake-mode.el the link points to isn't the same as the one here.</p>
<hr />
<div><pre><br />
;=============================================================================<br />
;<br />
; Program: CMake - Cross-Platform Makefile Generator<br />
; Module: $RCSfile: cmake-mode.el,v $<br />
;<br />
; Copyright (c) 2000-$Date: 2006/09/23 20:32:34 $ Kitware, Inc., Insight Consortium. All rights reserved.<br />
; See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.<br />
;<br />
; This software is distributed WITHOUT ANY WARRANTY; without even<br />
; the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR<br />
; PURPOSE. See the above copyright notices for more information.<br />
;<br />
;=============================================================================<br />
;;; cmake-mode.el --- major-mode for editing CMake sources<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;; Commentary:<br />
<br />
;; Provides syntax highlighting and indentation for CMakeLists.txt and<br />
;; *.cmake source files.<br />
;;<br />
;; Add this code to your .emacs file to use the mode:<br />
;;<br />
;; (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path))<br />
;; (require 'cmake-mode)<br />
;; (setq auto-mode-alist<br />
;; (append '(("CMakeLists\\.txt\\'" . cmake-mode)<br />
;; ("\\.cmake\\'" . cmake-mode))<br />
;; auto-mode-alist))<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;; Code:<br />
<br />
;;<br />
;; Regular expressions used by line indentation function.<br />
;;<br />
(defconst cmake-regex-blank "^[ \t]*$")<br />
(defconst cmake-regex-comment "#.*$")<br />
(defconst cmake-regex-blank-comment "#^[ \t]*$")<br />
(defconst cmake-regex-paren-left "(")<br />
(defconst cmake-regex-paren-right ")")<br />
(defconst cmake-regex-argument-quoted<br />
"\"\\([^\"\\\\]\\|\\\\\\(.\\|\n\\)\\)*\"")<br />
(defconst cmake-regex-argument-unquoted<br />
"\\([^ \t\r\n()#\"\\\\]\\|\\\\.\\)\\([^ \t\r\n()#\\\\]\\|\\\\.\\)*")<br />
(defconst cmake-regex-token (concat "\\(" cmake-regex-comment<br />
"\\|" cmake-regex-paren-left<br />
"\\|" cmake-regex-paren-right<br />
"\\|" cmake-regex-argument-unquoted<br />
"\\|" cmake-regex-argument-quoted<br />
"\\)"))<br />
(defconst cmake-regex-indented (concat "^\\("<br />
cmake-regex-token<br />
"\\|" "[ \t\r\n]"<br />
"\\)*"))<br />
(defconst cmake-regex-block-open<br />
"^\\(IF\\|MACRO\\|FOREACH\\|ELSE\\|ELSEIF\\|WHILE\\)$")<br />
(defconst cmake-regex-block-close<br />
"^[ \t]*\\(ENDIF\\|ENDFOREACH\\|ENDMACRO\\|ELSE\\|ELSEIF\\|ENDWHILE\\)[ \t]*(")<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Helper functions for line indentation function.<br />
;;<br />
(defun cmake-line-starts-inside-string ()<br />
"Determine whether the beginning of the current line is in a string."<br />
(if (save-excursion<br />
(beginning-of-line)<br />
(let ((parse-end (point)))<br />
(beginning-of-buffer)<br />
(nth 3 (parse-partial-sexp (point) parse-end))<br />
)<br />
)<br />
t<br />
nil<br />
)<br />
)<br />
<br />
(defun cmake-find-last-indented-line ()<br />
"Move to the beginning of the last line that has meaningful indentation."<br />
(let ((point-start (point))<br />
region)<br />
(forward-line -1)<br />
(setq region (buffer-substring-no-properties (point) point-start))<br />
(while (and (not (bobp))<br />
(or (looking-at cmake-regex-blank)<br />
(not (and (string-match cmake-regex-indented region)<br />
(= (length region) (match-end 0))))))<br />
(forward-line -1)<br />
(setq region (buffer-substring-no-properties (point) point-start))<br />
)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Line indentation function.<br />
;;<br />
(defun cmake-indent ()<br />
"Indent current line as CMAKE code."<br />
(interactive)<br />
(beginning-of-line)<br />
(if (cmake-line-starts-inside-string)<br />
()<br />
(if (bobp)<br />
(indent-line-to 0)<br />
(let ((point-start (point))<br />
token cur-indent)<br />
<br />
(save-excursion<br />
; Search back for the last indented line.<br />
(cmake-find-last-indented-line)<br />
<br />
; Start with the indentation on this line.<br />
(setq cur-indent (current-indentation))<br />
<br />
; Search forward counting tokens that adjust indentation.<br />
(while (re-search-forward cmake-regex-token point-start t)<br />
(setq token (match-string 0))<br />
(if (string-match (concat "^" cmake-regex-paren-left "$") token)<br />
(setq cur-indent (+ cur-indent cmake-tab-width))<br />
)<br />
(if (string-match (concat "^" cmake-regex-paren-right "$") token)<br />
(setq cur-indent (- cur-indent cmake-tab-width))<br />
)<br />
(if (and<br />
(string-match cmake-regex-block-open token)<br />
(looking-at (concat "[ \t]*" cmake-regex-paren-left))<br />
)<br />
(setq cur-indent (+ cur-indent cmake-tab-width))<br />
)<br />
)<br />
)<br />
<br />
; If this is the end of a block, decrease indentation.<br />
(if (looking-at cmake-regex-block-close)<br />
(setq cur-indent (- cur-indent cmake-tab-width))<br />
)<br />
<br />
; Indent this line by the amount selected.<br />
(if (< cur-indent 0)<br />
(indent-line-to 0)<br />
(indent-line-to cur-indent)<br />
)<br />
)<br />
)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Fill comment paragraph functions.<br />
;;<br />
(defconst cmake-fill-comment-prefix "# ")<br />
<br />
(defun cmake-fill-comment-paragraph-justify ()<br />
"Fills the current comment paragraph with justified margins."<br />
(interactive)<br />
(cmake-fill-comment-paragraph 1)<br />
)<br />
<br />
(defun cmake-fill-comment-paragraph (&optional justify)<br />
"Fills the current comment paragraph."<br />
(interactive "P")<br />
(let ((opos (point-marker))<br />
(begin nil)<br />
(end nil)<br />
(indent nil)<br />
)<br />
<br />
; Check if we are inside a comment.<br />
(if (not (progn<br />
(back-to-indentation)<br />
(looking-at cmake-regex-comment)))<br />
(error "not inside a comment paragraph ..."))<br />
; *** are right-side comments valid; how do we treat them here??? ***<br />
<br />
(message "filling comment paragraph ...")<br />
<br />
;;<br />
;; Find limits of paragraph.<br />
;;<br />
; Find end of paragraph.<br />
(save-excursion<br />
(while (and<br />
; we are in a comment<br />
(progn<br />
(back-to-indentation)<br />
(and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
; and not at the end of the buffer<br />
(progn<br />
(end-of-line)<br />
(not (= (point) (point-max))))<br />
)<br />
(forward-line 1)<br />
)<br />
(if (progn<br />
(back-to-indentation)<br />
(not (and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment)))))<br />
(forward-line -1))<br />
(end-of-line)<br />
(setq end (point-marker))<br />
)<br />
; Find beginning of paragraph.<br />
(save-excursion<br />
(while (and<br />
; we are in a comment<br />
(progn<br />
(back-to-indentation)<br />
(and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
; and not at the beginning of the buffer<br />
(progn<br />
(beginning-of-line)<br />
(not (= (point) (point-min))))<br />
)<br />
(forward-line -1)<br />
)<br />
(if (progn<br />
(back-to-indentation)<br />
(not (and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
)<br />
(forward-line 1))<br />
(back-to-indentation)<br />
(setq begin (point-marker))<br />
(setq indent(current-column))<br />
)<br />
<br />
;;<br />
;; Delete leading whitespace and uncomment.<br />
;;<br />
(save-excursion<br />
(goto-char begin)<br />
(beginning-of-line)<br />
(while (re-search-forward<br />
(concat "^[ \t]*\\("<br />
cmake-fill-comment-prefix<br />
"\\|#\\)[ \t]*"<br />
)<br />
end t)<br />
(replace-match "")<br />
)<br />
)<br />
<br />
;;<br />
;; Fill paragraph<br />
;;<br />
; Calculate fill width minus indent minus prefix.<br />
(setq fill-column (- fill-column<br />
indent<br />
(length cmake-fill-comment-prefix)<br />
))<br />
; Fill paragraph.<br />
(fill-region begin end justify)<br />
; Restore fill width.<br />
(setq fill-column (+ fill-column<br />
indent<br />
(length cmake-fill-comment-prefix)<br />
))<br />
<br />
;;<br />
;; Re-comment and re-indent region.<br />
;;<br />
(save-excursion<br />
(goto-char begin)<br />
(setq count (point-marker))<br />
(while (< count end)<br />
(beginning-of-line)<br />
(indent-to indent)<br />
(insert cmake-fill-comment-prefix)<br />
(forward-line 1)<br />
(setq count (point-marker))<br />
)<br />
)<br />
<br />
;;<br />
;; Delete the extra line that gets inserted somehow in XEmacs???<br />
;;<br />
(if version-xemacs<br />
(save-excursion<br />
(goto-char end)<br />
(end-of-line)<br />
(delete-char 1)<br />
)<br />
)<br />
<br />
(message "filling comment paragraph ... done")<br />
(goto-char opos)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Keyword highlighting regex-to-face map.<br />
;;<br />
(defconst cmake-font-lock-keywords<br />
(list '("^[ \t]*\\(\\w+\\)[ \t]*(" 1 font-lock-function-name-face))<br />
"Highlighting expressions for CMAKE mode."<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Syntax table for this mode. Initialize to nil so that it is<br />
;; regenerated when the cmake-mode function is called.<br />
;;<br />
(defvar cmake-mode-syntax-table nil "Syntax table for cmake-mode.")<br />
(setq cmake-mode-syntax-table nil)<br />
<br />
;;<br />
;; User hook entry point.<br />
;;<br />
(defvar cmake-mode-hook nil)<br />
<br />
;;<br />
;; Indentation increment.<br />
;;<br />
(defvar cmake-tab-width 2)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; CMake mode startup function.<br />
;;<br />
(defun cmake-mode ()<br />
"Major mode for editing CMake listfiles."<br />
(interactive)<br />
(kill-all-local-variables)<br />
(setq major-mode 'cmake-mode)<br />
(setq mode-name "CMAKE")<br />
<br />
; Create the syntax table<br />
(setq cmake-mode-syntax-table (make-syntax-table))<br />
(set-syntax-table cmake-mode-syntax-table)<br />
(modify-syntax-entry ?_ "w" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\( "()" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\) ")(" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?# "<" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\n ">" cmake-mode-syntax-table)<br />
<br />
; Setup font-lock mode.<br />
(make-local-variable 'font-lock-defaults)<br />
(setq font-lock-defaults '(cmake-font-lock-keywords))<br />
<br />
; Setup indentation function.<br />
(make-local-variable 'indent-line-function)<br />
(setq indent-line-function 'cmake-indent)<br />
<br />
; Setup comment syntax.<br />
(make-local-variable 'comment-start)<br />
(setq comment-start "#")<br />
<br />
; Some local overrides of functions<br />
(make-local-variable 'fill-paragraph-function)<br />
(setq fill-paragraph-function 'cmake-fill-comment-paragraph)<br />
<br />
; Run user hooks.<br />
(run-hooks 'cmake-mode-hook))<br />
<br />
; This file provides cmake-mode.<br />
(provide 'cmake-mode)<br />
<br />
;;; cmake-mode.el ends here<br />
</pre></div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_FAQ&diff=14891CMake FAQ2009-03-27T22:31:21Z<p>Bigler: /* How can I extend the build modes with a custom made one ? */ Fix note to be more clear.</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://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> accpets 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 />
== 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 />
=== 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 />
=== 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>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMakeCompareVersionStrings&diff=10507CMakeCompareVersionStrings2007-09-24T17:41:17Z<p>Bigler: Added COMPARE_VERSION macro for the testing code.</p>
<hr />
<div>I needed a way to compare two version strings to make sure that I had a version of a package that was sufficient for my needs. The first go around I used regular expressions to pull out all the dot versions, create a number, and finally compare the number.<br />
<br />
<pre><br />
SET(THREE_PART_VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+")<br />
<br />
# Breaks up a string in the form n1.n2.n3 into three parts and stores<br />
# them in major, minor, and patch. version should be a value, not a<br />
# variable, while major, minor and patch should be variables.<br />
MACRO(THREE_PART_VERSION_TO_VARS version major minor patch)<br />
IF(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" ${major} "${version}")<br />
STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" ${minor} "${version}")<br />
STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" ${patch} "${version}")<br />
ELSE(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
MESSAGE("MACRO(THREE_PART_VERSION_TO_VARS ${version} ${major} ${minor} ${patch}")<br />
MESSAGE(FATAL_ERROR "Problem parsing version string, I can't parse it properly.")<br />
ENDIF(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
ENDMACRO(THREE_PART_VERSION_TO_VARS)<br />
<br />
THREE_PART_VERSION_TO_VARS(${version-string} major_vers minor_vers patch_vers)<br />
MESSAGE("version = ${major_vers}.${minor_vers}.${patch_vers}")<br />
<br />
# Compute a version number<br />
MATH(EXPR version_number "${major_vers} * 1000000 + ${minor_vers} * 1000 + ${patch_vers}" )<br />
MESSAGE("version_number = ${version_number}")<br />
</pre><br />
<br />
This was somewhat cumbersome, and was hard coded for three dot versions (x.y.z). I wanted to be able to use a single macro for version strings with 1 to any number of dot versions. In addition I wanted to be able to compare version strings with different number of dot versions (i.e. 0.99.1 and 0.99.1.2).<br />
<br />
<pre><br />
# Computes the realtionship between two version strings. A version<br />
# string is a number delineated by '.'s such as 1.3.2 and 0.99.9.1.<br />
# You can feed version strings with different number of dot versions,<br />
# and the shorter version number will be padded with zeros: 9.2 <<br />
# 9.2.1 will actually compare 9.2.0 < 9.2.1.<br />
#<br />
# Input: a_in - value, not variable<br />
# b_in - value, not variable<br />
# result_out - variable with value:<br />
# -1 : a_in < b_in<br />
# 0 : a_in == b_in<br />
# 1 : a_in > b_in<br />
#<br />
# Written by James Bigler.<br />
MACRO(COMPARE_VERSION_STRINGS a_in b_in result_out)<br />
# Since SEPARATE_ARGUMENTS using ' ' as the separation token,<br />
# replace '.' with ' ' to allow easy tokenization of the string.<br />
STRING(REPLACE "." " " a ${a_in})<br />
STRING(REPLACE "." " " b ${b_in})<br />
SEPARATE_ARGUMENTS(a)<br />
SEPARATE_ARGUMENTS(b)<br />
<br />
# Check the size of each list to see if they are equal.<br />
LIST(LENGTH a a_length)<br />
LIST(LENGTH b b_length)<br />
<br />
# Pad the shorter list with zeros.<br />
<br />
# Note that range needs to be one less than the length as the for<br />
# loop is inclusive (silly CMake).<br />
IF(a_length LESS b_length)<br />
# a is shorter<br />
SET(shorter a)<br />
MATH(EXPR range "${b_length} - 1")<br />
MATH(EXPR pad_range "${b_length} - ${a_length} - 1")<br />
ELSE(a_length LESS b_length)<br />
# b is shorter<br />
SET(shorter b)<br />
MATH(EXPR range "${a_length} - 1")<br />
MATH(EXPR pad_range "${a_length} - ${b_length} - 1")<br />
ENDIF(a_length LESS b_length)<br />
<br />
# PAD out if we need to<br />
IF(NOT pad_range LESS 0)<br />
FOREACH(pad RANGE ${pad_range})<br />
# Since shorter is an alias for b, we need to get to it by by dereferencing shorter.<br />
LIST(APPEND ${shorter} 0)<br />
ENDFOREACH(pad RANGE ${pad_range})<br />
ENDIF(NOT pad_range LESS 0)<br />
<br />
SET(result 0)<br />
FOREACH(index RANGE ${range})<br />
IF(result EQUAL 0)<br />
# Only continue to compare things as long as they are equal<br />
LIST(GET a ${index} a_version)<br />
LIST(GET b ${index} b_version)<br />
# LESS<br />
IF(a_version LESS b_version)<br />
SET(result -1)<br />
ENDIF(a_version LESS b_version)<br />
# GREATER<br />
IF(a_version GREATER b_version)<br />
SET(result 1)<br />
ENDIF(a_version GREATER b_version)<br />
ENDIF(result EQUAL 0)<br />
ENDFOREACH(index)<br />
<br />
# Copy out the return result<br />
SET(${result_out} ${result})<br />
ENDMACRO(COMPARE_VERSION_STRINGS)<br />
</pre><br />
<br />
I tested it with the following input:<br />
<br />
<pre><br />
# a and b need to be passed in by value<br />
MACRO(COMPARE_VERSION a b)<br />
COMPARE_VERSION_STRINGS(${a} ${b} result)<br />
IF(result LESS 0)<br />
MESSAGE("${a} < ${b}")<br />
ELSE(result LESS 0)<br />
IF(result GREATER 0)<br />
MESSAGE("${a} > ${b}")<br />
ELSE(result GREATER 0)<br />
MESSAGE("${a} == ${b}")<br />
ENDIF(result GREATER 0)<br />
ENDIF(result LESS 0)<br />
ENDMACRO(COMPARE_VERSION)<br />
<br />
SET(version-string "1.3.31")<br />
<br />
COMPARE_VERSION(${version-string} "1.3.30")<br />
COMPARE_VERSION(${version-string} "1.3.31")<br />
COMPARE_VERSION(${version-string} "1.3.32")<br />
COMPARE_VERSION(${version-string} "1.2.32")<br />
COMPARE_VERSION(${version-string} "1.10.1")<br />
<br />
COMPARE_VERSION("9.2" "9.1")<br />
COMPARE_VERSION("9.2" "9.2")<br />
COMPARE_VERSION("9.2" "9.3")<br />
<br />
COMPARE_VERSION("9.1" "9.2")<br />
COMPARE_VERSION("9.2" "9.2")<br />
COMPARE_VERSION("9.3" "9.2")<br />
<br />
COMPARE_VERSION("9.10" "9.2")<br />
COMPARE_VERSION("9.2" "9.10")<br />
<br />
COMPARE_VERSION("0.92.1.0" "0.92.1.1")<br />
COMPARE_VERSION("0.92.1.1" "0.92.1.1")<br />
COMPARE_VERSION("0.92.1.2" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.92.1.2" "0.99.1.1")<br />
COMPARE_VERSION("0.99.1.2" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.92.1.2" "0.99.1")<br />
COMPARE_VERSION("0.99.1" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.99.1.2" "0.99.1")<br />
COMPARE_VERSION("0.99.1" "0.99.1.1")<br />
<br />
COMPARE_VERSION( "1" "10")<br />
COMPARE_VERSION("10" "1")<br />
</pre><br />
<br />
Here's the output:<br />
<br />
<pre><br />
1.3.31 > 1.3.30<br />
1.3.31 == 1.3.31<br />
1.3.31 < 1.3.32<br />
1.3.31 > 1.2.32 (note this is 1.2 not 1.3)<br />
1.3.31 < 1.10.1<br />
9.2 > 9.1<br />
9.2 == 9.2<br />
9.2 < 9.3<br />
9.1 < 9.2<br />
9.2 == 9.2<br />
9.3 > 9.2<br />
9.10 > 9.2<br />
9.2 < 9.10<br />
0.92.1.0 < 0.92.1.1<br />
0.92.1.1 == 0.92.1.1<br />
0.92.1.2 > 0.92.1.1<br />
0.92.1.2 < 0.99.1.1<br />
0.99.1.2 > 0.92.1.1<br />
0.92.1.2 < 0.99.1<br />
0.99.1 > 0.92.1.1<br />
0.99.1.2 > 0.99.1<br />
0.99.1 < 0.99.1.1<br />
1 < 10<br />
10 > 1<br />
</pre></div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMakeCompareVersionStrings&diff=10504CMakeCompareVersionStrings2007-09-24T17:38:53Z<p>Bigler: Filled in text for COMAPRE_VERSION_STRING macro</p>
<hr />
<div>I needed a way to compare two version strings to make sure that I had a version of a package that was sufficient for my needs. The first go around I used regular expressions to pull out all the dot versions, create a number, and finally compare the number.<br />
<br />
<pre><br />
SET(THREE_PART_VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+")<br />
<br />
# Breaks up a string in the form n1.n2.n3 into three parts and stores<br />
# them in major, minor, and patch. version should be a value, not a<br />
# variable, while major, minor and patch should be variables.<br />
MACRO(THREE_PART_VERSION_TO_VARS version major minor patch)<br />
IF(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" ${major} "${version}")<br />
STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" ${minor} "${version}")<br />
STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" ${patch} "${version}")<br />
ELSE(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
MESSAGE("MACRO(THREE_PART_VERSION_TO_VARS ${version} ${major} ${minor} ${patch}")<br />
MESSAGE(FATAL_ERROR "Problem parsing version string, I can't parse it properly.")<br />
ENDIF(${version} MATCHES ${THREE_PART_VERSION_REGEX})<br />
ENDMACRO(THREE_PART_VERSION_TO_VARS)<br />
<br />
THREE_PART_VERSION_TO_VARS(${version-string} major_vers minor_vers patch_vers)<br />
MESSAGE("version = ${major_vers}.${minor_vers}.${patch_vers}")<br />
<br />
# Compute a version number<br />
MATH(EXPR version_number "${major_vers} * 1000000 + ${minor_vers} * 1000 + ${patch_vers}" )<br />
MESSAGE("version_number = ${version_number}")<br />
</pre><br />
<br />
This was somewhat cumbersome, and was hard coded for three dot versions (x.y.z). I wanted to be able to use a single macro for version strings with 1 to any number of dot versions. In addition I wanted to be able to compare version strings with different number of dot versions (i.e. 0.99.1 and 0.99.1.2).<br />
<br />
<pre><br />
# Computes the realtionship between two version strings. A version<br />
# string is a number delineated by '.'s such as 1.3.2 and 0.99.9.1.<br />
# You can feed version strings with different number of dot versions,<br />
# and the shorter version number will be padded with zeros: 9.2 <<br />
# 9.2.1 will actually compare 9.2.0 < 9.2.1.<br />
#<br />
# Input: a_in - value, not variable<br />
# b_in - value, not variable<br />
# result_out - variable with value:<br />
# -1 : a_in < b_in<br />
# 0 : a_in == b_in<br />
# 1 : a_in > b_in<br />
#<br />
# Written by James Bigler.<br />
MACRO(COMPARE_VERSION_STRINGS a_in b_in result_out)<br />
# Since SEPARATE_ARGUMENTS using ' ' as the separation token,<br />
# replace '.' with ' ' to allow easy tokenization of the string.<br />
STRING(REPLACE "." " " a ${a_in})<br />
STRING(REPLACE "." " " b ${b_in})<br />
SEPARATE_ARGUMENTS(a)<br />
SEPARATE_ARGUMENTS(b)<br />
<br />
# Check the size of each list to see if they are equal.<br />
LIST(LENGTH a a_length)<br />
LIST(LENGTH b b_length)<br />
<br />
# Pad the shorter list with zeros.<br />
<br />
# Note that range needs to be one less than the length as the for<br />
# loop is inclusive (silly CMake).<br />
IF(a_length LESS b_length)<br />
# a is shorter<br />
SET(shorter a)<br />
MATH(EXPR range "${b_length} - 1")<br />
MATH(EXPR pad_range "${b_length} - ${a_length} - 1")<br />
ELSE(a_length LESS b_length)<br />
# b is shorter<br />
SET(shorter b)<br />
MATH(EXPR range "${a_length} - 1")<br />
MATH(EXPR pad_range "${a_length} - ${b_length} - 1")<br />
ENDIF(a_length LESS b_length)<br />
<br />
# PAD out if we need to<br />
IF(NOT pad_range LESS 0)<br />
FOREACH(pad RANGE ${pad_range})<br />
# Since shorter is an alias for b, we need to get to it by by dereferencing shorter.<br />
LIST(APPEND ${shorter} 0)<br />
ENDFOREACH(pad RANGE ${pad_range})<br />
ENDIF(NOT pad_range LESS 0)<br />
<br />
SET(result 0)<br />
FOREACH(index RANGE ${range})<br />
IF(result EQUAL 0)<br />
# Only continue to compare things as long as they are equal<br />
LIST(GET a ${index} a_version)<br />
LIST(GET b ${index} b_version)<br />
# LESS<br />
IF(a_version LESS b_version)<br />
SET(result -1)<br />
ENDIF(a_version LESS b_version)<br />
# GREATER<br />
IF(a_version GREATER b_version)<br />
SET(result 1)<br />
ENDIF(a_version GREATER b_version)<br />
ENDIF(result EQUAL 0)<br />
ENDFOREACH(index)<br />
<br />
# Copy out the return result<br />
SET(${result_out} ${result})<br />
ENDMACRO(COMPARE_VERSION_STRINGS)<br />
</pre><br />
<br />
I tested it with the following input:<br />
<br />
<pre><br />
SET(version-string "1.3.31")<br />
<br />
COMPARE_VERSION(${version-string} "1.3.30")<br />
COMPARE_VERSION(${version-string} "1.3.31")<br />
COMPARE_VERSION(${version-string} "1.3.32")<br />
COMPARE_VERSION(${version-string} "1.2.32")<br />
COMPARE_VERSION(${version-string} "1.10.1")<br />
<br />
COMPARE_VERSION("9.2" "9.1")<br />
COMPARE_VERSION("9.2" "9.2")<br />
COMPARE_VERSION("9.2" "9.3")<br />
<br />
COMPARE_VERSION("9.1" "9.2")<br />
COMPARE_VERSION("9.2" "9.2")<br />
COMPARE_VERSION("9.3" "9.2")<br />
<br />
COMPARE_VERSION("9.10" "9.2")<br />
COMPARE_VERSION("9.2" "9.10")<br />
<br />
COMPARE_VERSION("0.92.1.0" "0.92.1.1")<br />
COMPARE_VERSION("0.92.1.1" "0.92.1.1")<br />
COMPARE_VERSION("0.92.1.2" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.92.1.2" "0.99.1.1")<br />
COMPARE_VERSION("0.99.1.2" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.92.1.2" "0.99.1")<br />
COMPARE_VERSION("0.99.1" "0.92.1.1")<br />
<br />
COMPARE_VERSION("0.99.1.2" "0.99.1")<br />
COMPARE_VERSION("0.99.1" "0.99.1.1")<br />
<br />
COMPARE_VERSION( "1" "10")<br />
COMPARE_VERSION("10" "1")<br />
</pre><br />
<br />
Here's the output:<br />
<br />
<pre><br />
1.3.31 > 1.3.30<br />
1.3.31 == 1.3.31<br />
1.3.31 < 1.3.32<br />
1.3.31 > 1.2.32 (note this is 1.2 not 1.3)<br />
1.3.31 < 1.10.1<br />
9.2 > 9.1<br />
9.2 == 9.2<br />
9.2 < 9.3<br />
9.1 < 9.2<br />
9.2 == 9.2<br />
9.3 > 9.2<br />
9.10 > 9.2<br />
9.2 < 9.10<br />
0.92.1.0 < 0.92.1.1<br />
0.92.1.1 == 0.92.1.1<br />
0.92.1.2 > 0.92.1.1<br />
0.92.1.2 < 0.99.1.1<br />
0.99.1.2 > 0.92.1.1<br />
0.92.1.2 < 0.99.1<br />
0.99.1 > 0.92.1.1<br />
0.99.1.2 > 0.99.1<br />
0.99.1 < 0.99.1.1<br />
1 < 10<br />
10 > 1<br />
</pre></div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_User_Contributed_Macros&diff=10503CMake User Contributed Macros2007-09-24T17:18:03Z<p>Bigler: Added link for Compare Version Strings.</p>
<hr />
<div>'''User Contributed Macros'''<br />
<br />
== Find Modules ==<br />
Although CMake comes with a whole bunch of FindXXX packages, there is a large number of packages there are not covered. The hope is that these user-contributed macros will eventually make their way into the official distribution. Before contributing, please have your FindXXX package conform to the [http://www.cmake.org/cgi-bin/viewcvs.cgi/Modules/readme.txt?root=CMake&view=markup CMake Module Guidelines].<br />
<br />
#[[CMakeUserFindAUTOPACK | Find Autopack]]<br />
#[[CMakeUserFindClanLib | Find ClanLib]]<br />
#[[CMakeUserFindDirectShow | Find DirectShow]]<br />
#[[CMakeUserFindMySQL | Find MySQL]]<br />
#[[CMakeUserFindPARMETIS | Find ParMetis]]<br />
#[[CMakeUserFindVLD| Find VLD - Visual Leak Debugger]]<br />
#[[CMakeUserUseBison| Use Bison - Parser Generator]]<br />
#[[CMakeUserUseFlex| Use Flex - Lexer Generator]]<br />
#[[CMakeUserUseLATEX| Use LaTeX - Build LaTeX Documents]]<br />
#[[CMakeUserUseRPMTools| Use RPM Tools - Build RPM (source or binary)]]<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Make Equivalents ==<br />
While attempting to convert a gnu makefile to Cmake, there was <br />
a need to provide some macros to provide equivalent functionality. <br />
<br />
#[[CMakeMacroFilterOut | FILTER_OUT (filter-out)]]<br />
#[[CMakeMacroLibtoolFile | CREATE_LIBTOOL_FILE (create a libtool archive file)]]<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Some helpers along the way ==<br />
#[[CMakeCopyIfDifferent | COPY_IF_DIFFERENT]]<br />
#[[CMakeMacroMerge | MERGE]] --- Merges two sorted lists into a single sorted list. Useful to keep source and header files next to each other.<br />
#[[CMakeMacroCreateFinalFile | CREATE_FINAL_FILE]] -- create a KDE style final file, which includes all source files, so that the compilation will be noticable faster.<br />
#[[CMakeMacroListOperations | List Operations]] -- A compilation of some helpful list operations.<br />
#[[CMakeMacroParseArguments | PARSE_ARGUMENTS]] -- A macro to help parse arguments for other macros.<br />
#[[CMakeMacroAddCxxTest | ADD_CXXTEXT]] -- A macro to add tests written the CxxTest testing framework.<br />
#[[CMakeMacroForceAddFlags | Force Flags]] -- A macro to force certain arguments for specified flag (similar to a set union).<br />
#[[CMakeTestInline | Test Inline]] -- A test for how your compiler defines inline.<br />
#[[CMakeCompareVersionStrings | COMPARE_VERSION_STRINGS]] -- A macro to help compare arbitrary version strings for less than, equal to, and greater than.<br />
<br />
See also the list of all macros in the [[:Category:CMakeMacro | CMake Macro category]].<br />
<br />
[[CMake|Home]] <br />
[[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Visual Studio generator helpers ==<br />
When generating Visual Studio projects, the priorities can be <br />
sometimes different than for other generators. These are some<br />
VS-specific (and sometimes not-so-specific) macros that could<br />
help you generate better VS projects.<br />
<br />
#[[CMakeMacroGatherProjectFiles | GatherProjectFiles]] -- create and cache a list of project files by recursively globbing a directory structure<br />
#[[CMakeMacroGenerateProject | GenerateProject]] -- creates a VS project with subgroups that mimic the directory structure<br />
<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
{{CMake/Template/Footer}}</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_Editors_Support&diff=10224CMake Editors Support2007-08-23T18:18:04Z<p>Bigler: Emacs mode patch addition</p>
<hr />
<div>==CMake Editor Modes==<br />
<br />
There are [[CMake]] syntax highlighting and indentation supports for several editors:<br />
<br />
* Emacs [http://www.cmake.org/CMakeDocs/cmake-mode.el combined syntax highlighting and indentation mode]. The current file in the repository doesn't behave very well if you try to run fill-paragrap (M-q) on comments. This [[CMake Emacs mode patch for comment formatting|patched version]] written by Miguell A. Figueroa-Villanueva fixes it. Hopefully the patch will make it into the tree someday. To enable it, add the following to your ''.emacs'' file:<br />
<br />
<pre><br />
; Add cmake listfile names to the mode list.<br />
(setq auto-mode-alist<br />
(append<br />
'(("CMakeLists\\.txt\\'" . cmake-mode))<br />
'(("\\.cmake\\'" . cmake-mode))<br />
auto-mode-alist))<br />
<br />
(autoload 'cmake-mode "~/CMake/Docs/cmake-mode.el" t)<br />
</pre><br />
<br />
* VIM [http://www.cmake.org/CMakeDocs/cmake-syntax.vim syntax highlighting] and [http://www.cmake.org/CMakeDocs/cmake-indent.vim indentation mode]. To enable indentation, copy indentation file to your .vim/indent directory, syntax highlighting file to your .vim/syntax directory and add the following to your .vimrc:<br />
<br />
<pre><br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in runtime! indent/cmake.vim <br />
:autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in setf cmake<br />
:autocmd BufRead,BufNewFile *.ctest,*.ctest.in setf cmake<br />
</pre><br />
<br />
* Eclipse [http://www.cthing.com/CMakeEd.asp CMake Editor]. Plug-in for the Eclipse IDE providing syntax coloring and content assist for editing CMakeLists.txt and any file ending in a .cmake extension. Integrates the CMake command reference documentation into the Eclipse Help system.<br />
<br />
* [http://kate.kde.org Kate], KWrite, [http://www.kdevelop.org KDevelop] and all other [http://www.kde.org KDE] applications, which use the kate text-editing component support cmake syntax highlighting since KDE 3.4.<br />
<br />
* UltraEdit (an approach) save the jpg as text: [[Image:wordfile.jpg]]<br />
<br />
* Enscript [http://tristancarel.com/pub/patches/enscript/cmake.st syntax highlighting rules]. To enable it:<br />
*# copy <tt>cmake.st</tt> in the <tt>hl/</tt> directory.<br />
*#add the following in the <tt>namerules</tt> section of the <tt>hl/enscript.st</tt> file:<br />
<br />
<pre><br />
/CMakeLists\.txt/ cmake;<br />
/\.cmake.*$/ cmake;<br />
/\.ctest.*$/ cmake;<br />
</pre><br />
<br />
* [http://scintilla.sourceforge.net/SciTEDownload.html SciTE] version 1.73 has CMake support. To enable the feature edit SciTEGlobal.Properties and remove the comment before cmake lines.<br />
<br />
* [http://www.macromates.com TextMate] is a wonderful text editor for OS X. [http://www.bluequartz.net/CMake.tmbundle.zip CMake Bundle]. This plugin adds syntax highlighting for Cmake files.<br />
<br />
* NEdit support was added by [http://public.kitware.com/pipermail/cmake/2007-May/014267.html Philippe Poilbarbe]<br />
<br />
==Creating New Editor Mode==<br />
<br />
The best way to start is to check the logic in existing ones. Make sure to enable indentation for files that match the following file names:<br />
<br />
* CMakeLists.txt<br />
* *.cmake<br />
* *.cmake.in<br />
* *.ctest<br />
* *.ctest.in</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_Emacs_mode_patch_for_comment_formatting&diff=10223CMake Emacs mode patch for comment formatting2007-08-23T18:16:54Z<p>Bigler: This is the cmake emacs mode file patched to better formatt comments</p>
<hr />
<div><pre><br />
;=============================================================================<br />
;<br />
; Program: CMake - Cross-Platform Makefile Generator<br />
; Module: $RCSfile: cmake-mode.el,v $<br />
;<br />
; Copyright (c) 2000-$Date: 2006/09/23 20:32:34 $ Kitware, Inc., Insight Consortium. All rights reserved.<br />
; See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.<br />
;<br />
; This software is distributed WITHOUT ANY WARRANTY; without even<br />
; the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR<br />
; PURPOSE. See the above copyright notices for more information.<br />
;<br />
;=============================================================================<br />
;;; cmake-mode.el --- major-mode for editing CMake sources<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;; Commentary:<br />
<br />
;; Provides syntax highlighting and indentation for CMakeLists.txt and<br />
;; *.cmake source files.<br />
;;<br />
;; Add this code to your .emacs file to use the mode:<br />
;;<br />
;; (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path))<br />
;; (require 'cmake-mode)<br />
;; (setq auto-mode-alist<br />
;; (append '(("CMakeLists\\.txt\\'" . cmake-mode)<br />
;; ("\\.cmake\\'" . cmake-mode))<br />
;; auto-mode-alist))<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;; Code:<br />
<br />
;;<br />
;; Regular expressions used by line indentation function.<br />
;;<br />
(defconst cmake-regex-blank "^[ \t]*$")<br />
(defconst cmake-regex-comment "#.*$")<br />
(defconst cmake-regex-blank-comment "#^[ \t]*$")<br />
(defconst cmake-regex-paren-left "(")<br />
(defconst cmake-regex-paren-right ")")<br />
(defconst cmake-regex-argument-quoted<br />
"\"\\([^\"\\\\]\\|\\\\\\(.\\|\n\\)\\)*\"")<br />
(defconst cmake-regex-argument-unquoted<br />
"\\([^ \t\r\n()#\"\\\\]\\|\\\\.\\)\\([^ \t\r\n()#\\\\]\\|\\\\.\\)*")<br />
(defconst cmake-regex-token (concat "\\(" cmake-regex-comment<br />
"\\|" cmake-regex-paren-left<br />
"\\|" cmake-regex-paren-right<br />
"\\|" cmake-regex-argument-unquoted<br />
"\\|" cmake-regex-argument-quoted<br />
"\\)"))<br />
(defconst cmake-regex-indented (concat "^\\("<br />
cmake-regex-token<br />
"\\|" "[ \t\r\n]"<br />
"\\)*"))<br />
(defconst cmake-regex-block-open<br />
"^\\(IF\\|MACRO\\|FOREACH\\|ELSE\\|ELSEIF\\|WHILE\\)$")<br />
(defconst cmake-regex-block-close<br />
"^[ \t]*\\(ENDIF\\|ENDFOREACH\\|ENDMACRO\\|ELSE\\|ELSEIF\\|ENDWHILE\\)[ \t]*(")<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Helper functions for line indentation function.<br />
;;<br />
(defun cmake-line-starts-inside-string ()<br />
"Determine whether the beginning of the current line is in a string."<br />
(if (save-excursion<br />
(beginning-of-line)<br />
(let ((parse-end (point)))<br />
(beginning-of-buffer)<br />
(nth 3 (parse-partial-sexp (point) parse-end))<br />
)<br />
)<br />
t<br />
nil<br />
)<br />
)<br />
<br />
(defun cmake-find-last-indented-line ()<br />
"Move to the beginning of the last line that has meaningful indentation."<br />
(let ((point-start (point))<br />
region)<br />
(forward-line -1)<br />
(setq region (buffer-substring-no-properties (point) point-start))<br />
(while (and (not (bobp))<br />
(or (looking-at cmake-regex-blank)<br />
(not (and (string-match cmake-regex-indented region)<br />
(= (length region) (match-end 0))))))<br />
(forward-line -1)<br />
(setq region (buffer-substring-no-properties (point) point-start))<br />
)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Line indentation function.<br />
;;<br />
(defun cmake-indent ()<br />
"Indent current line as CMAKE code."<br />
(interactive)<br />
(beginning-of-line)<br />
(if (cmake-line-starts-inside-string)<br />
()<br />
(if (bobp)<br />
(indent-line-to 0)<br />
(let ((point-start (point))<br />
token cur-indent)<br />
<br />
(save-excursion<br />
; Search back for the last indented line.<br />
(cmake-find-last-indented-line)<br />
<br />
; Start with the indentation on this line.<br />
(setq cur-indent (current-indentation))<br />
<br />
; Search forward counting tokens that adjust indentation.<br />
(while (re-search-forward cmake-regex-token point-start t)<br />
(setq token (match-string 0))<br />
(if (string-match (concat "^" cmake-regex-paren-left "$") token)<br />
(setq cur-indent (+ cur-indent cmake-tab-width))<br />
)<br />
(if (string-match (concat "^" cmake-regex-paren-right "$") token)<br />
(setq cur-indent (- cur-indent cmake-tab-width))<br />
)<br />
(if (and<br />
(string-match cmake-regex-block-open token)<br />
(looking-at (concat "[ \t]*" cmake-regex-paren-left))<br />
)<br />
(setq cur-indent (+ cur-indent cmake-tab-width))<br />
)<br />
)<br />
)<br />
<br />
; If this is the end of a block, decrease indentation.<br />
(if (looking-at cmake-regex-block-close)<br />
(setq cur-indent (- cur-indent cmake-tab-width))<br />
)<br />
<br />
; Indent this line by the amount selected.<br />
(if (< cur-indent 0)<br />
(indent-line-to 0)<br />
(indent-line-to cur-indent)<br />
)<br />
)<br />
)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Fill comment paragraph functions.<br />
;;<br />
(defconst cmake-fill-comment-prefix "# ")<br />
<br />
(defun cmake-fill-comment-paragraph-justify ()<br />
"Fills the current comment paragraph with justified margins."<br />
(interactive)<br />
(cmake-fill-comment-paragraph 1)<br />
)<br />
<br />
(defun cmake-fill-comment-paragraph (&optional justify)<br />
"Fills the current comment paragraph."<br />
(interactive "P")<br />
(let ((opos (point-marker))<br />
(begin nil)<br />
(end nil)<br />
(indent nil)<br />
)<br />
<br />
; Check if we are inside a comment.<br />
(if (not (progn<br />
(back-to-indentation)<br />
(looking-at cmake-regex-comment)))<br />
(error "not inside a comment paragraph ..."))<br />
; *** are right-side comments valid; how do we treat them here??? ***<br />
<br />
(message "filling comment paragraph ...")<br />
<br />
;;<br />
;; Find limits of paragraph.<br />
;;<br />
; Find end of paragraph.<br />
(save-excursion<br />
(while (and<br />
; we are in a comment<br />
(progn<br />
(back-to-indentation)<br />
(and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
; and not at the end of the buffer<br />
(progn<br />
(end-of-line)<br />
(not (= (point) (point-max))))<br />
)<br />
(forward-line 1)<br />
)<br />
(if (progn<br />
(back-to-indentation)<br />
(not (and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment)))))<br />
(forward-line -1))<br />
(end-of-line)<br />
(setq end (point-marker))<br />
)<br />
; Find beginning of paragraph.<br />
(save-excursion<br />
(while (and<br />
; we are in a comment<br />
(progn<br />
(back-to-indentation)<br />
(and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
; and not at the beginning of the buffer<br />
(progn<br />
(beginning-of-line)<br />
(not (= (point) (point-min))))<br />
)<br />
(forward-line -1)<br />
)<br />
(if (progn<br />
(back-to-indentation)<br />
(not (and (looking-at cmake-regex-comment)<br />
(not (looking-at cmake-regex-blank-comment))))<br />
)<br />
(forward-line 1))<br />
(back-to-indentation)<br />
(setq begin (point-marker))<br />
(setq indent(current-column))<br />
)<br />
<br />
;;<br />
;; Delete leading whitespace and uncomment.<br />
;;<br />
(save-excursion<br />
(goto-char begin)<br />
(beginning-of-line)<br />
(while (re-search-forward<br />
(concat "^[ \t]*\\("<br />
cmake-fill-comment-prefix<br />
"\\|#\\)[ \t]*"<br />
)<br />
end t)<br />
(replace-match "")<br />
)<br />
)<br />
<br />
;;<br />
;; Fill paragraph<br />
;;<br />
; Calculate fill width minus indent minus prefix.<br />
(setq fill-column (- fill-column<br />
indent<br />
(length cmake-fill-comment-prefix)<br />
))<br />
; Fill paragraph.<br />
(fill-region begin end justify)<br />
; Restore fill width.<br />
(setq fill-column (+ fill-column<br />
indent<br />
(length cmake-fill-comment-prefix)<br />
))<br />
<br />
;;<br />
;; Re-comment and re-indent region.<br />
;;<br />
(save-excursion<br />
(goto-char begin)<br />
(setq count (point-marker))<br />
(while (< count end)<br />
(beginning-of-line)<br />
(indent-to indent)<br />
(insert cmake-fill-comment-prefix)<br />
(forward-line 1)<br />
(setq count (point-marker))<br />
)<br />
)<br />
<br />
;;<br />
;; Delete the extra line that gets inserted somehow in XEmacs???<br />
;;<br />
(if version-xemacs<br />
(save-excursion<br />
(goto-char end)<br />
(end-of-line)<br />
(delete-char 1)<br />
)<br />
)<br />
<br />
(message "filling comment paragraph ... done")<br />
(goto-char opos)<br />
)<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Keyword highlighting regex-to-face map.<br />
;;<br />
(defconst cmake-font-lock-keywords<br />
(list '("^[ \t]*\\(\\w+\\)[ \t]*(" 1 font-lock-function-name-face))<br />
"Highlighting expressions for CMAKE mode."<br />
)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; Syntax table for this mode. Initialize to nil so that it is<br />
;; regenerated when the cmake-mode function is called.<br />
;;<br />
(defvar cmake-mode-syntax-table nil "Syntax table for cmake-mode.")<br />
(setq cmake-mode-syntax-table nil)<br />
<br />
;;<br />
;; User hook entry point.<br />
;;<br />
(defvar cmake-mode-hook nil)<br />
<br />
;;<br />
;; Indentation increment.<br />
;;<br />
(defvar cmake-tab-width 2)<br />
<br />
;------------------------------------------------------------------------------<br />
<br />
;;<br />
;; CMake mode startup function.<br />
;;<br />
(defun cmake-mode ()<br />
"Major mode for editing CMake listfiles."<br />
(interactive)<br />
(kill-all-local-variables)<br />
(setq major-mode 'cmake-mode)<br />
(setq mode-name "CMAKE")<br />
<br />
; Create the syntax table<br />
(setq cmake-mode-syntax-table (make-syntax-table))<br />
(set-syntax-table cmake-mode-syntax-table)<br />
(modify-syntax-entry ?_ "w" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\( "()" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\) ")(" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?# "<" cmake-mode-syntax-table)<br />
(modify-syntax-entry ?\n ">" cmake-mode-syntax-table)<br />
<br />
; Setup font-lock mode.<br />
(make-local-variable 'font-lock-defaults)<br />
(setq font-lock-defaults '(cmake-font-lock-keywords))<br />
<br />
; Setup indentation function.<br />
(make-local-variable 'indent-line-function)<br />
(setq indent-line-function 'cmake-indent)<br />
<br />
; Setup comment syntax.<br />
(make-local-variable 'comment-start)<br />
(setq comment-start "#")<br />
<br />
; Some local overrides of functions<br />
(make-local-variable 'fill-paragraph-function)<br />
(setq fill-paragraph-function 'cmake-fill-comment-paragraph)<br />
<br />
; Run user hooks.<br />
(run-hooks 'cmake-mode-hook))<br />
<br />
; This file provides cmake-mode.<br />
(provide 'cmake-mode)<br />
<br />
;;; cmake-mode.el ends here<br />
</pre></div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMakeMacroForceAddFlags&diff=10017CMakeMacroForceAddFlags2007-07-31T18:58:15Z<p>Bigler: Filled in initial text</p>
<hr />
<div>[[CMake_User_Contributed_Macros|Back]]<br />
<br />
I have several projects that depend on the presence of certain arguments to various flags. If the user accidentally removes them, I want to forcefully put them back in while preserving any additional arguments the user may have added. The following macro is helpful for doing this. The operation is similar to a set union, but I don't deal with duplicates in either set.<br />
<br />
<pre><br />
# This will add arguments not found in ${parameter} to the end. It<br />
# does not attempt to remove duplicate arguments already existing in<br />
# ${parameter}.<br />
<br />
MACRO(FORCE_ADD_FLAGS parameter)<br />
# Create a separated list of the arguments to loop over<br />
SET(p_list ${${parameter}})<br />
SEPARATE_ARGUMENTS(p_list)<br />
# Make a copy of the current arguments in ${parameter}<br />
SET(new_parameter ${${parameter}})<br />
# Now loop over each required argument and see if it is in our<br />
# current list of arguments.<br />
FOREACH(required_arg ${ARGN})<br />
# This helps when we get arguments to the function that are<br />
# grouped as a string:<br />
#<br />
# ["-O3 -g"] instead of [-O3 -g]<br />
SET(TMP ${required_arg}) #elsewise the Seperate command doesn't work)<br />
SEPARATE_ARGUMENTS(TMP)<br />
FOREACH(option ${TMP})<br />
# Look for the required argument in our list of existing arguments<br />
SET(found FALSE)<br />
FOREACH(p_arg ${p_list})<br />
IF (${p_arg} STREQUAL ${option})<br />
SET(found TRUE)<br />
ENDIF (${p_arg} STREQUAL ${option})<br />
ENDFOREACH(p_arg)<br />
IF(NOT found)<br />
# The required argument wasn't found, so we need to add it in.<br />
SET(new_parameter "${new_parameter} ${option}")<br />
ENDIF(NOT found)<br />
ENDFOREACH(option ${TMP})<br />
ENDFOREACH(required_arg ${ARGN})<br />
SET(${parameter} ${new_parameter} CACHE STRING "" FORCE)<br />
ENDMACRO(FORCE_ADD_FLAGS)<br />
</pre><br />
<br />
Here is an example script using the macro.<br />
<br />
<pre><br />
SET(flags "")<br />
<br />
MESSAGE("flags = ${flags}")<br />
MESSAGE("forcing: -g3 -msse")<br />
FORCE_ADD_FLAGS(flags -g3 -msse)<br />
MESSAGE("flags = ${flags}")<br />
<br />
MESSAGE("forcing: \"-msse -msse2\" -O3")<br />
FORCE_ADD_FLAGS(flags "-msse -msse2" -O3)<br />
MESSAGE("flags = ${flags}")<br />
<br />
MESSAGE("forcing: -g3")<br />
FORCE_ADD_FLAGS(flags -g3)<br />
MESSAGE("flags = ${flags}")<br />
</pre><br />
<br />
Here's the output.<br />
<br />
<pre><br />
flags =<br />
forcing: -g3 -msse<br />
flags = -g3 -msse<br />
forcing: "-msse -msse2" -O3<br />
flags = -g3 -msse -msse2 -O3<br />
forcing: -g3<br />
flags = -g3 -msse -msse2 -O3<br />
</pre><br />
<br />
Note that forcing a particular argument only adds it if it isn't already present and any previous arguments are left intact.</div>Biglerhttps://public.kitware.com/Wiki/index.php?title=CMake_User_Contributed_Macros&diff=10016CMake User Contributed Macros2007-07-31T18:47:58Z<p>Bigler: Added link to CMakeMacroForceAddFlags</p>
<hr />
<div>'''User Contributed Macros'''<br />
<br />
== Find Modules ==<br />
Although CMake comes with a whole bunch of FindXXX packages, there is a large number of packages there are not covered. The hope is that these user-contributed macros will eventually make their way into the official distribution. Before contributing, please have your FindXXX package conform to the [http://www.cmake.org/cgi-bin/viewcvs.cgi/Modules/readme.txt?root=CMake&view=markup CMake Module Guidelines].<br />
<br />
#[[CMakeUserFindAUTOPACK | Find Autopack]]<br />
#[[CMakeUserFindClanLib | Find ClanLib]]<br />
#[[CMakeUserFindDirectShow | Find DirectShow]]<br />
#[[CMakeUserFindMySQL | Find MySQL]]<br />
#[[CMakeUserFindPARMETIS | Find ParMetis]]<br />
#[[CMakeUserFindVLD| Find VLD - Visual Leak Debugger]]<br />
#[[CMakeUserUseLATEX| Use LaTeX - Build LaTeX Documents]]<br />
#[[CMakeUserUseRPMTools| Use RPM Tools - Build RPM (source or binary)]]<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Make Equivalents ==<br />
While attempting to convert a gnu makefile to Cmake, there was <br />
a need to provide some macros to provide equivalent functionality. <br />
<br />
#[[CMakeMacroFilterOut | FILTER_OUT (filter-out)]]<br />
#[[CMakeMacroLibtoolFile | CREATE_LIBTOOL_FILE (create a libtool archive file)]]<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Some helpers along the way ==<br />
#[[CMakeCopyIfDifferent | COPY_IF_DIFFERENT]]<br />
#[[CMakeMacroMerge | MERGE]] --- Merges two sorted lists into a single sorted list. Useful to keep source and header files next to each other.<br />
#[[CMakeMacroCreateFinalFile | CREATE_FINAL_FILE]] -- create a KDE style final file, which includes all source files, so that the compilation will be noticable faster.<br />
#[[CMakeMacroListOperations | List Operations]] -- A compilation of some helpful list operations.<br />
#[[CMakeMacroParseArguments | PARSE_ARGUMENTS]] -- A macro to help parse arguments for other macros.<br />
#[[CMakeMacroAddCxxTest | ADD_CXXTEXT]] -- A macro to add tests written the CxxTest testing framework.<br />
#[[CMakeMacroForceAddFlags | Force Flags]] -- A macro to force certain arguments for specified flag (similar to a set union).<br />
<br />
See also the list of all macros in the [[:Category:CMakeMacro | CMake Macro category]].<br />
<br />
[[CMake|Home]] <br />
[[CMake_User_Contributed_Macros|Back]]<br />
<br />
== Visual Studio generator helpers ==<br />
When generating Visual Studio projects, the priorities can be <br />
sometimes different than for other generators. These are some<br />
VS-specific (and sometimes not-so-specific) macros that could<br />
help you generate better VS projects.<br />
<br />
#[[CMakeMacroGatherProjectFiles | GatherProjectFiles]] -- create and cache a list of project files by recursively globbing a directory structure<br />
#[[CMakeMacroGenerateProject | GenerateProject]] -- creates a VS project with subgroups that mimic the directory structure<br />
<br />
<br />
[[CMake|Home]] [[CMake_User_Contributed_Macros|Back]]<br />
<br />
{{CMake/Template/Footer}}</div>Bigler