Script mode and arbitraty arguments

Hi,

I’m trying to use CMake script as <lang>_COMPLIER_LAUNCHER setting it to ${CMAKE_COMMAND} -P my-wrapper.cmake.
Here is my trivial script just to show given parameters:

foreach(_arg RANGE ${CMAKE_ARGC})
    message(STATUS "${_arg}: `${CMAKE_ARGV${_arg}}`")
endforeach()

The problem is that compiler given args may contain -DFOO args and CMake trying to parse them…
Sample output:

$ cmake -P my-wrapper.cmake one two -DFOO
-- 0: `cmake`
-- 1: `-P`
-- 2: `my-wrapper.cmake`
-- 3: `one`
-- 4: `two`
-- 5: `-DFOO`
-- 6: ``
CMake Error: Parse error in command line argument: -DFOO
Should be: VAR:type=value

CMake Error: Problem processing arguments. Aborting.

I propose the following changes:
CMake in scripting mode should stop processing its args after -- “option” and pass remaining options as is. E.g.:

$ cmake -DFOO=BAR -P my-wrapper.cmake -- one two -DFOO

The script gets the FOO variable w/ value BAR as expected, but everything after -- just assigned to CMAKE_ARGV<n> variable and shouldn’t trigger an error.

PS. I’m ready to work on MR…

2 Likes

Seems reasonable to me, I’d be supportive of such an enhancement. We would want Brad’s confirmation that there’s not some historical reason why this hasn’t already been done (it’s a tough thing to search for in the existing list of issues!). It seems like the sort of functionality that I would have expected to have come up before.

The other weird thing:
CMake runs script first then continue to “parse” arguments and failed finally %)

Looking to the code I see that script gonna run as soon as -P <script> option found. Meaning that

  1. only variables found before -P would be passed
  2. what is “expected” behavior here:
    $ cmake -DFOO=BAR -P script.cmake -DFOO=BAZ
    
    I.e., isn’t it “expected” FOO to have BAZ?
  3. it’s possible to run multiple scripts with different set of variables
    Example:
    $ cmake -DFOO=BAR -P 1.cmake -DFOO=BAZ -P 2.cmake
    
    the first script gets BAR as FOO value but the second gets BAZ.

@brad.king Should I preserve any backward-compatible behavior here?

Keep in mind that the CMake documentation is pretty clear that -D options must come before -P:

cmake [{-D <var>=<value>}...] -P <cmake-script-file>

Process the given cmake file as a script written in the CMake language. No configure or generate step is performed and the cache is not modified. If variables are defined using -D , this must be done before the -P argument.

One could potentially mount a case that anything after the -P <cmake-script-file> should be treated as arguments to the script and not processed at all. Given the existing behaviour of running the script as soon as the -P argument is processed, would we even need to use a -- option to separate the script args from the CMake args? The fact that the current behavior allows multiple -P invocations to be chained is something I’ve never seen and is not mentioned anywhere in the docs, as far as I can tell. I doubt this is something that we should try to preserve, but Brad can make that call.

Yes, backward compatibility needs to be preserved. One way to do this would be to have a different option altogether for running scripts (not -P).

MR4707