[CMake] Re-executing CMake from the Makefile.

Brad King brad.king at kitware.com
Fri Aug 15 15:20:36 EDT 2008


Óscar Fuentes wrote:
> thinking on a two-phase build, something like this:
> 
> $ cmake -G "Unix Makefiles" # as llvm-config is not available, the
> executables are ignored.
> 
> $ make # this builds the libs and llvm-config and stops.
> 
> $ make # This implicitly invokes cmake, which now can use llvm-config for
> determining dependencies and build the executables.
> 
> It would be a good thing if the second `make' were not necessary.

You can do this in one build by splitting it into two projects in terms
of CMakeLists.txt file layout.  The first project would build all the
static libs, determine dependencies, and then drive the second project
build automatically.

The outer project would do something like this:

------------------------------------------------------
# CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(LLVM)

# Rule to create llvm-config script itself.
add_custom_command(
  OUTPUT ${LLVM_BINARY_DIR}/.../llvm-config
  COMMAND ...command to generate it from all libs...
  DEPENDS ${LLVM_SOURCE_DIR}/.../llvm-config.in
          ...dependency on some file touched when libraires change,
             such as CMakeCache.txt or something...
  )

# Target to drive generation of the config script.
add_custom_target(llvm_config ALL
  DEPENDS ${LLVM_BINARY_DIR}/.../llvm-config)

add_subdirectory(Component1)
add_subdirectory(Component2)
...

# Rules to drive subproject build.
add_custom_command(
  OUTPUT Tools
  COMMAND ${CMAKE_CTEST_COMMAND}
  --build-and-test ${LLVM_SOURCE_DIR}/tools ${LLVM_BINARY_DIR}/tools
  ...
  # see [1] for all options
  ...
  --build-options
     -DLLVM_CONFIG_SCRIPT:STRING=${LLVM_BINARY_DIR}/.../llvm-config
  )
add_custom_target(build_tools ALL DEPENDS Tools)

# Make sure llvm-config is ready first.
add_dependencies(build_tools llvm_config)
------------------------------------------------------
# Component1/CMakeLists.txt
add_library(component1 STATIC ...)

# Make sure this library is built before generating config script.
add_dependencies(llvm_config component1)
------------------------------------------------------
# Component2/CMakeLists.txt
add_library(component2 STATIC ...)

# Make sure this library is built before generating config script.
add_dependencies(llvm_config component2)
------------------------------------------------------

Then the inner project would look like this:

------------------------------------------------------
# tools/CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(LLVMTools)
... use ${LLVM_CONFIG_SCRIPT} to get dependencies...
------------------------------------------------------

Using CMake's target export/import features can tie the projects
together so that the dependency computation in llvm-config need only to
specify target names and not the full library names.

http://www.cmake.org/Wiki/CMake_2.6_Notes#Exporting_and_Importing_Targets

This will take a bit of work to set up at first, but should be pretty
solid.  Users would even be able to load the tools project separately to
 build it without re-building any archives if they want.  I can provide
more help if you need it.

-Brad

[1] Sample project that drives a subdirectory as its own project
http://www.cmake.org/cgi-bin/viewcvs.cgi/Tests/ExportImport/CMakeLists.txt?revision=1.6&root=CMake&view=markup


More information about the CMake mailing list