CMake FAQ
General information and availability
What is CMake
CMake is a cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. CMake is quite sophisticated: it is possible to support complex environments requiring system configuration, preprocessor generation, code generation, and template instantiation. Please go to http://www.cmake.org/HTML/About.html to learn more about CMake.
What is the current release?
The current release of CMake is 2.0. This release is available at:
http://www.cmake.org/HTML/Download.html
Nightly development can be accessed through CVS.
See http://www.cmake.org/HTML/Download.html for more information.
CMake roadmap and release schedule
CMake 2.0 is out and CMake 2.2 will probably happen in late 2004 or early 2005. Depending on funding and time there may be support for FORTRAN, native Java, and cross-compiling. The bug tracker at www.cmake.org/Bug also has a number of feature requests for CMake. These feature requests typically et rolled into future versions of CMake.
Edit this entry / Log info / Last changed on Wed Jun 9 08:41:44 2004 by Andy
I found a Bug! What should I do?
Please report the bug in our bug tracker: http://www.cmake.org/Bug .
Please make sure to look at the old bugs not to include duplicates, include detailed instructions of the bug and how to reproduce it.
I want a new feature in CMake. What should I do?
Report a feature request in our Bug tracker http://www.cmake.org/Bug .
Please make sure to look at the old feature requests not to include duplicates, include detailed instructions of the feature and proposed implementation.
Using CMake
Writing correct CMakeList files
CMake by default maintains quite a bit of backwards compatibility to support older projects that used earlier versions of CMake (mainly versions before 1.4, in 1.4 we made the syntax more strict and cleaned up quite a bit). This backwards compatibility comes at the expense of allowing CMakeList files that really are not written correctly. So, if you want to write your CMakeList files correctly you should really specify:
CMAKE_MINIMUM_REQUIRED(VERSION 1.4)
at the top of your main CMakeLists.txt file. That will modify how CMake processes your CMakeList files to be more strict and to complain if you use any deprecated commands. For example in old versions of CMake
IF (foo) ENDIF(bar)
was legal (stupid but legal) With CMAKE_MINIMUM_REQUIRED(VERSION 1.4) this will be flagged as an error.
How do I get the current source or binary directory?
Is there any way to get the "current working directory" in a CMake variable?
You can use the following:
CMAKE_CURRENT_SOURCE_DIR: points to your current source directory CMAKE_CURRENT_BINARY_DIR: points to the equivalent binary directory
Running CMake
Is there an option to produce more 'verbose' compiling?
Set CMAKE_VERBOSE_MAKEFILE to ON. This will make generator to produce all outputs, including compiler lines.
If you are on Windows using Borland or NMake Makefiles, then you will see lines like:
cl @c:\DOCUME~1\ANDY~1.KIT\LOCALS~1\Temp\nma03504
The reason for this is that Borland and Microsoft Visual Studio make programs have limitation on the length of command string. They overcome this limitation by writing arguments to the file and then pass file to the program.
If you actually want to see what the command looks like, set CMAKE_START_TEMP_FILE and CMAKE_END_TEMP_FILE to "".
On Makefile generators, there is a shortcut by setting Makefile variable VERBOSE to 1. For example on UNIX:
make VERBOSE=1
I set a cmake variable in my environment, but it didn't change anything. Why?
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.
Platform-specific questions
How can I apply resources on Mac OSX automatically?
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 custom rule which is executed after the executable is linked:
ADD_EXECUTABLE(MyExecutable ${MyExecutable_SRCS}) SET(MyExecutable_PATH ${EXECUTABLE_OUTPUT_PATH}) IF(NOT MyExecutable_PATH) SET(MyExecutable_PATH ${CMAKE_CURRENT_BINARY_DIR}) ENDIF(NOT MyExecutable_PATH)
IF(APPLE) FIND_PROGRAM(VTK_APPLE_RESOURCE Rez /Developer/Tools) IF(VTK_APPLE_RESOURCE) ADD_CUSTOM_COMMAND(SOURCE MyExecutable COMMAND ${VTK_APPLE_RESOURCE} ARGS Carbon.r -o ${MyExecutable_PATH}/MyExecutable TARGET MyExecutable) ENDIF(VTK_APPLE_RESOURCE) ENDIF(APPLE)
This will execute:
/Developer/Tools/Rez Carbon.r -o /binary/path/MyExecutable
after MyExecutable is linked.
Why does FIND_LIBRARY not find .DLL libraries under WIN32?
For those who come from a Unix background to MS Windows:
You never link directly to the .dll, you have to link against the import library .lib for the .dll.
Linking against dynamic libraries (.dll under Windows) is quite different from linking against shared objects (.so) under Linux.
In Windows, there are two types of library, a static library and an import library (both called .lib). In Windows, building A.dll will also build the import library A.lib (which is not the static library).
Conclusion: There is no need to find a .dll for linking.
Some more details can be found here: http://cphoenix.best.vwh.net/winvunix.html
Why am I getting a linker error to _mainCRTStartup under WIN32?
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.
ADD_EXECUTABLE(exename [WIN32] source1 source2 ... sourceN)
... The second argument to this command can be WIN32 which indicates that the executable (when compiled on windows) is a windows app (using WinMain) not a console app (using main)....
How to use MFC with CMake
To use MFC, the CMAKE_MFC_FLAG variable must be set to 6.
This can be set in a CMakeLists.txt file and will enable MFC in the application. It should be set to 6. This is used in visual studio 6 and 7 project files. The CMakeSetup dialog uses MFC and the CMakeLists.txt looks like this:
ADD_DEFINITIONS(-D_AFXDLL) SET(CMAKE_MFC_FLAG 6) ADD_EXECUTABLE(CMakeSetup WIN32 ${SRCS})
Miscellaneous questions
How do I use CMake to build LaTeX documents?
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.
PROJECT(Document) IF(LATEX_COMPILE) ADD_CUSTOM_COMMAND( OUTPUT ${Document_BINARY_DIR}/TDocument.dvi DEPENDS ${Document_BINARY_DIR}/TDocument.tex COMMAND ${LATEX_COMPILE} ARGS ${Document_SOURCE_DIR}/TDocument.tex ) ENDIF(LATEX_COMPILE) IF(DVIPDF_COMPILE) ADD_CUSTOM_COMMAND( OUTPUT ${Document_BINARY_DIR}/TDocument.pdf DEPENDS ${Document_BINARY_DIR}/TDocument.dvi COMMAND ${DVIPDF_COMPILE} ARGS ${Document_SOURCE_DIR}/TDocument.dvi ) ENDIF(DVIPDF_COMPILE)
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo DEPENDS ${Document_BINARY_DIR}/TDocument.pdf )
How do I rename library after it is created?
Let say you do are creating library named Foo to the new name Bar. Foo is created with command: ADD_LIBRARY(Foo SHARED ${Foo_sources})
The following will rename the library after it is created (requires CMake 1.8 or later):
# Set the existing library name: SET(LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}Foo${CMAKE_SHARED_LIBRARY_SUFFIX}) # Set new library name: SET(NEW_LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}Bar${CMAKE_SHARED_LIBRARY_SUFFIX}) # Copy: ADD_CUSTOM_COMMAND( TARGET Foo POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy ${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${LIB_NAME} ${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${NEW_LIB_NAME} )
In CCMake, typing full paths is tedious. Is there a better way?
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.
For example:
/usr/loc<TAB>
will expand to
/usr/local/
Which regular expressions are supported by cmake?
The MATCHES and MATCHALL uses a regular expression, not a wild card. Here are the meanings of the metacharacters in the cmake regular expression:
^ Matches at beginning of a line $ Matches at end of a line . Matches any single character [ ] Matches any character(s) inside the brackets [^ ] Matches any character(s) not inside the brackets - Matches any character in range on either side of a dash * Matches preceding pattern zero or more times + Matches preceding pattern one or more times ? Matches preceding pattern zero or once only () Saves a matched expression and uses it in a later match
example: "[-][L]([^ ;])+"
matches all strings beginning with -L and ending with a space or a semicolon, the usual linkdirs under Linux.
Why does CMake use full paths, or can I copy my build tree?
CMake uses full paths because:
- configured header files may have full paths in them, and moving those files without re-configuring would cause upredicatble behavior.
- because cmake supports out of source builds, if custom commands used relative paths to the source tree, the would not work when they are run in the build tree because the current directory would be incorrect.
- on Unix systems rpaths are 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.
Can the build tree be copied:
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. However, cmake is not run every time a build is done. Currently (cmake 1.6.X, and cmake 1.7.x ) do not support fixing a moved binary tree. This feature may be added before 1.8. If that feature were added, it would still require cmake to be re-run by hand each time a build tree is moved.
CMake does not generate a "make distclean" target. Why?
CMake generates many files related to the build system, but since CMakeLists.txt files can run scripts and other arbitrary commands, there is no way it can keep track of 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. There is a "make clean" target that will remove files generated by the compiler and linker.
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.
Since the source tree is never changed, no distclean target is needed. A fresh build can be achieved by removing the build tree or creating a separate build tree.
Does CMake's "make install" support DESTDIR?
Yes, when a makefile generator is used. After the build completes, one may run "make install" to install any files the project configured to be installed. Running
make install DESTDIR="/home/me/mydist"
will cause the installation to copy files to "/home/me/mydist/PREFIX/...". This is useful for package maintainers.
Running "make clean" does not remove custom command outputs. Why?
Since CMake 2.0 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.
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. Please see question 5.6 for more details.