Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can CMake arguments be forwarded to ExternalProject

Tags:

c++

cmake

I have (mostly) successfully set up ExternalProject_Add for googletest. However, I noticed that things like my choice of C++ compiler, build type, etc. are not automatically forwarded to the ExternalProject.

I can easily add any given flag by adding it to CMAKE_ARGS in the call to ExternalProject_Add like so:

CMAKE_ARGS -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS}

However, this requires that I enumerate all of the possible arguments that should be forwarded to googletests's CMake invocation, and that list is pretty enormous. I would also need to create that same list for every other ExternalProject_Add I wanted. That seems fragile and error prone.

Is there a way to tell CMake to "forward" the configuration that the user provided along? In other words, if I invoked CMake as:

cmake <path-to-project> -DCMAKE_C_COMPILER=/usr/bin/clang -DSOME_RANDOM_FLAG=stuff

Then I would like my call to ExternalProject_Add to provide the same compiler selection and value for SOME_RANDOM_FLAG, without needing to explicitly list those names. I'm not sure that simply passing CMake's ARGV along would work, since saying

CC=/usr/bin/clang cmake <path-to-project>

would ideally work as well.

Any thoughts on how to accomplish this?

like image 658
acm Avatar asked Aug 18 '12 19:08

acm


2 Answers

After long hours of trying to figure this out, it was finally answered (by Don Hinton) in the CMake mailing list. Fraser's solution is very close, but can still pass some project specific arguments that can cause some unpredictable behavior.

The following works properly. Hopefully this will save people some time trying to figure this out:

cmake_minimum_required(VERSION 3.1)

# MUST be done before call to 'project'
get_cmake_property(vars CACHE_VARIABLES)
foreach(var ${vars})
  get_property(currentHelpString CACHE "${var}" PROPERTY HELPSTRING)
    if("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "")
        # message("${var} = [${${var}}]  --  ${currentHelpString}") # uncomment to see the variables being processed
        list(APPEND CL_ARGS "-D${var}=${${var}}")
    endif()
endforeach()

project(SuperBuild)

include(ExternalProject)

ExternalProject_Add(ext_proj
  ...

  CMAKE_ARGS ${CL_ARGS}
)

Link to mailing list thread: https://cmake.org/pipermail/cmake/2018-January/067002.html

like image 115
Samaursa Avatar answered Nov 18 '22 14:11

Samaursa


I don't know of a robust way to achieve this, and I'm pretty sure there's no standard "CMake way", but my answer to a similar question about capturing CMake command line arguments might help you?

like image 4
Fraser Avatar answered Nov 18 '22 12:11

Fraser