On 11/13/2011 11:30 PM, Eric Noulard wrote: > 2011/11/13 Robert Dailey <rcdai...@gmail.com>: >> I understand that currently Makefiles generated by CMake are >> single-configuration by-design. In other words, you can't issue a "debug" or >> "release" command to make, you have to regenerate for a different >> configuration. > > For this purpose you can use 2 build trees that use the same source tree > > cd /path/to/source > mkdir dbuild > cd dbuild > cmake -DCMAKE_BUILD_TYPE=Debug .. > cd .. > mkdir rbuild > cd rbuild > cmake -DCMAKE_BUILD_TYPE=Release .. > > now to build debug > cd dbuild; make > > and to build release > cd rbuild; make > >> Can someone explain the reason for this design? > > Don't know in the past I used makefile that can deal with multiple config, > everytime it was a "re-entrant" makefile scheme. May be this should be > avoided in order to produce 'portable' makefiles? > >> Are there any plans to change it? > > Don't know. > But may be it would be nice to have a way to create > "several build trees" at one time for that and produce a unifying > top level makefile that drive them all.
One can nearly achieve this by now; see the following example: # CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(MULTICONFIG C) SET(CMAKE_VERBOSE_MAKEFILE ON) # --> IF(CMAKE_CONFIGURATION_TYPES) ADD_CUSTOM_TARGET(configs) ADD_CUSTOM_TARGET(builds) FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES) FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${i}) ADD_CUSTOM_TARGET(config-${i} COMMAND ${CMAKE_COMMAND} ${PROJECT_SOURCE_DIR} -DCMAKE_BUILD_TYPE=${i} -DCACHE_DIR=${PROJECT_BINARY_DIR} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${i}) ADD_DEPENDENCIES(configs config-${i}) ADD_CUSTOM_TARGET(build-${i} COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/${i}) ADD_DEPENDENCIES(builds build-${i}) ENDFOREACH() FOREACH(i IN LISTS FORWARD) ADD_CUSTOM_TARGET(${i} COMMAND ${CMAKE_COMMAND} --build \${CONFIG} --target ${i}) ENDFOREACH() ADD_CUSTOM_TARGET(world ALL COMMAND ${CMAKE_COMMAND} --build \${CONFIG}) RETURN() ENDIF() IF(DEFINED CACHE_DIR) LOAD_CACHE(${CACHE_DIR} EXCLUDE CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES) ENDIF() # <-- ADD_EXECUTABLE(main main.c) SET_TARGET_PROPERTIES(main PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG COMPILE_DEFINITIONS_RELEASE RELEASE) /* main.c: */ int main(void){return 0;} The part to add in order to enable multiple build trees is between "-->" and "<--". The basic idea is: If CMAKE_CONFIGURATION_TYPES is defined, create a build tree for each entry along with a custom target which configures that tree with the correct CMAKE_BUILD_TYPE. Also, add a custom target which builds that tree via "cmake --build". These build trees' configurations must be a separate step - therefore, driven by a custom target - because the top-level configuration has to be finished to enable the several build trees to load the cache via LOAD_CACHE(); otherwise, the initial -D settings would not be forwarded. For these reasons, we need the CACHE_DIR variable, and the RETURN() statement disables the actual part of the CMakeLists.txt file in the top-level configuration. Obviously, CMAKE_BUILD_TYPE/CMAKE_CONFIGURATION_TYPES must not be loaded from the cache to the build trees. A downside is that you must implement your own, say, "target forwarding" if you want to be able to say "main <TARGET> CONFIG=debug"; the FORWARD variable with a list of targets to be forwarded is used for this purpose. To see the project in action, go to an empty top-level build directory and issue, e.g.: cmake <srcdir> \ -DCMAKE_CONFIGURATION_TYPES="debug;release;custom" \ -DCMAKE_C_FLAGS_CUSTOM="-DCUSTOM" \ -DFORWARD="main" This will create the subdirectories {debug,release,custom}; now make configs to configure the different build trees and load the cache from the top-level configuration. Subsequently, you can say "make builds" to build all configurations, or "cmake --build <config>" to build only one, or "make main CONFIG=<CONFIG>" or even "make CONFIG=<CONFIG>". Anyway, although the addition to mimic the behavior of a real multi- configuration generator to the Makefiles ones is no big deal, I'm in doubt if it's worth the effort. Personally, I'm fine with the Makefiles generators' single-configuration limitation. Regards, Michael >> I'm new to Makefiles so I'm curious to learn as much as possible >> about it. > > If you are new to makefile may be you can have a look at > the chapter 4 of this book > http://www.informit.com/store/product.aspx?isbn=0130091154 > > it is about GNU make but it contains valuable introduction to "makefile" > and the book may downloaded: > http://ptgmedia.pearsoncmg.com/images/0130091154/downloads/0130091154.zip -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake