How to store CMake build settings

2019-01-09 04:20发布

问题:

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?

回答1:

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>


回答2:

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.