원본 : http://www.vtk.org/Wiki/CMake_FAQ

조금씩 번역해 나가고 있습니다. 저는 무척 영어를 못하므로 원문을 직접 보시길 권합니다.
대충 의역한 부분이 많으니 혹 번역이 틀린 부분은 댓글 부탁드립니다.

General information and availability

CMake란 무엇인가?

CMake는 크로스 플랫폼을 지원하는 오픈소스 빌드(make) 시스템이다. CMake는 플랫폼, 컴파일러에 대한 의존도가 낮은 간단한 설정 파일을 이용해 소프트웨어의 컴파일 과정을 돕는다. CMake는 당신의 개발환경에서 사용할 수 있는 makefile과 환경을 생성해준다. CMake는 매우 정교하다: 시스템 설정, preprocessor 생성, 코드 생성, 템플릿 생성이 필요한 복잡한 환경을 지원하는 것도 가능하다.  http://www.cmake.org/HTML/About.html 에서 CMake를 사용하는 법을 배울수 있다.

최신 버전.

CMake의 최신 버전을 다운로드 받을 수 있는 곳: http://www.cmake.org/HTML/Download.html

이곳에서 너는 windows용, 몇가지 리눅스 버전 또는 CMake의 소스코드를 받을 수 있다.

또 Git을 통해 nightly build버전에도 접근할 수 있다.  http://www.cmake.org/HTML/Download.html. 웹페이지를 통해 소스를 브라우징할수도 있다. git repository online (for historical purpose, here is the old frozen cvs repository online).

버그를 찾았다면?

버그를 리포트하는 곳: http://www.cmake.org/Bug

이미 등록된 버그인지 꼭 확인해주기 바란다. 그리고 상세한 설명과 어떻게 그 버그를 재현할수 있는지를 적어주기 바란다.

새로운 기능을 원한다면?

새 Feature를 등록하는 곳 : 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.

"Mastering CMake" 가 소개하는 가장 최신 버전은 ?

A new edition of the Mastering CMake book has been released which documents CMake 2.6.

The following features have been added since printing the book:

  • New INSTALL command (cmake --help-command INSTALL)
  • New LIST command (cmake --help-command LIST)
  • Updated FIND_PATH, FIND_PROGRAM, and FIND_FILE commands to be more powerful (cmake --help-command FIND_PATH)
  • RPATH and Mac OS X install_name support (cmake --help-command SET_TARGET_PROPERTIES)
  • CPack Beta (not finished or documented)
  • EXECUTE_PROCESS was added and replaces EXEC_PROGRAM
  • Other changes have been bug fixes and internal CMake restructuring

Where can I find searchable CMake Mailing Archives?

There exist at least these ones:

 site:http://www.cmake.org/pipermail/cmake/ <search terms>

CMake 실행하기

'verbose' 컴파일의 방법을 제공합니까? (Is there an option to produce more 'verbose' compiling?)

Makefile에서 당신은 VERBOSE 를 1로 설정할 수 있습니다. Unix에서 예를 들면:

make VERBOSE=1

또한 CMAKE_VERBOSE_MAKEFILE 값을 ON으로 설정하실 수도 있습니다.

Windows(nmake)에서 아래 명령으로 CMAKE_VERBOSE_MAKEFILE 를 오버라이드할 수도 있습니다.

nmake /S

Unix상에서 아래 명령을 사용해서 verbose mode를 대부분 override할 수 있습니다.

make VERBOSE=""

If you are on Windows using Borland or NMake Makefiles, 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 strings. 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 ""

컴파일할 때 필요한 라이브러리 검사를 스킵할 수 있는 방법이 있습니까?

Makefile을 사용한다면

Unix, Linux계열에서 Makefile을 사용할 때, 타겟 이름 뒤에 "/fast"를 붙일 수 있습니다. 예를 들어:

make target_name/fast

windows에서는 아래와 같이 합니다.

make target_name\fast

Using Visual Studio >= 7.1

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.

Using Visual Studio <= 7.0

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.

cmake 변수를 설정했으나, 아무것도 변하지 않습니다. 왜인가요?

CMake 빌드 설정은 빌드 트리 내의 CMake cache에 저장됩니다. 그들은 CMake "cache entries"라고 불리며 당신의 command shell 환경 변수와 아무런 상관이 없습니다. CMake GUI(Windows에서는 CMakeSetup, Unix에서는 ccmake)를 사용하시거나 wizard mode(cmake -i)로 cache entries를 고치세요. 초기 값은 새 빌드 트리를 생성할 때 cmake 명령의 인자로 -D를 줘서 설정할 수도 있습니다.

다른 컴파일러를 사용하는 방법은?

Method 1: 환경 변수를 사용하는 방법

For C and C++, set the CC and CXX environment variables. This method is not guaranteed to work for all generators. (Specifically, if you are trying to set Xcode's GCC_VERSION, this method confuses Xcode.)

For example:

CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source

Method 2: cmake -D를 사용하는 방법

Set the appropriate CMAKE_FOO_COMPILER variable(s) to a valid compiler name or full path on the command-line using cmake -D.

For example:

cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source

Method 3 (추천하지 않음): set()을 사용하는 법

Set the appropriate CMAKE_FOO_COMPILER variable(s) to a valid compiler name or full path in a list file using set(). This must be done before any language is set (ie before any project() or enable_language() command).

For example:

set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")


CMAKE_C_COMPILER를 GUI를 통해 변경했지만 다음 configure 단계에서 되돌아갑니다.

일단 빌드 트리가 생성되고 나면 컴파일러는 변경할 수 없습니다. (많은 구현상의 이슈들이 있습니다.)

In CCMake, full paths 를 쓰는 것은 지루합니다.(tedious). 더 나은 방법이 있나요?

CMake 1.6 부터, CCMake는 Tab을 이용한 자동 완성 기능을 제공합니다. 처음 약간만 입력하고 TAB을 누르십시오. 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:


will expand to


Out-of-source build trees

 "out-of-source" build란 무엇입니까?

빌드를 통해 생성되는 파일들은 어딘가에 저장될 것입니다. in-source 빌드란 그들을 소스 트리안에 두는 것을 말합니다. out-of-source 빌드는 그들은 완전히 다른 곳에 놓기 때문에 소스트리 내부에는 아무런 변화가 없을 것입니다.

예를 들어 아래는 in-place 빌드를 수행했습니다. 바이너리는 소스코드와 같은 디렉토리에 생성됩니다.

 cd Hello
 ccmake .

다음 예제에서는 out-of-place 빌드가 수행되었습니다. 따라서 소스코드, 라이브러리들, 실행파일들은 다른 디렉토리에 생성될 것입니다.

 mkdir HelloBuild
 cd HelloBuild
 ccmake ../Hello

우리는 Out-of-source 빌드를 추천합니다. 당신은 하나의 소스트리를 다양한 옵션으로 빌드하여 가지고 있을 수 있습니다. 예를 들어 HelloBuildDebug, HelloBuildRelease를 함께 유지할 수 있습니다.

Note: Before performing an out-of-source build, ensure that all CMake generated in-source build information is removed from the source directory, e.g., CMakeFiles directory, CMakeCache.txt.

out-of-source 빌드를 시도했지만 in-source 빌드되는 것 같습니다. 

소스트리 안에 CMakeCache.txt가 있는지 확인해보십시오. CMake가 CMakeCache.txt 파일이 있는 디렉토리에서 실행되면 CMake는 그 디렉토리가 Build 디렉토리라고 가정합니다. "cmake ../mysrc" 와 같이 실행한 적이 있으면 mysrc 폴더에는 CMakeCache.txt 파일이 생길것이고, 그 디렉토리를 빌드 디렉토리로 간주합니다.

빌드 트리를 다시 만들기 위해 "cmake ."을 수행하는데 대한 부작용입니다. 어쨌든 in-source와 out-of-source가 섞이는 것은 좋지 않기 때문에 고쳐지지 않을 것입니다.

CMake는 full paths를 사용하지 않나요? 빌드트리를 복사할 수 있나요?

CMake는 아래와 같은 이유로 전체 경로를 사용합니다:

  1. configured header files may have full paths in them, and moving those files without re-configuring would cause upredictable behavior.
  2. 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.
  3. 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.

빌드 트리를 복사할 수 있나요?

아니오. 위에서 말한 것처럼 CMake는 full path를 사용합니다. 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.

The workaround is to create a new build tree without copying or moving the old one.

CMake "make distclean" target을 생성하지 않습니다. 왜인가요?

GNU autotools에 생성된 빌드트리들은 "make distclean" target 을 가지고 build 결과물과 Makefile들 그리고 빌드시스템에 의해 생성된 다른 파일들을 지울 수 있습니다. CMake는 "make distclean" target을 생성하지 않습니다. 왜냐하면 CMakeLists.txt 파일들이 스크립트와 독자적인 명령들을 실행할 수 있기 때문입니다. CMake는 CMake를 실행하여 생성된 파일들을 정확히 tracking할 수 없습니다. distclean을 제공하면 마치 그것이 동작하는 것처럼 착각할지도 모릅니다.(make clean은 제공되고 있습니다.)

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.

(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.)

make clean을 해도 custom command의 output이 지워지지 않습니다.

CMake 2.2 또는 그 이상에서 custom command의 output은 make clean에 의해 제거됩니다. 버전을 확인해보시기 바랍니다. 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.

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.

CMakeLists.txt 작성하기

하위 호환성을 갖는 법?

CMake 2.6버전부터 아래 명령어를 통해 하위 호환성을 가질 수 있습니다:

 cmake_minimum_required(VERSION 2.6) # or other version

이것은 CMake의 버전을 확인하여 이 프로젝트가 빌드될 수 있는지를 알려줄 것입니다. 더 자세한 부분은 아래 링크를 참조하세요.

현재 소스 디렉토리와 바이너리 디렉토리를 알아내는 법

CMAKE_CURRENT_SOURCE_DIR 은 소스 디렉토리의 절대 패스를 가르킵니다.
CMAKE_CURRENT_BINARY_DIR 는 바이너리 디렉토리의 절대 패스를 가르킵니다.

Why are my CMake variables not updated in the GUI after a SET command?

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.

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:


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.

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

 cmake --help-command SET

to see full instructions for the command.

How can I change the default build mode and see it reflected in the GUI?

Adapt the following commands in your CMakeLists.txt (this example sets the Release With Debug Information mode):

      "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."

어떻게 실행파일을 만들고 파일을 생성할 수 있나요?

아래와 같이 target을 추가하시면 됩니다.:

 ADD_EXECUTABLE(generate generate.c)

The rest of the process is simpler in CMake 2.6 and above than in previous versions.

사용자 정의의 파일을 만들려면 ADD_CUSTOM_COMMAND를 사용하세요. (In this example we assume generate accepts the input and output files as arguments.)

   OUTPUT someoutput.txt
   COMMAND generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
   DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt

This tells CMake how to build the file but does not actually add a rule to the build system. Another target must require it. One may create a custom target explicitly for this rule:

 ADD_CUSTOM_TARGET(driver ALL DEPENDS someoutput.txt)

or the file may be added as part of some other target:

 ADD_EXECUTABLE(product product.c someoutput.txt)

In CMake 2.4 and below the generate target may not be specified directly in the COMMAND option of add_custom_command (but it can still be used in the DEPENDS option as of CMake 2.4). Instead use GET_TARGET_PROPERTY to obtain the location of the generated executable. Additionally, the output must always be specified by full path.

   DEPENDS generate

How can I generate a source file during the build?

The ADD_CUSTOM_COMMAND command lets you generate a source file that you can then include in another target. For example:

 ADD_EXECUTABLE(foo foo.c)

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.)

You can also use ADD_CUSTOM_COMMAND when the generator command is another executable in the same project.

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:

 # make sure cmake addes the binary directory for the project to the include path
 # add the executable that will do the generation
 ADD_EXECUTABLE(my_generator my_generator.cxx)
 # add the custom command that will generate all three files
   OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp
   DEPENDS my_generator
 # now create an executable using the generated files

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:


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.)

How can I add a dependency to a source file which is generated in a subdirectory?

Rules created with ADD_CUSTOM_COMMAND as above have scope only in the directory in which they are specified. If the generated file is needed in another directory, a target-level dependency needs to be added. Create a target in the subdirectory with the custom rule in order to drive it:

 # subdir/CMakeLists.txt

Now other targets can depend on the target from the subdirectory:

 # CMakeLists.txt
 # Create the executable.
 # Tell CMake the source won't be available until build time.
 # Make sure the source is generated before the executable builds.
 ADD_DEPENDENCIES(generated generate_foo)

I use EXEC_PROGRAM but the result is not set in subdirectories. Why?

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:


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.

How can I get or set environment variables?

CMake names environment variables using an ENV prefix and surrounding the names in curly braces. Here is an example:


Reading variables will work in any version of CMake. Writing to them works in CMake 2.2 and higher using the following syntax:


Note that there is currently no way to tell apart an empty environment variable value from a variable that is not set at all.

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.

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.

Why do I have unwanted semicolons ; in my compiler flags?

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.

How can I get quoting and escapes to work properly?

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.

Isn't the "Expression" in the "ELSE (Expression)" confusing?

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:

   ...do something...
   ...do something else...

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.

As of CMake 2.6.0 the ELSE() and ENDIF() constructs can be empty. The same is true for closing constructs on ENDMACRO(), ENDFUNCTION(), and ENDFOREACH(). If you require 2.4.x compatibility, CMake 2.4.3 or greater recognizes the CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS option (which is superfluous in 2.6.0)

 cmake_minimum_required(VERSION 2.4.3)

   ...do something...
   ...do something else...
   ...do something else...

Which regular expressions are supported by CMake?

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:

^ 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 a pattern on either side of the |
* 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.

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":

 SET(test "hello world ! catch: me if you can")
 STRING(REGEX REPLACE ".*catch: ([^ ]+).*" "\\1" result "${test}" )
 MESSAGE(STATUS "result= ${result}")

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.

 -- result= me

For those of you who know Perl, the equivalent Perl code could be:

 $test = "hello world ! catch: me if you can";
 $result = $test;
 $result =~ s/.*catch: ([^ ]+).*/$1/;
 print "-- result= $result\n";

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.

How to convert a semicolon separated list to a whitespace separated string?

 foreach(arg ${foo})
   set(bar "${bar} ${arg}")
 endforeach(arg ${foo})
 message("foo: ${foo}")
 message("bar: ${bar}")

How can I build multiple modes without switching ?

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.:


Inside you can place as many target directories for out-of-source build modes as you want, e.g.:


In each of these directories issue a command (assuming that you have CMakeLists.txt directly in Project-directory)

cmake -DCMAKE_BUILD_TYPE=type_of_build ../../

to create a cmake cache configured for requested build type.

Now you can make each build just by entering appropriate directory and executing a make command.

How can I specify my own configurations (for generators that allow it) ?

For generators that allow it (like Visual Studio), CMake generates four configurations by default: Debug, Release, MinSizeRel and RelWithDebInfo. Many people just need Debug and Release, or need other configurations. To modify this, you need to change the variable CMAKE_CONFIGURATION_TYPES in the cache:

   set(CMAKE_CONFIGURATION_TYPES Debug Release DebugMX31 ReleaseMX31)
     "Reset the configurations to what we need"

Note that the first line checks whether the generator supports multiple configurations.

If you just want to add your own configurations while keeping the default ones, you can use list operations:

     "Add the configurations that we need"

How can I extend the build modes with a custom made one ?

The following code snipet (taken from a CMakeLists.txt) adds a Maintainer mode:

    "Flags used by the C++ compiler during maintainer builds."
    FORCE )
    "Flags used by the C compiler during maintainer builds."
    FORCE )
    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
    "Flags used for linking binaries during maintainer builds."
    FORCE )
    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
    "Flags used by the shared libraries linker during maintainer builds."
    FORCE )
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs
    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Maintainer."
    FORCE )

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 a CMAKE_BUILD_TYPE previously set in the CMakeLists.txt. A simple "SET(CMAKE_BUILD_TYPE)" does silently overwrite, the change is only visible in the GUI if "CACHE" is set when overriding.

Why does foreach skip empty values?

The code in question is of the form

 set(var "a;b;;c;d") # list 'a', 'b', , 'c', 'd'
 foreach(v ${var})
   # v=a, v=b, v=c, v=d, one at a time

and the loop variable 'v' never attains the empty-string value . This is because the ${var} syntax is an unquoted argument so the CMake language expands the list and removes the empty value. The foreach command does not even see the empty value. One can verify this because the code

 foreach(v a b "" c d)

will see the empty value.

Does CMake support precompiled headers?

Yes and no. Every platform does precompiled headers a bit differently, and there is currently no first-class interface provided by CMake and implemented on every platform. However, CMake does provide enough primitives for projects to use precompiled headers on specific platforms. Our issue tracker has a feature request with attachements providing user-contributed helper macros for some platforms.

Writing FindXXX.cmake files

What are the rules to write a FindXXX.cmake file?

Let's follow the instructions and the advices in the Modules/readme.txt [1] file located in the CVS repository.

Why does find_library look in system directories before its PATHS option?

The code in question is often of the form

 find_library(FOO_LIBRARY NAMES foo PATHS /opt/foo/lib)

CMake will find "/usr/lib/libfoo.so" instead of "/opt/foo/lib/libfoo.so" if both exist. The reason is that /opt/foo/lib is a hard-coded guess of the location. The documentation of find_library specifies the search order. User, project, and system configuration variables are always more local than hard-coded guesses and should override them, so the PATHS option is used last.

Some find-modules compute probable locations based on other information available from the system such as a project-specific environment variable. The HINTS option (CMake 2.6 and higher) takes precedence over system directories specifically for this case:


CMake will find "$ENV{FOO_LIB_DIR}/libfoo.so" before "/usr/lib/libfoo.so".

Finding and using external packages

How do I use CMake to generate SWIG wrapper libraries?

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.

# This example shows how to use python
# Currently these languages have been tested:
#  perl tcl ruby php4 pike





SWIG_ADD_MODULE(example python
  example.i example.cxx)

# This example shows how to use tcl
SET (	MODULE_NAME		project	)
SET (	SRC_FILES		Vertex.h Vertex.cxx Shapes.h Shapes.cxx )


# Look for TCL

FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80
				PATHS /usr/lib /usr/local/lib)




If you get errors indicating that C and C++ include files cannot be found, like,

Error: Unable to find 'string.h'
Error: Unable to find 'time.h'
Error: Unable to find 'string'
Error: Unable to find 'functional'
Error: Unable to find 'utility'
Error: Unable to find 'limits.h'
Error: Unable to find 'fstream'
Error: Unable to find 'sys/times.h'
Error: Unable to find 'unistd.h'
Error: Unable to find 'malloc.h'

try setting the -includeall property on fewer source files:

# Try doing this on fewer files

In particular, you may need -includeall only on the top-level .i files.

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.

    OUTPUT    ${Document_BINARY_DIR}/TDocument.dvi
    DEPENDS   ${Document_BINARY_DIR}/TDocument.tex
    ARGS      ${Document_SOURCE_DIR}/TDocument.tex 

    OUTPUT    ${Document_BINARY_DIR}/TDocument.pdf
    DEPENDS   ${Document_BINARY_DIR}/TDocument.dvi 
    ARGS      ${Document_SOURCE_DIR}/TDocument.dvi
  DEPENDS ${Document_BINARY_DIR}/TDocument.pdf

The following uses commands in CMake version 2.0 and later

# Find LaTeX
    OUTPUT    ${Document_BINARY_DIR}/TDocument.dvi
    ARGS      ${Document_SOURCE_DIR}/TDocument.tex
    DEPENDS   ${Document_SOURCE_DIR}/TDocument.tex
    COMMENT   "Tex2dvi"
      OUTPUT    ${Document_BINARY_DIR}/TDocument.ps
      ARGS      ${Document_BINARY_DIR}/TDocument.dvi
                -o ${Document_BINARY_DIR}/TDocument.ps
      DEPENDS   ${Document_BINARY_DIR}/TDocument.dvi
      COMMENT   "dvi2ps"

      OUTPUT    ${Document_BINARY_DIR}/TDocument.pdf
      ARGS      ${Document_BINARY_DIR}/TDocument.ps
      DEPENDS   ${Document_BINARY_DIR}/TDocument.ps
      COMMENT   "ps2pdf"
    ADD_CUSTOM_TARGET(LaTeXDocument ALL echo
      DEPENDS   ${Document_BINARY_DIR}/TDocument.pdf

How do I get LaTeX references to be correct?

When your latex document contains references (e.g. \ref{...} command) you get to run two passes of latex. In the most general case, i.e. when additionally your document uses a bibtex bibliography, you shall need three passes of latex (and one pass of bibtex):

  1. latex (first pass: for bibtex to have an .aux file)
  2. bibtex (for generating the .bbl file)
  3. latex (second pass)
  4. latex (third pass)

The following code snippet illustrates how you can "pervert" the bibtex and latex generated auxilary files (.aux, .log, .dvi, .bbl...) to create an "artificial" set of CMake dependencies. The side-effect of those dependencies should hopefully be the above described sequence of calls to latex and bibtex

  ARGS      -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
  COMMENT   "Latex (first pass)"

  ARGS      -terse ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
  COMMENT   "Bibtex"

  ARGS      -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
  COMMENT   "Latex (second pass)"

  ARGS      -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
  COMMENT   "Latex (third pass)"
# Eventually trigger the whole process

How can I set TEXINPUTS for a LaTeX compilation?

First note that most often you can avoid using TEXINPUTS by copying all the necessary files (.tex source file and included graphic files e.g. .eps files) from your PROJECT_SOURCE_DIR hirarchy to your PROJECT_BINARY_DIR subdir [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 concerned PROJECT_BINARY_DIR subdir now contains files that are NOT generated by CMake (in the sense that those files are not the result of a system command but were merely duplicated)...

If you consider it is cleaner or easier to define a TEXINPUTS environment variable [the latex command probably misses a -I flag] you can find an example in the InsightDocuments cvs archive (refer to the section "cvs access" near the bottom of Kitware's ITK download page) or use google with keywords "ITK_TEXINPUTS CONFIGURE_FILE". Look at InsightDocuments/CourseWare/Training/Vis2003/Latex/CMakeLists.txt and search for e.g. "LaTeXWrapper.sh.in".

Roughly the mechanism goes:

  • SET ITK_TEXINPUTS with the desired TEXINPUTS
  • 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
  • use ADD_CUSTOM_COMMAND to invoke this shell script

This very example is Win32 portable (except that LaTeXWrapper.bat.in generates a .bat shell script)

Library questions

Can I build both shared and static libraries with one ADD_LIBRARY command?

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.

Does that mean I have to build all my library objects twice, once for shared and once for static?! I don't like that!

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...

...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.

   TARGET_LINK_LIBRARIES(zzDYNAMIC -Wl,-whole-archive zzSTATIC -Wl,-no-whole-archive)

...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 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.

How do I make my shared and static libraries have the same root name, but different suffixes?

Set the OUTPUT_NAME of your shared and static libraries to the same thing.

 ADD_LIBRARY(foo SHARED ${foo_sources})
 ADD_LIBRARY(foo-static STATIC ${foo_sources})
 # The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it.
 # The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it.
 # Now the library target "foo-static" will be named "foo.lib" with MS tools.
 # This conflicts with the "foo.lib" import library corresponding to "foo.dll",
 # so we add a "lib" prefix (which is default on other platforms anyway):

One more detail is needed with CMake 2.6.x and lower (but not CMake 2.8 or higher). If you are building your shared and static libraries in the same directory, you will also need the following to keep your shared and static libraries from clobbering each other during the build.

 # Help CMake 2.6.x and lower (not necessary for 2.8 and above, but doesn't hurt):

How do I rename a library after it has already been built?

You don't rename it. It's been built! Its name is whatever CMakeLists.txt says it's supposed to be.

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:

 SET(NEW_LIB_NAME ${Bar_prefix}Bar${Bar_suffix})

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.

Does CMake support "convenience" libraries?

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.

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.

Why are libraries linked to my shared library included when something links to it?

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.

Something like the following will work in CMake 2.6:


CMake dependency scanner

CMake does not preprocess source files while scanning dependencies. Code like

 #if 0
 # include "bla.h"

will result in a dependency on "bla.h". This sometimes leads to source files recompiling unnecessarily but will not break the build.

Installation questions

Does CMake's "make install" support DESTDIR?

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.

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):

(1) make install DESTDIR="/some/absolute/path"
(2) make DESTDIR="/some/absolute/path" install
(3) DESTDIR="/some/absolute/path" make install
(4) export DESTDIR="/some/absolute/path
    make install

Can I do "make uninstall" with CMake?

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.

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:

if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
    message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")

file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
list(REVERSE files)
foreach (file ${files})
    message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
    if (EXISTS "$ENV{DESTDIR}${file}")
            COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
            OUTPUT_VARIABLE rm_out
            RESULT_VARIABLE rm_retval
        if(NOT ${rm_retval} EQUAL 0)
            message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
        endif (NOT ${rm_retval} EQUAL 0)
    else (EXISTS "$ENV{DESTDIR}${file}")
        message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
    endif (EXISTS "$ENV{DESTDIR}${file}")

Then in the top-level CMakeLists.txt add the following logic:

# uninstall target

    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

Now you will have an "uninstall" target at the top-level directory of your build tree.

Instead of creating an "uninstall" target, Unix users could enter this command in the shell:

 xargs rm < install_manifest.txt

Distribution questions

Where is "make dist"?

CMake doesn't create a "make dist" target.

What is the best way to distribute source code or binaries for a cmake-based project?

For creating source or binary packages there is now CPack coming with CMake, see the documentation.

Of course you can also use any other ways to create packages.

Platform-specific questions

How do I build universal binaries on Mac OS X?

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:


If you wish to build both as 32 and 64 bit, do this:


You can also set the same named CMake cache variable on an existing binary tree. This works with both makefiles and the Xcode generator.

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.

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.

Lastly, note that CTest is only able to test one architecture. See bug 6157.

How can I apply resources on Mac OS X 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 a custom rule which is executed after the executable is linked:

 ADD_EXECUTABLE(MyExecutable ${MyExecutable_SRCS})

                        COMMAND ${APPLE_RESOURCE} Carbon.r -o ${MyExecutable_PATH})

This will execute:

/Developer/Tools/Rez Carbon.r -o /binary/path/MyExecutable

after MyExecutable is linked.

'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.

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 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.

Conclusion: There is no need to find a .dll for linking. You only need to find the .lib import library.

Some more details can be found here: [2].

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 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.

Why do I get this error: nafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv

This is because the application is using both the static and dll versions of the MFC library. To fix the problem, you can do the following:

SET(CMAKE_MFC_FLAG 2)     # force the IDE to use static MFC
ADD_DEFINITIONS(-D_AFXDLL) # make sure if afx.h is included the dll MFC is used

How to use MFC with CMake

To use MFC, the CMAKE_MFC_FLAG variable must be set as follows:

0: Use Standard Windows Libraries
1: Use MFC in a Static Library
2: Use MFC in a Shared DLL 

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:


Note that visual studio 9 project files do not appear to work with CMAKE_MFC_FLAG 1; this may be related to bug 7056.

In order to use MFC with UNICODE, you must also specify the entry point wWinMainCRTStartup. For example:

set_target_properties(MyApp PROPERTIES
    LINK_FLAGS "/ENTRY:\"wWinMainCRTStartup\"")

See this article as to why _BIND_TO_CURRENT_CRT_VERSION and _BIND_TO_CURRENT_MFC_VERSION are necessary for Visual Studio 2008 SP1.

How To Put Files in Folders in Visual Studio Projects

The Visual Studio IDE supports putting files into folders. CMake can be used to put files in folders with the SOURCE_GROUP command.

 SOURCE_GROUP(name [REGULAR_EXPRESSION regex] [FILES src1 src2 ...])

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.

 For example:
 SOURCE_GROUP(FooFiles FILES foo.cxx)
 SOURCE_GROUP(BarFiles FILES bar.cxx)
 ADD_LIBRARY(foo foo.cxx bar.cxx)

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).

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.

How to create Visual Studio 6 Projects that contain only a single build type

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:

  1. Create a directory in which you copy the files *.dsptemplate and CMakeVisualStudio6Configurations.cmake from CMake's Templates directory.
  2. Edit the .cmake file and change the SET(CMAKE_CONFIGURATION_TYPES ...) line to set the build types that you want in your set.
  3. Edit the *Header.dsptemplate files to contain only the configuration types you want in your set.
  4. In your CMakeLists.txt file, set the MSPROJECT_TEMPLATE_DIRECTORY to the directory that you created.

That's it. Run CMake and your new configuration files will be created.

Note: Editing the *Header.dsptemplates files should be done very carefully. Here are some guidelines:

- 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"') - 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. - 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.

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:

  1. PROP BASE Output_Dir ""
  2. PROP BASE Intermediate_Dir ""
  3. PROP Intermediate_Dir ""



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).

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.

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.)

Can CMake set the Debugging/Working Directory property in Visual Studio projects?

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.

Why does CMakeSetup with the message "LINK : fatal error LNK1104: cannot open file 'user32.lib'" while configuring a project?

The path to the SDK libs (user32.lib) must be added by the IDE when the project generator "Visual Studio 8 2005" is used, because cmake uses VCExpress.exe and on the fly generated project files to check for compiling (VCExpress.exe reads some config files for the compiler/linker options)

So add the sdk lib path (...\Microsoft Platform SDK\Lib) at Tools->Options->Projects and Solutions->VC++ Directories->Library files

See also:

How can I avoid the error "Arg list too long" when running make?

This error is sometimes encountered when building a static library with many object files using Unix make command. It typically looks something like this:

gmake[2]: execvp: /bin/sh: Arg list too long

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 ARG_MAX to extend the length of the command line it will allow.

The error can also happen when linking shared libraries, and can be solved by upping the sysconf parameter MAX_ARG.

On AIX this can be done with the command:

chdev -l sys0 -a ncargs='30'

How can I find out platforms definitions, search paths, etc. from gcc ?

The following is really the best if not only way to get information about predefined macros with a GNU compiler:

$ touch empty.c
$ gcc -v -dD -E empty.c 

This will give you all you might want to know about the preprocessor, the builtin include search dirs and all predefined definitions, so you can check whether it's __LINUX or _LINUX_ or _APPLE_ or __APPLE etc. The empty file and all these parameters are really required. You probably want to pipe the output (both stdout and stderr) to a file. If you want the information for C++, use a C++ file suffix for the empty file.

This is how you can get the builtin library search paths:

$ gcc --print-search-dirs

How can I get a windows registry key ?

The only thing to know is that you can't use just the "SET" command in place of "GET" command. CMake read the value from the registry only when you "get" it from the cache. For instance :


If a key name (ex: Install_Dir in this case) was not specified , the Default key value will be get. Now you could use the SDK_ROOT_PATH to add include and lib path to your project :



You can also read a registry key in the PATHS section of a FIND_LIBRARY, FIND_PATH, FIND_PROGRAM, or FIND_FILE command


For other examples have a look in the CMake Modules folder :

- FindJava.cmake
- FindPythonLibs.cmake
- ..

How can I build my MSVC application with a static runtime?

Here are three options you could employ to compile your MSVC application with /MT instead of /MD.

Manual Replace

You can rely on the user to manually modify CMAKE_C_FLAGS_DEBUG, CMAKE_C_FLAGS_RELEASE, CMAKE_CXX_FLAGS_DEBUG, CMAKE_CXX_FLAGS_RELEASE, etc. within the cache editor. After an initial configure of your software they would have to replace /MD entries with /MT.

Make Override Files

If you intend to build the entire source tree using /MT and you don't need this ever to be configurable via the CMake GUI, the best approach is to create an override file which initializes the starting cache values for the compile flags.

First create a c_flag_overrides.cmake & cxx_flag_overrides.cmake file which contain something like this... (or whatever flags you wish to use per compiler).

        set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
        set(CMAKE_C_FLAGS_RELEASE_INIT        "/MT /O2 /Ob2 /D NDEBUG")
        set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
        set(CMAKE_CXX_FLAGS_RELEASE_INIT        "/MT /O2 /Ob2 /D NDEBUG")

NOTE: These files are only evaluated on the first run of CMake so they can't be dependent on a CMake option() meant to be toggled from the GUI, for example. They could be dependent on a command line -D option or an environment variable if desired.

Then enable them by setting the following variables prior to the project() command.


Dynamic Replace

Alternatively, if you need dynamic control of /MT via some configure option you could use the following technique. Note: CMAKE_CXX_FLAGS_<FOO> is a directory level option, however. Also, this option has the downside of leaving /MD visible in the cache editor although it has no effect.

   if(${flag_var} MATCHES "/MD")
      string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
   endif(${flag_var} MATCHES "/MD")

'Open Source > cmake' 카테고리의 다른 글

CMake build with ninja  (0) 2012.09.25
[번역] CMake FAQ  (0) 2011.08.18
[CMAKE] File 다루기  (0) 2011.05.30
[cmake] 2. Hello with two files.  (0) 2011.04.12
[cmake] 목차  (0) 2011.04.12
[cmake] 2. Hello  (0) 2011.04.12
Posted by 소혼
TAG , ,

티스토리 툴바