Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store CMake build settings

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?

like image 487
Beachwalker Avatar asked Jul 11 '13 08:07

Beachwalker


2 Answers

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>
like image 187
Beachwalker Avatar answered Sep 28 '22 03:09

Beachwalker


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.

like image 30
JonnyRo Avatar answered Sep 28 '22 02:09

JonnyRo