Question

There are often many swiches to enable/disable when trying to build a project that uses CMake.

How do you store the build settings made by some user to make a build reproduceable on another machine? Is there some kind of export functionality or do you just copy the build (cache) folder?

Was it helpful?

Solution

There is an option to pre-load a script for populating the cache file with cmake using

cmake -C <initial-cache>

The initial-cache is a file containing variables set in the following way, e.g. for the install prefix:

set(CMAKE_INSTALL_PREFIX "/my/install/prefix" CACHE PATH "")

Then just pass this file while populating the cache with cmake. Easy, but I didn't know that and found no good sample. As a plus, this is an platform independent way instead of writing a script or batch file.

I create a separate script folder next to the sources out of the generated out-of-source build folder. My files containing the settings are stored there for each lib/executable to build.

You can put all the settings into a separate file and at the end of the day there are just a few calls left:

cmake -E make_directory build/somelib
cmake -E chdir build/somelib cmake -C ../../script/cmake/somelib.cmake ../../source/somelib/src
cmake --build build/somelib --target install

Simple, isn't it?

Automatically generate initial-cache file:

If you are on a *nix system you can run the following inside your build dir:

cmake -N -LA | tail -n+2 | sed -r 's/([A-Za-z_0-9]+):([A-Z]+)=(.*)/set(\1 "\3" CACHE \2 "")/' >cmake-init.txt

On Windows, something like the following cmake script should work:

# list all cache variables
# this should be run in your build dir

set(filename ${CMAKE_ARGV3})
message(STATUS "Writing to ${filename}")
if(NOT filename)
    message(FATAL_ERROR "Must provide an output filename")
    return()
endif()

execute_process(COMMAND "${CMAKE_COMMAND}" "-N" "-LA" OUTPUT_VARIABLE cacheVars)
string(REPLACE "\n" ";" cacheVars ${cacheVars})
file(WRITE ${filename} "")

foreach (variable ${cacheVars})
    string(REGEX REPLACE "([A-Za-z_0-9]+):([A-Z]+)=(.*)$" "set(\\1 \"\\3\" CACHE \\2 \"\")\n" output ${variable})
    if(CMAKE_MATCH_0)
        file(APPEND ${filename} ${output})
    endif()
endforeach()

Save it to, e.g., get_cache_vars.cmake and run it like:

cd <your build-dir>
cmake -P path\to\get_cache_vars.cmake <outputfile.txt>

OTHER TIPS

The best way to replicate this on another machine is to use -DSETTING=TRUE/FALSE args.

If you have a LOT of these options differing from the default you can build your cmake call using a script.

Ex:

#!/bin/bash
cmake -G "Unix Makefiles \
   -DOPTION1=TRUE
   -DOPTION2=FALSE

Distribute the helper bash script to the other machine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top