How can CMake arguments be forwarded to ExternalPr

2019-02-08 10:53发布

问题:

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?

回答1:

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



回答2:

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?



标签: c++ cmake