[CMake] Add --help-option command line option.

Nicolas Desprès nicolas.despres at gmail.com
Fri Apr 20 11:32:31 EDT 2012


2012/4/20 David Cole <david.cole at kitware.com>:
> 2012/4/20 Nicolas Desprès <nicolas.despres at gmail.com>:
>> 2012/4/20 Eric Noulard <eric.noulard at gmail.com>:
>>> Le 20 avril 2012 13:40, Nicolas Desprès <nicolas.despres at gmail.com> a écrit :
>>>> 2012/4/20 Eric Noulard <eric.noulard at gmail.com>:
>>>>> Le 20 avril 2012 10:44, Nicolas Desprès <nicolas.despres at gmail.com> a écrit :
>>>>>> Hi,
>>>>>>
>>>>>> I would like to have your opinion before to start to implement it.
>>>>>>
>>>>>> I would like to add the following options to the cmake command line interface:
>>>>>> --help-option opt [file]   = Print help for a given option and exit.
>>>>>> --help-option-list [file]  = List available options and exit.
>>>>>> --help-options [file]      = Print help for all options and exit.
>>>>>>
>>>>>> The goal is to have access to the project build options from the
>>>>>> command line interface like you can see them in ccmake and cmake-gui.
>>>>>> Advanced variable will be marked as such, of course. The output will
>>>>>> be similar to --help-variable* options.
>>>>>>
>>>>>> I have noticed that most cmake based projects document their options
>>>>>> in their README file whereas the documentation is already included in
>>>>>> cmake when you call the option() and set() commands. I hope this
>>>>>> feature will help to remove this duplication and people will just
>>>>>> write in their README file a "see cmake --help-options for available
>>>>>> build options".
>>>>>>
>>>>>> Comments?
>>>>>
>>>>> I think that Enabling/Designing some way to document user written CMake scripts
>>>>> is a very interesting goal.
>>>>>
>>>>
>>>> Thanks.
>>>>
>>>>> I started doing something along that line using basic markup, which has been
>>>>> used to improve CPack documentation (--help-variable and
>>>>> --help-command) in 2.8.8.
>>>>> see: http://www.cmake.org/Bug/bug_relationship_graph.php?bug_id=10067
>>>> Thanks for the pointer. Indeed, it is nice piece of work.
>>>>>
>>>>> My approach does not need to actually "parse" CMake script but only to
>>>>> catch comment line blocks.
>>>>> I say that because the problem with options is that
>>>>> you may need to parse **AND EVALUATE** some CMake script code
>>>>> in order to know whether if the OPTION is active or not.
>>>>>
>>>>> See e.g.
>>>>> cmake --help-module CMakeDependentOption
>>>>
>>>> Thanks for the pointer. I was not aware of this module.
>>>>
>>>>>
>>>>> So how would grab the documentation from OPTION or CMAKE_DEPENDENT_OPTION?
>>>>>
>>>>> 1a) Read out the provided CMake [file]  and custom parse  OPTION  and
>>>>> CMAKE_DEPENDENT_OPTION ?
>>>>> (possibly disregarding the control flow like OPTION inside IF(WIN32),
>>>>> IF(APPLE) etc...) ?
>>>>>
>>>>> 1b) Evaluate the CMakeLists.txt as ccmake and make-gui do?
>>>>>
>>>>> 2) Would you also handle "INCLUDE" and handle OPTION find in there as well?
>>>>>
>>>>> I think that a full parse (as done by ccmake and/or cmake-gui) is not
>>>>> easy at all.
>>>>> I'd suggest to parse OPTION (and CMAKE_DEPENDENT_OPTION) found in any
>>>>> CMakeLists.txt recursively, beginning with the one given on the command line,
>>>>> i.e. 1a) + recursion without 2).
>>>>>
>>>>> The main problem with this approach (be it recursive or not) is that you may
>>>>> list options which are platform dependent and/or conditionally evaluated.
>>>>>
>>>>> Another way to go is to require an extra ##option markup (in any
>>>>> script including CMakeLists.txt)
>>>>> that could be placed anywhere but ideally just before the real
>>>>> "OPTION/CMAKE_DEPENDENT_OPTION" statement.
>>>>> That way you can parse it the way I did for CPack doc without the need
>>>>> for any kind of CMake
>>>>> script evaluation.
>>>>> I know this duplicate the "comment" somehow, but it would give to the
>>>>> developer a mean to
>>>>> have more control concerning what is shown and what is not shown in
>>>>> terms of documentation.
>>>>>
>>>>> Using this scheme we can imagine some "unified" way to get user doc
>>>>> from user file (CMakeLists.txt or any *.cmake):
>>>>>
>>>>> --help-user-list <file>  --> list any user documented item from file
>>>>> (variable, command/macro, option, property etc...)
>>>>> --help-user <file>       --> dump all user doc whatever the category
>>>>>
>>>>> we can imagine some way to filter out the category we want
>>>>>
>>>>> --help-user-list <file> option
>>>>> --help-user <file> option <optionname>
>>>>> --help-user <file> variable <varname>
>>>>>
>>>>> etc...
>>>>>
>>>>
>>>> First of all thanks for replying. Although, that's an interesting
>>>> approach, I find it quite complex. Actually, I haven't dug into the
>>>> source code yet but what I had in mind was to basically/naively do the
>>>> same job that is done by ccmake and cmake-gui. I think (I haven't
>>>> checked yet) the code is already factored in some way, so I could just
>>>> call the right functions.
>>>
>>> If you go this way then calling:
>>> cmake --help-option-list CMakeLists.txt
>>
>> I would have say: cmake --help-option-list <builddir> like when you call ccmake.
>>
>>>
>>> will begin the configuration work which does not seem wise if you
>>> simply want to list some help.
>>>
>>> I wouldn't personally expect to get some side effect from --help-xxxx.
>>>
>>
>> We can name the command line option differently if it is problem.
>> --build-option-list for instance.
>>
>>>> That's said. Maybe ccmake and cmake-gui have some issues I am not
>>>> aware of and your approach try to address them.
>>>
>>> They don't have issue they do not do the same task.
>>> ccmake and cmake-gui (just like cmake) do **PROCESS**
>>> the CMakeLists.txt scripts so that when you push 'c' or 'configure'
>>> cache **file** gets populatedd, any configure_file is done etc...
>>
>> Ok. From my understanding, they all do the same job but with a
>> different user interface:
>> * cmake: command line
>> * ccmake: curses
>> * cmake-gui: gui
>>
>> As you have spotted below cmake differs from the others since it does
>> the configuration and the generation each time it is called.
>>
>>>
>>> at least ALL the default case CMakeLists.txt is interpreted.
>>
>> I agree.
>>
>>>
>>> none of the current  cmake --help-xxxx have any side-effect.
>>
>> Ok. So, we can name the option differently.
>>
>>>
>>>> One thing I forgot to mention in my first email is the handling of
>>>> variables marked as red in cmake-gui and with a * in ccmake. Honestly,
>>>> I have never really understood the logic behind this feature, but
>>>> again I think all that code is factored.
>>>
>>> ccmake and cmake-gui do a "one time" evaluation of all CMakeLists.txt hierarchy
>>> but do not generate (unlike cmake command) the generator files
>>> (Makefile, project files etc...).
>>> Before that they offer you a chance to further chose "option" or set values for
>>> some variables (CMAKE_INSTALL_PREFIX) etc...
>>>
>>> Then if you do mmodify something using the GUI/TUI you can hit
>>> 'c/configure' again.
>>> Each time you "configure" ccmake or cmake-gui shows you the "newly
>>> created variables",
>>> which is useful to know because for example after the first run you
>>> ticked an extra option
>>> which triggers the discovery of some program or file etc...which
>>> translates into a new
>>> CMake variable you can spot easily.
>>>
>>> As you already guess on the "configure" when you start ccmake/cmake-gui from
>>> an empty cache/build dir you get an "all red/all starred" var on subsequent call
>>> only new vars get displayed this way.
>>>
>>> I personally think you cannot implement some "--help-whatever" option
>>> that could possibly
>>> populate (even partially) the build tree, so that building
>>> "--help-whatever" on top on
>>> current functions implemented for ccmake or cmake-gui is a clear no GO.
>>>
>>> (as an explanation why it would be bad, for example bash completion
>>>  for cmake uses --help-xxx a lot in order to offer completion
>>>  see: http://www.cmake.org/Bug/view.php?id=13056)
>>>
>>> That's my own point of view, but I expect others will give their
>>> opinion as well.
>>
>> Ok. Thank you for the clarification. You have spotted interesting
>> points I did not really think about and mentioned in my first email.
>>
>> My main goal is to add to cmake the same features you have in ccmake
>> and cmake-gui and to ease the users to find out the interesting option
>> they have to pass to cmake without duplicating the documentation which
>> is already written in the CMakeLists.txt and the .cmake files. Also
>> that will provide something more or less similar as what you get with
>> configure --help when it is generated by autoconf.
>>
>> First, let's forget about naming the options --help-XXX since as you
>> have said they have side effects and could not be used in completion
>> scripts. Here the workflow, I have in mind:
>>
>> $ cd myproject
>> $ mkdir _build
>> $ cd _build
>> $ cmake --build-options ..
>> # The configuration and generation is performed.
>> # All the options and their value (including the advanced one? maybe
>> an extra argument would be necessary here?) are printed and marked
>> with a * like in ccmake.
>> $ cmake --build-options .
>> # The configuration and generation is performed.
>> # All the options and their value (including the advanced one? maybe
>> an extra argument would be necessary here?) are printed without the *.
>>
>> Now the users know they have to at least set CMAKE_BUILD_TYPE and
>> CMAKE_INSTALL_PREFIX for instance:
>>
>> $ cmake -DCMAKE_BUILD_TYPE=Release
>> -DCMAKE_INSTALL_PREFIX="$HOME/usr/stow/myproject" .
>> # The configuration and generation is performed.
>>
>> I think you get the idea. This approach does not change the current
>> behavior of cmake.
>>
>> Another approach, if we want to mimic more ccmake and cmake-gui, would
>> be to add --configure and --generate flags. They should be used only
>> when one of the --build-option* flag is present, in order to keep the
>> default current behavior. The behavior of --configure and --generate
>> would be the same as pushing respectively the "configure" and
>> "generate" button in cmake-gui. So, the workflow will look like:
>>
>> $ cd myproject
>> $ mkdir _build
>> $ cd _build
>> $ cmake --build-options .
>> CMake Error: The source directory "/home/despre_n/open-src/cmake/_b"
>> does not appear to contain CMakeLists.txt.
>> Specify --help for usage, or press the help button on the CMake GUI.
>> $ cmake --build-options ..
>> Empty cache.
>> Please configure first by specifying --configure.
>> $ cmake --build-options --configure ..
>> [...]
>> -- Configuring done
>> Build options available in this project:
>> (* mark newly created variables ; you can set this options using the -D flag)
>>
>> FOO*:BOOL=''
>>       Foo documentation
>> CMAKE_BUILD_TYPE*:STRING=''
>>       Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
>> CMAKE_C_FLAGS are used)
>>       Debug Release RelWithDebInfo MinSizeRel
>> $ cmake -DCMAKE_BUILD_TYPE=Debug --build-options .
>> Build options available in this project:
>> (* mark newly created variables ; you can set this options using the -D flag)
>>
>> FOO*:BOOL=''
>>       Foo documentation
>> CMAKE_BUILD_TYPE*:STRING='Debug'
>>       Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
>> CMAKE_C_FLAGS are used)
>>       Debug Release RelWithDebInfo MinSizeRel
>> $ cmake --configure .
>> [...]
>> -- Configuring done
>> $ cmake --build-options .
>> Build options available in this project:
>> (* mark newly created variables ; you can set this options using the -D flag)
>>
>> FOO:BOOL=''
>>       Foo documentation
>> CMAKE_BUILD_TYPE:STRING='Debug'
>>       Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
>> CMAKE_C_FLAGS are used)
>>       Debug Release RelWithDebInfo MinSizeRel
>> $ cmake --generate .
>> -- Generating done
>> -- Build files have been written to: <path to the build directory>
>>
>> What do you think of these approaches?
>>
>> --
>> Nicolas Desprès
>> --
>>
>> 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
>
>
> Don't spend too much effort/time on this without gathering a good
> consensus first, because I think we'll be unlikely to accept a patch
> that simply documents every darn thing under the sun. Only the
> project-specific things should be documented in project-specific help.
>

That's why I have posted this email before to start coding :-).

> These are good ideas, but the problem that we've identified and never
> figured out a good way around is that you'll end up with incomplete
> project documentation in this manner. Think about how options and
> variable set commands may be hidden inside if/else constructs that do
> not get processed, or subdirectories that are completely optional and
> do not get traversed. (We've had verbal discussions about this very
> thing for YEARS now... not sure if there are any mailing list
> discussions on archive about it.)
>

Are you suggesting that ccmake and cmake-gui do not do the "right" job?

> In my opinion, it would be better to have a mode of processing the
> CMakeLists files that gathers the relevant documentation strings from
> ALL occurrences of set, option and any other commands that have doc
> strings attached to them, for ALL POSSIBLE cmake code paths, and then
> cache the documentation after doing such processing. That is a
> completely different beast than the processor that we currently have
> in place, but it would produce complete project documentation.
>

Sounds really interesting but very intrusive in the parser at the same
time. Do the nodes of the abstract syntax tree accept a visitor? It
could helps implementing such things in a non-intrusive way. Others
languages like Emacs lisp or Python (I'm not sure about the last one)
already provide documentation embedded into the code. Maybe we could
have a look at how they deal with that issue.

> Another alternative would be to have projects specify their own help
> in a yet-to-be-invented form, and then be able to reference that help
> from the various set and option commands throughout their CMakeLists
> files. Perhaps a ProjectHelp.cmake file, with certain variables set in
> it, those variables indicating what other variables to document, such
> file to be included in the CMakeLists file? That would be better, in
> my opinion, because it would allow project authors to filter out stuff
> that they DON'T want documented.
>

Marking variables as internal or advanced isn't enough for saying "do
not document me for the end-user"?
Or do you mean something like: document(VAR1 VAR2 VAR3)?

Actually, my goal is just to brought to the cmake command line
interface exactly the same kind of features ccmake and cmake-gui
already have. Do you think it is too ambitious and/or would never
work? My coworkers and I are happy with the current behavior of ccmake
and cmake-gui. I just want to have the same feature in cmake for being
able to | grep things and scripts other stuff and also because I
prefer the command line interface rather than any interactive
interface for this task.

Thank you for your feedback.

-- 
Nicolas Desprès


More information about the CMake mailing list