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

David Cole david.cole at kitware.com
Fri Apr 20 13:16:38 EDT 2012


2012/4/20 Nicolas Desprès <nicolas.despres at gmail.com>:
> 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.
>

All of the stuff that is visible as documentation strings in the
cmake-gui and ccmake interfaces should be available after a configure
step in the CMakeCache.txt. Some grep-ping with a few lines of context
should prove to you that the documentation you seek for cache
variables is easily available after configure. A re-arrangement of
what's there (or a grep it out and re-display it in your desired
format) should be quite possible already.


> Thank you for your feedback.
>
> --
> Nicolas Desprès


More information about the CMake mailing list