[CMake] Disabling Argument Parsing in CMake -P Scripts

Gregoire Aujay gaujay at movea.com
Mon Mar 25 13:19:43 EDT 2013


Hello,

I would be interested in the '--' to disable command line argument parsing by CMake.
Has someone opened an issue on mantis for this one ?


Regards,
Gregoire


-----Original Message-----
From: cmake-bounces at cmake.org [mailto:cmake-bounces at cmake.org] On Behalf Of David Cole
Sent: samedi 3 novembre 2012 00:05
To: Eskandar Ensafi
Cc: cmake
Subject: Re: [CMake] Disabling Argument Parsing in CMake -P Scripts

On Fri, Nov 2, 2012 at 5:44 PM, Eskandar Ensafi <Ensafi at spacecomputer.com> wrote:
> I'm not sure if I'm qualified to propose a patch, but I will look at the source code to see what I can come up with.  I have additional concerns about the way the CMAKE_ARGVn variables are initialized, and this might be a good time to address these concerns.
>
> I don't know if this was a design choice, but with some exceptions, 
> CMake seems to first parse the entire command-line, and then it runs 
> each -P script in order, with CMAKE_ARGC/ARGVn initialized to the 
> entire command-line, not just the arguments following the appropriate 
> -P script.  When the command-line is parsed, some recognized options 
> are removed (e.g. -L[A][H], -N) with no ill effect, others are removed 
> but interfere with the initialization of CMAKE_ARGC/ARGVn (e.g. 
> --help, --version, and all variants), and some are parsed but NOT 
> removed (e.g. -D name:type=value, -G generator, contrary to comments 
> in my previous e-mail).  A more robust treatment of these command-line 
> arguments would be to fail with an error if incompatible combinations 
> of options are detected, and if any options are recognized and parsed 
> by CMake, they should be removed from the command-line.  Parsing 
> errors should cause to CMake to exit with an error, but this is not 
> consistent (-G fails given a bog
 us generator, but -D with a badly formed argument allows CMake to continue).
>
> To demonstrate, take the following simple example:
>
> # MyScript.cmake
> MESSAGE(">>> BEGIN SCRIPT >>>")
> IF (DEFINED MyVar)
>   MESSAGE("MyVar = ${MyVar}")
> ENDIF()
> MESSAGE("CMAKE_ARGC = ${CMAKE_ARGC}")
> MATH(EXPR ARGC "${CMAKE_ARGC} - 1")
> FOREACH(I RANGE 0 ${ARGC})
>   MESSAGE("CMAKE_ARGV${I} = ${CMAKE_ARGV${I}}")
> ENDFOREACH()
> MESSAGE("<<< END SCRIPT <<<")
>
> Then run it as follows:
>
> cmake -P MyScript.cmake testing -DMyVar=Test one two three -P 
> MyScript.cmake four five six
>
>>>> BEGIN SCRIPT >>>
> CMAKE_ARGC = 13
> CMAKE_ARGV0 = cmake
> CMAKE_ARGV1 = -P
> CMAKE_ARGV2 = MyScript.cmake
> CMAKE_ARGV3 = testing
> CMAKE_ARGV4 = -DMyVar=Test
> CMAKE_ARGV5 = one
> CMAKE_ARGV6 = two
> CMAKE_ARGV7 = three
> CMAKE_ARGV8 = -P
> CMAKE_ARGV9 = MyScript.cmake
> CMAKE_ARGV10 = four
> CMAKE_ARGV11 = five
> CMAKE_ARGV12 = six
> <<< END SCRIPT <<<
>>>> BEGIN SCRIPT >>>
> MyVar = Test
> CMAKE_ARGC = 13
> CMAKE_ARGV0 = cmake
> CMAKE_ARGV1 = -P
> CMAKE_ARGV2 = MyScript.cmake
> CMAKE_ARGV3 = testing
> CMAKE_ARGV4 = -DMyVar=Test
> CMAKE_ARGV5 = one
> CMAKE_ARGV6 = two
> CMAKE_ARGV7 = three
> CMAKE_ARGV8 = -P
> CMAKE_ARGV9 = MyScript.cmake
> CMAKE_ARGV10 = four
> CMAKE_ARGV11 = five
> CMAKE_ARGV12 = six
> <<< END SCRIPT <<<
>
> Notice how the entire command-line, including intervening -P options and the parsed -D option, is made available to both scripts (i.e. they are both executed with the same CMAKE_ARGC/ARGVn even though CMAKE_ARGV7 was the last argument for the first script, and CMAKE_ARGV10 to CMAKE_ARGV12 were the arguments for the second script).  This may or may not be useful, but to avoid breaking compatibility, I propose defining something like CMAKE_ARGC_FIRST and CMAKE_ARGC_LAST in each -P script invocation so that we can determine the range of options specific to the script being executed.
>
> Now, if we deliberately introduce an error in the -D flag as follows:
>
> cmake -P MyScript.cmake testing -DMyVar one two three -P 
> MyScript.cmake four five six
>
> Then CMake will run the first script, and it will exit with an error when it tries to parse -DMyVar (missing value).
>
> Since implementing a "--" option will require some changes to CMake's command-line parsing logic, I suggest that we fix the aforementioned issues as part of this effort.  Again, I am not the best person to undertake this effort due to my lack of familiarity with the CMake code base, but if someone with more experience would like to collaborate with me, I would be more than happy to help.
>
> Best,
>
> Eskandar
>
>
> On Nov 2, 2012, at 2:45 AM, David Cole wrote:
>
>> "--" for script mode is a good idea. (Actually, if we had this for 
>> non-script mode even, it would then make sense to expose the command 
>> line arguments in similar variables even when configuring a 
>> CMakeLists file. Presently, the CMAKE_ARGVn vars are only available 
>> in script
>> mode.)
>>
>> Can you propose a patch?
>>
>> If so, open a feature request in the bug tracker, and attach a "git 
>> format-patch -1" file.
>>
>> Thanks,
>> David
>>
>>
>> On Fri, Nov 2, 2012 at 12:21 AM, Eskandar Ensafi 
>> <Ensafi at spacecomputer.com> wrote:
>>> Hello,
>>>
>>> I often find it very useful to run CMake scripts of the form "cmake -P script-name arg1 arg2 ..." as a cross-platform scripting solution that doesn't rely on Perl, Python, etc.  One major limitation is that CMake continues to parse all arguments after the script name.  For example, if arg1 is "-i" then CMake will enter wizard mode before executing the script, and options such as "-D", "-G" and "-L" will be parsed and removed from the command-line by CMake.  The current behavior limits the flexibility of CMake's script mode by making it impossible to pass arbitrary options to be parsed directly by the script.
>>>
>>> It would be great if I could somehow specify "cmake -P script-name -- arg1 arg2 ..." to tell CMake to stop parsing all subsequent arguments while still placing arg1, arg2, etc. in the CMAKE_ARGVn variables.  If the "--" flag is potentially problematic and may pose compatibility problems, perhaps another syntax can be adopted, such as "cmake -PP script-name arg1 arg2 ..." where -P is doubled.
>>>
>>> Is this something that can be easily implemented?
>>>
>>> Best,
>>>
>>> Eskandar
>>> --
>>>
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at 
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Please keep messages on-topic and check the CMake FAQ at: 
>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.cmake.org/mailman/listinfo/cmake
>

Unfortunately, the CMake command line parsing code is an organically grown mess in need of some serious clean up and attention. It's going to take somebody a lot of time and effort to clean it up *without* breaking backwards compatibility. As you've discovered, it has its quirks. It doesn't error on things it doesn't know about, as you prove with your "one" "two" "three" arguments... But it does error for some conditions.

This would be a good item to put on the list for when we finally transition to CMake 3.0 (at some point in the as yet undetermined
future...) where we would be free(-er) to break the backwards compatibility barrier.

It's never easy, though: people are using the command line in ways today that I'm sure none of us expect.

Anyhow, have a good weekend...


David
--

Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake




More information about the CMake mailing list