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

Nicolas Desprès nicolas.despres at gmail.com
Sat Apr 21 10:26:15 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 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.
>

That's what I already do actually, but I wanted something more user
friendly. Anyway, I give up. Now I'm convinced that only a static
approach as you and Eric suggested that generate the part of the
README I don't want to see duplicated would work.

Cheers,

-- 
Nicolas Desprès


More information about the CMake mailing list