<br><br>On Saturday, March 14, 2015, Aleix Pol <<a href="mailto:aleixpol@kde.org">aleixpol@kde.org</a>> wrote:<br>> On Wed, Mar 11, 2015 at 11:10 AM, Stephen Kelly <<a href="mailto:steveire@gmail.com">steveire@gmail.com</a>> wrote:<br>>> Hi,<br>>><br>>> Following from the thread here:<br>>><br>>>  <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12394">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12394</a><br>>>  <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12650">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12650</a><br>>><br>>> I'm starting to gather requirements and make sure the feature is<br>>> well designed to satisfy the needs we're already aware of, and fits with<br>>> the features CMake currently has.<br>>><br>>> The aim is to generate a structured file containing metadata relating the<br>>> buildsystem.<br>>><br>>> To help with completing the design of this feature, I've written<br>>> documentation (documentation driven design), and a unit test<br>>> containing a CMakeLists.txt file which exercises many modern CMake<br>>> features in the "generate-metadata" branch in my clone.<br>>><br>>> Mostly the design I propose can be read in the documentation I wrote. I'm<br>>> interested in any feedback.<br>>><br>>>  <a href="https://gitorious.org/cmake/steveires-cmake/source/generate-metadata:Tests/Metadata/CMakeLists.txt">https://gitorious.org/cmake/steveires-cmake/source/generate-metadata:Tests/Metadata/CMakeLists.txt</a><br>>>  <a href="http://www.steveire.com/cmake-future/manual/cmake-metadata-generation.7.html">http://www.steveire.com/cmake-future/manual/cmake-metadata-generation.7.html</a><br>>><br>>> I expect to require a few iterations to figure out what the metadata files<br>>> should contain in the end.  Note that there are already some differences<br>>> between my design and Aleix's implementation, such as that my design<br>>> proposes one metadata file per config. There are also some things<br>>> missing like location, because it is not yet clear to me whether build<br>>> or install locations are needed etc.<br>>><br>>> The content of the metadata file is determined by the build properties, and<br>>> is necessarily similar to the compile-related content created when<br>>> generating the actual buildsystem.  It additionally contains information<br>>> about the output locations of build artifacts and information relating to<br>>> the cmake description itself.<br>>><br>>> Goals include:<br>>><br>>> * Make it possible for IDEs to access the compile-related information for<br>>>   autocompletion and code navigation etc purposes.<br>>><br>>> * Remove the need for IDEs to parse generated Makefiles or Ninja files to<br>>>   access compile-related information.  The structure of those files is not<br>>>   'stable', while the content of the metadata file is stable.<br>>>     <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.user/48412">http://thread.gmane.org/gmane.comp.programming.tools.cmake.user/48412</a><br>>><br>>> <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11081">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11081</a><br>>><br>>> * Remove the need for users to create a new build directory and new build<br>>>   in order to use or switch IDEs.  QtCreator requires that<br>>>   the C::B 'extra generator is used as it parses compile information from<br>>>   that.  Other 'extra generators' such as for eclipse, sublime, kate etc<br>>>   also require fresh/new build directories, although the actual buildsystem<br>>>   they create is identical (assuming using all Makefile based or<br>>>   all Ninja based 'extra generators')<br>>><br>>> * Make it possible to write a plugin for the editors/IDEs such as sublime<br>>>   which consumes the metadata file and invokes the build using whatever<br>>>   buildsystem the user already has a build directory for, instead of<br>>>   writing an 'extra generator' and maintaining it in the cmake repo.<br>>>     <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/9004">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/9004</a><br>>><br>>> * Make it possible for editors/IDEs to allow specifying the configuration<br>>>   at build-time, where the IDE has that feature, and where a multi-config<br>>>   generator is available.  That is, QtCreator provides user-interface for<br>>>   choosing debug/release config to build.  Currently it can't offer that<br>>>   when using cmake, because it only allows the use of Makefile or Ninja<br>>>   generators, in order to make use of the C::B file.  QtCreator should be<br>>>   able to use the Xcode or Visual Studio generators, generate the metadata<br>>>   file(s), and invoke `cmake --build . --config ${CONFIG}` as<br>>>   appropriate.  Eclipse, Sublime and other editors have similar abilities<br>>>   to invoke config-specific builds after generation.<br>>><br>>> * Provide a list of 'build targets', which can be listed and invoked in<br>>>   IDE/editor user interface.  Build targets for all linked binaries<br>>>   and utilties are provided.  The tooling is expected to perform filtering<br>>>   on the target types to show only executables and utilities for<br>>>   execution, for example.<br>>><br>>> * Provide a list of source files per target per type of source file, eg<br>>>   object sources, header files, generated files, files excluded from the<br>>>   active configuration/platform/compiler, non-compiled files.<br>>><br>>> * Make it more easy for an IDE to support actions such as 'remove file<br>>>   from the project', which requires removing it from the CMakeLists.txt<br>>>   at the appropriate place, and 'add new file/class to target', which<br>>>   involves adding code to the CMakeLists.txt file at the appropriate<br>>>   place.  Most likely the easiest way to do the latter is using the<br>>>   target_sources() command, and to support the former, the location of<br>>>   the declaration of the target, and all target_sources() calls would<br>>>   need to be recorded.  Even that is not enough because of transitive<br>>>   consumption of source files through the link interface, but that is<br>>>   likely irrelevant.<br>>><br>>> * Provide information about the entire build graph of link-dependencies<br>>>   for visulization and dependency analysis<br>>>     <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/4042">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/4042</a><br>>><br>>> * Provide enough information about runtime link dependencies for IDEs to<br>>>   be able to properly invoke targets with debuggers, profilers and other<br>>>   tools.<br>>><br>>> <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11011">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11011</a><br>>><br>>><br>>> The CMAKE_EXPORT_COMPILE_COMMANDS variable already exists to generate<br>>> compile command lines, but that is a file whose format is defined by<br>>> Clang, not by CMake, and other tools in the Clang ecosystem also support<br>>> it.  It is not extensible or versioned in the way that a CMake-defined<br>>> file format is, so I don't propose using it as a starting point.<br>>><br>>> Notes:<br>>><br>>> * I deliberately didn't push an implementation to my repo, so that this<br>>>   discussion can focus on the design of the feature and contents of the<br>>>   file first.<br>>><br>>> * In the documentation and the test I didn't mention that the metadata file<br>>>   is JSON.  I'm not opposed to it, but I think there should be some kind of<br>>>   schema defining how to read the metadata file.  If we go with JSON<br>>> (instead of xml, say), then we'd have to define our own schema format, which<br>>>   is not impossible.  My proposal is to generate the schema beside the metadata<br>>>   file instead of writing a metadata version into the metadata file<br>>> itself.  Does<br>>>   anyone feel strongly about the file being JSON?  I just want to record the<br>>>   reason for everything in this design phase - we don't have to spend a lot<br>>>   of time on it.<br>> [1]<br>><br>>><br>>> * I didn't document the location or directory.  I'm not clear on whether<br>>>   it is supposed to be the build location, or the install location(s!),<br>>>   or all of those.<br>>><br>>> * I don't generate 'dependencies' (actually the list of files which the<br>>>   buildsystem re-generation depends on) as Aleix did, because there is no<br>>>   well-defined usefulness for that list yet.<br>> [2]<br>><br>>><br>>> * I documented the 'name' for the targets, and the TARGET_FILE_NAME<br>>>   etc information, and can push an implementation which generates them.<br>>><br>>> <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12619">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12619</a><br>>><br>>> * If it is useful to preprocess/compile/assemble individual files from<br>>>   IDEs, as made possible by the Makefiles and Ninja generators, we'll need<br>>>   to design that.<br>>><br>>> <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12429">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=12429</a><br>>><br>>> * Some more information from project() may be relevant, but it's not clear<br>>>   yet. We will likely know more when we have decided the file format and<br>>>   generated some 'interesting' metadata files.<br>>><br>>> * We might need backtraces for not only all add_library and add_executable<br>>>   calls, but also all target_sources() calls.<br>>><br>>> * We list the Generator used to configure the build.  That way IDEs know<br>>>   which build output parser to use.<br>>><br>>> * I propose to generate one metadata file per configuration active in the<br>>>   buildsystem.  That means that the Makefile and Ninja generators would<br>>>   generate only one file, and the multi-config generators would generate<br>>>   multiple files.  When changing the 'active configuration', IDEs would<br>>>   then read whatever metadata file is relevant to the active configuration.<br>>><br>>>   This also means that conditions don't need to be added inside the metadata<br>>>   file for configurations in order to show files 'excluded' by being part of<br>>>   a non-active configuration.  The code implementing discovery of excluded<br>>>   files is in the generate-metadata branch in my clone.<br>>><br>>><br>>> <a href="http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11323">http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10711/focus=11323</a><br>>>     "At least Qt Creator does not need information on which conditions to<br>>>      be met for a file to become part of the current build."<br>> [3]<br>><br>>><br>>> * I propose generating language-specific source lists, because CMake can<br>>>   build files with compilers which do not match their file extension.<br>>><br>>> * I propose generating language-specific compile properties in the metadata<br>>>   file if there a language specific variant groups.  For example if the<br>>>   compile options themselves are language-specific (the feature enabling that<br>>>   was merged to CMake master this week), then a property for each language<br>>>   is specified.  Otherwise only a language-agnostic property is generated. This<br>>>   can vary per-configuration for a multi-config generator, so each metadata<br>>>   file for a multi-config generator could have different properties present.<br>>>   Consumers read the language specific property if it is present, and read<br>>>   the language agnostic version otherwise.<br>>><br>>> * Generating metadata only (without generating buildsystem files) is not<br>>>   currently in scope.  This was requested several times, but it is not<br>>>   clear why.<br>> [4]<br>><br>>><br>>> * How much information does tooling need about installation?  Targets<br>>>   can use different include directories and compile definitions in their<br>>>   install locations compared to their build locations.  If IDEs want to<br>>>   provide some user interface related to the project files in their<br>>>   install location, perhaps a separate solution based on cmExportFile*<br>>>   is needed.  For future investigation.<br>> [5]<br>><br>> Hi,<br>> To be honest, I don't really understand why we're doing this here now,<br>> 7 months after the first e-mail with the proposal of the feature. I'm<br>> hoping we're doing this for transparency and, to be honest, all I want<br>> by now is this to be over.<br>><br>> [1] About schema, you mean this, no? <a href="http://json-schema.org/examples.html">http://json-schema.org/examples.html</a><br>> I think it's fine to come up with a schema, can be useful to provide<br>> tests I guess?<br><br>That looks great after a short glance, yes. <br><br>It should be useful not only for unit tests, but for telling tools how to parse the metadata files when multiple different versions of the content can be generated by cmake.<br><br>> I don't think it's important.<br>> I think JSON is the format to use, but then anything that's easily<br>> parseable works for me. JSON is, much more than XML even.<br><br>OK, I'm happy with using json too.<br><br>> [2] Ok. The KDevelop implementation was using it for being able to<br>> know what files are in scope. <br><br>By 'in scope' you mean 'used by the primary CMakeLists.txt files via include() or find_package()' or something like that? OK, let's see if that's the best source of that data or if we should add something new internally in cmake. <br><br><br>> I'm still planning to do some cmake<br>> parsing for code-completion and it seemed like a way to provide the<br>> information. We can consider this part of the second iteration of the<br>> project though, as it wasn't very useful as it was anyway.<br>><br>> [3] This is the biggest problem I see with this proposal. This has 2 problems:<br>> * We will have to set up a file system watcher to keep track of new<br>> cmake-metadata*.ext files popping up at random times.<br><br>The 'ext' was just a placeholder while I wasn't sure about the data format to generate. Let's call it cmake-metadata.json now.<br><br>The Makefile and Ninja generators will only ever generate and keep up-to-date a single 'cmake-metadata.json' without any -debug or -release suffix, because those are 'single configuration generators'. Xcode and Visual Studio will generate the configuration specific files, but will always regenerate all of them.<br><br>> * When the configs change, the file will remain there as cmake doesn't<br>> clean up stuff generated from previous builds. This will confuse the<br>> IDE since it will have available files that are not available anymore.<br><br>I think the above explanation covers this.<br><br>> [4] Because cmake is really slow and you often want to have the<br>> metadata file updated often, every time one of the cmake files in the<br>> project change.<br><br>OK, maybe we can add something for that, but is it the generation stage that is the slow part? How much time would we gain by doing this?<br><br>><br>> [5] In fact, installation information is more interesting for headers<br>> than targets, IMHO.<br><br>Can you say why? <br><br>><br>> Hope this helps,<br>> Aleix<br>><br><br>Yes it does, thanks very much!<br><br>Steve. <br>