GNOME Bugzilla – Bug 751761
Support cmake build system
Last modified: 2017-10-23 21:16:59 UTC
elementary wants CMake support for Builder so they can use it as their SDK.
For CFLAGS extraction, it appears that some of ide-makecache.c can be reused (if not fully). Just like automake, we need the boostrap phase to have occurred so that we have a Makefile to parse.
I was planning to chat with you about this, to feel out what "support" would entail. I can't imagine automatically modifying CMake files, but it would be nice to be able to have a button to run cmake (the equivalent of a configure script) and another to run ninja (or make). (In reply to Christian Hergert from comment #1) > For CFLAGS extraction, it appears that some of ide-makecache.c can be reused > (if not fully). Just like automake, we need the boostrap phase to have > occurred so that we have a Makefile to parse. Hmm, parsing the generated Makefile does not seem like a good idea to me, if it can be avoided. For one, CMake has multiple backends. The Makefile backend is the default, but most WebKit developers don't use that, we use the Ninja backend (which is way faster for big projects). The other backends are mostly IDE-specific (e.g. Visual Studio, Kate, XCode... normally CMake outputs build files for an IDE, the opposite of what we want to do). If you had to pick only one to support, I would vote for Ninja, but ideally Builder would not be tied to any particular backend. I'm not completely clear on what the requirements are for "CFLAGS extraction," but maybe you can simply look in CMakeCache.txt for CMAKE_C_FLAGS and friends. [1] [2] I guess the goal is to discover the warning flags used for particular files? [1] http://www.cmake.org/Wiki/CMake_Useful_Variables [2] http://stackoverflow.com/questions/8474753/get-cmake-variable
(In reply to Michael Catanzaro from comment #2) > I'm not completely clear on what the requirements are for "CFLAGS > extraction," but maybe you can simply look in CMakeCache.txt for > CMAKE_C_FLAGS and friends. [1] [2] I guess the goal is to discover the > warning flags used for particular files? I was not aware you could use multiple backends. I agree that it would be nice to be backend independent. For C, on autotools, we parse the output of a make dry run, not the makefile itself. In particular, we are looking for includes (-I) an defines (-D) along with a few other options. The tricky part is resolving relative paths since clang needs full paths for include directories (since our CWD won't match the build). So first, we find all the targets that contain foo.c. Then we discover the flags for each of the targets (usually taking the first one that gives us reasonable cflags back).
You should be aware that CMake supports the JSON Compilation Database (http://clang.llvm.org/docs/JSONCompilationDatabase.html) of clang when “-DCMAKE_EXPORT_COMPILE_COMMANDS=Yes” is set. Something along the lines of $ mkdir tmp && cd tmp $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=Yes .. $ cp compile_commands.json .. $ cd .. && rm -rf tmp essentially serves the CFLAGS on a silver plate. You just have to parse the JSON.
(In reply to Richard Wiedenhöft from comment #4) > You should be aware that CMake supports the JSON Compilation Database > (http://clang.llvm.org/docs/JSONCompilationDatabase.html) of clang when > “-DCMAKE_EXPORT_COMPILE_COMMANDS=Yes” is set. Something along the lines of > > $ mkdir tmp && cd tmp > $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=Yes .. > $ cp compile_commands.json .. > $ cd .. && rm -rf tmp > > essentially serves the CFLAGS on a silver plate. You just have to parse the > JSON. Thanks for taking the time to suggest this. That should make this much, much easier.
I did start on a prototype for whoever wants to run with it. It does some of the basic mechanics in Python (which was a bit non-obvious for some GObject Introspection stuff). The branch is wip/cmake https://git.gnome.org/browse/gnome-builder/log/?h=wip%2Fcmake
I've started to write a plugin that would bring CMake support (make backend only so far). Alas, I'm not a CMake specialist, and thus, I'm wondering that would be the best option for extracting build targets. Parsing compile_commands.json, as suggested by Richard here, is working ok for build flags. Should we parse cmake_install.cmake for targets? Any better solutions? WiP code can be found here: https://gitlab.com/tchaik/gnome-builder/tree/wip/tchaik/cmake/plugins/cmake
Thanks for working on this Martin! Has anyone who has a CMake project had a chance to test this out? I don't know enough about CMake to provide appropriate guidance, but a quick glance at the cmake_install.cmake files looks like you'd have to write a real CMake syntax parser?
https://www.phoronix.com/scan.php?page=news_item&px=Qt-Creator-CMake-Server-Mode might be interesting. However it would lock us into a very new CMake requirement.
Ooooh cool. That looks clearly worth the cost of a high dependency. (FWIW I think Builder should always use Ninja unconditionally. There is no value in the make backend IMO; it has no advantages.)
Well, while having cmake plugin based on cmake-server would, indeed, be cool, wouldn't it be interesting to have a file based one? Could be used as a fallback for CMake version < 3.7. Then still, we need to figure out what's the better way of retrieving targets.
As always, I'm willing to defer to the person willing to write the code!
(In reply to Christian Hergert from comment #12) > As always, I'm willing to defer to the person willing to write the code! This, yes. But I am suspicious, because: (a) CMake server seems to be built for exactly what you're trying to do, specifically so that you don't have to do this style of file parsing (b) Your plugin will appear in Builder 3.24 at the earliest, and all users with Builder 3.24 will surely also have CMake 3.7 (unless Builder is installed manually or via Flatpak)
We can also ensure that the GNOME 3.24 SDK contains a 3.7 cmake. As we start developing against runtimes, it becomes important that the runtimes have some of the tooling we need because its hard for us to inject binaries into the runtime to provide the features.
Created attachment 362069 [details] [review] First (incomplete) attempt at porting cmake plugin to C. First version of a *non* cmake-server based C plugin for CMake (heavily based on the recent work done by Christian on the meson plugin)... From the commit message: * Build flags extraction is done using IdeCompileCommands and thus should be availabe after configure, no need for running a build. * Targets extraction isn't implemented yet. Best option would be to switch to a cmake-server based implementation. Still looking for a cheap bypass... * Async initialisation. If anyone knows about a trick that would allow us to extract targets in a simple and stylish way, please share your experience! I have been working on a cmake-server based implementation but seems to be a lot more work than expected. WiP code can be found here: https://gitlab.com/tchaik/gnome-builder/tree/wip/tchaik/cmake-server
Review of attachment 362069 [details] [review]: Cool! I'll test this tomorrow and see if we can get it merged. ::: src/plugins/cmake/gbp-cmake-pipeline-addin.c @@ +141,3 @@ + ide_subprocess_launcher_push_argv (configure_launcher, prefix_option); + + if (config_opts != NULL) This needs to be "if (!ide_str_empty0 (config_opts))", i just recently fixed that in the meson plugin.
Created attachment 362100 [details] [review] Second version, including the empty config_opts string fix. This second patch should include that fix that I missed...