cldoc icon indicating copy to clipboard operation
cldoc copied to clipboard

Use CMake JSON compilation database

Open gnzlbg opened this issue 11 years ago • 10 comments
trafficstars

CMake can generate a compilation data-base for all files in a project (which includes per file compiler flags) as follows:

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

It would be awesome if cldoc could use it to generate documentation without needing to provide it with a list of files and flags.

gnzlbg avatar Jul 31 '14 12:07 gnzlbg

Integration with build systems is up to the user. It is trivial to add a target to autotools (for example), which calls cldoc with the right flags and source files. I imagine the same is easily possible for cmake as well. I'm not a cmake user, so I can't offer you the specifics of doing such a thing. I would be happy to provide a cmake module/macro with cldoc which makes the process easier (extracting the right flags + sources for a specific target lib/exec), but as I said, I don't have the expertise to write one myself.

jessevdk avatar Aug 02 '14 06:08 jessevdk

Integration with build systems is up to the user.

Making it easier won't hurt and CMake is widely used. I am willing to patch/write whatever functionality is necessary and add a minimal example about how to add it to CMake.

Can you pass cldoc different flags for different source files?

CMake generates a JSON file (called compile_commands.json) that looks like this:

[
{
  "directory": "/user/name/build_dir/sub_dir",
  "command": "/usr/local/bin/clang++    -stdlib=libc++ -std=c++1z -Wall -Wextra -Wdocumentation -pedantic -g3 -fomit-frame-pointer -O0 -fno-inline -o CMakeFiles/sub_dir/file1.cpp.o -c /user/name/source_dir/sub_dir/file1.cpp",
  "file": "/user/name/source_dir/sub_dir/file1.cpp"
},
{
  "directory": "/user/name/build_dir/sub_dir",
  "command": "/usr/local/bin/clang++    -stdlib=libc++ -std=c++1z -Wall -Wextra -Wdocumentation -pedantic -g3 -fomit-frame-pointer -O0 -fno-inline -o CMakeFiles/sub_dir/file2.cpp.o -c /user/name/source_dir/sub_dir/file2.cpp",
  "file": "/user/name/source_dir/sub_dir/file2.cpp"
}
]

It contains everything cldoc needs:

  • the path to the directory in which the file will be built,
  • all the compiler commands to build the given target (they can be different for each target)
  • the path to the file.

gnzlbg avatar Aug 02 '14 09:08 gnzlbg

What I'm saying is that it's easier/better to integrate it directly in cmake. Meaning, you simply add a new target (i.e. docs) to your cmake file, and call cldoc appropriately from there. Then you can simply do make docs to invoke cldoc. The added benefit is that you don't need to export any data from cmake, or parse (possibly unstable) json formats. Everything you need is already available from within cmake.

See https://github.com/jessevdk/cldoc/blob/master/example/CMakeLists.txt for an example

jessevdk avatar Aug 02 '14 10:08 jessevdk

This is how i'm doing it and is a pain since:

  • it forces you to maintain a list of header and source files, and
  • if doesn't take possibly different compile flags between the source files (resulting in libclang errors).

I've actually achieved to automate this a bit with file(GLOB_RECURSE ..) to create the list of file but this option is advised against by CMake developers and documentation (you need to run cmake again every time a file changes).

This works fine for a toy example, but I haven't been able to scale it to a small project. The compilation database gives you everything you need, and it is a stable json format, clang-analyzer, clang-tidy and other tools use it without problems.

I'm open to any suggestion that allows cldoc to be used in a small project. My only needs in CMake are:

  • it has to automatically get all header and source file information from cmake,
  • it has to automatically use the correct flags for each source file,
  • it should support using an user provided libclang (since for example the -std=c++1z only works with clang trunk but not with the libclang provided by XCode under Mac).

gnzlbg avatar Aug 02 '14 10:08 gnzlbg

Like I said before, patches are welcome. I don't use cmake. cldoc does not allow for specifying differenc compile args for different files from the command line, but it's trivial to add support for it when reading information from a file instead. I'd suggest adding a flag to the generate command which accepts the cmake json db file and process info from there.

jessevdk avatar Aug 02 '14 10:08 jessevdk

I'd suggest adding a flag to the generate command which accepts the cmake json db file and process info from there.

Ok. I'll fork and branch and will try to get that going first.

gnzlbg avatar Aug 02 '14 10:08 gnzlbg

@gnzlbg Did you have any problems with the cmake branch?

fire avatar Sep 30 '14 17:09 fire

@fire lack of time =/

gnzlbg avatar Oct 01 '14 08:10 gnzlbg

Actually I would see some intersting use cases for such a feature :

  • possibility to support project with different flags compiler (imagine a C/C++ project that mixes C and C++11 sources )
  • some build tools supports the clang compile_commands.json listing, so its not tied to cmake. Actually when using libclang this should be the preferred way to parse file. irony for emacs uses it to provide easy to configure auto-completion for a project. The important thing I mean, is that it is not a cmake thing at all
  • This feature could be the pre-requisite for a tool that would inotify this file and the file listed there, and regenerate on a per-file basis the documentation, and use something like livereload to reload the generated documentation. It would be really useful when generating large chunk of data

atuleu avatar Nov 27 '15 11:11 atuleu

@gnzlbg I looked into this feature. I don't think it will be useful for automatic listing of source file. I like to put my documentation in header file for example. CMake will render a database for .cpp file only. Then if you use cldoc on a .cpp file that have no documentation, it will not render anything. Therefore you will still need to give manually the list of file you want to parse.

It is a big issue, because if you just expand the .cpp files to get the documentation located in the headers, for most c++ projects you will for sure parse the header files several times ... I don't know how the rest of the parser will do when encountering several time the same documentation. And then what happen if you include a library documented with cldoc ? you will have its documentation embedded and listed in your library ... :/ so you have to expand only the file based in your BASEDIR ... seems quite complicated.

We still have the issue if we just want to have the right compile flags for any header file.

We could simply use a rule .h <=> .cpp matching based on the Basename of a file, but in some project, you would miss some files. For example, what is the rule for a "config.h" header, that most of the time never have a .cpp file associated with.

I don't think asking for user to use the feature "compile database" to put all their documentation in source file is a good practice. First it will introduce different behavior on what seems unrelated options, and I don't like myself to put non internal documentation in source files.

So at the beginning it looks like for me it was a a "no worries, I can implement this in a couple of hour feature", but this is a bit more involved, and I see no easy way to do it ...

atuleu avatar Nov 30 '15 11:11 atuleu