{"id":540,"date":"2020-06-30T15:47:01","date_gmt":"2020-06-30T14:47:01","guid":{"rendered":"http:\/\/eocanha.org\/blog\/?p=540"},"modified":"2020-06-30T15:47:01","modified_gmt":"2020-06-30T14:47:01","slug":"developing-on-webkitgtk-with-qt-creator-4-12-2","status":"publish","type":"post","link":"https:\/\/eocanha.org\/blog\/2020\/06\/30\/developing-on-webkitgtk-with-qt-creator-4-12-2\/","title":{"rendered":"Developing on WebKitGTK with Qt Creator 4.12.2"},"content":{"rendered":"\n<p>After the latest migration of WebKitGTK test bots to use the <a href=\"https:\/\/base-art.net\/Articles\/introducing-the-webkit-flatpak-sdk\/\">new SDK based on Flatpak<\/a>, the old development environment based on jhbuild became deprecated. It can still be used with <code>export WEBKIT_JHBUILD=1<\/code>, though, but support for this way of working will gradually fade out.<\/p>\n\n\n\n<p>I used to work on a chroot because I love the <a href=\"\/blog\/2013\/12\/19\/using-schroot-to-have-a-stable-and-transplantable-development-environment\/\">advantages of having an isolated and self-contained environment<\/a>, but <a href=\"https:\/\/github.com\/containers\/bubblewrap\/issues\/214\">an issue in the way bubblewrap manages mountpoints<\/a> basically made it impossible to use the new SDK from a chroot. It was time for me to update my development environment to the new ages and have it working in my main Kubuntu 18.04 distro.<\/p>\n\n\n\n<p>My mail goal was to have a comfortable IDE that follows standard GUI conventions (that is, no emacs nor vim) and has code indexing features that (more or less) work with the WebKit codebase. Qt Creator was providing all that to me in the old chroot environment thanks to some configuration tricks by <a href=\"https:\/\/github.com\/ntrrgc\">Alicia<\/a>, so it should be good for the new one.<\/p>\n\n\n\n<p>I preferred to use <a href=\"https:\/\/download.qt.io\/official_releases\/qtcreator\/4.12\/4.12.2\/qt-creator-opensource-linux-x86_64-4.12.2.run\">the Qt Creator 4.12.2 offline installer for Linux<\/a>, so I can download exactly the same version in the future in case I need it, but other platforms and versions are also <a href=\"https:\/\/download.qt.io\/official_releases\/qtcreator\/\">available<\/a>.<\/p>\n\n\n\n<p>The WebKit source code can be downloaded as always using git:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">git clone git.webkit.org\/WebKit.git<\/pre>\n\n\n\n<p>It&#8217;s useful to add <code>WebKit\/Tools\/Scripts<\/code> and <code>WebKit\/Tools\/gtk<\/code> to your PATH, as well as any other custom tools you may have. You can customize your <code>$HOME\/.bashrc<\/code> for that, but I prefer to have an <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/env.sh\"><code>env.sh<\/code> environment script<\/a> to be sourced from the current shell when I want to enter into my development environment (by running <code><a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/webkit\">webkit<\/a><\/code>). If you&#8217;re going to use it too, remember to adjust to your needs the paths used there.<\/p>\n\n\n\n<p>Even if you have a pretty recent distro, it&#8217;s still interesting to have the latests Flatpak tools. Add <a href=\"https:\/\/launchpad.net\/~alexlarsson\/+archive\/ubuntu\/flatpak\">Alex Larsson&#8217;s PPA<\/a> to your apt sources:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo add-apt-repository ppa:alexlarsson\/flatpak<\/pre>\n\n\n\n<p>In order to ensure that your distro has all the packages that webkit requires and to install the WebKit SDK, you have to run these commands (I omit the full path). Downloading the Flatpak modules will take a while, but at least you won&#8217;t need to build everything from scratch. You will need to do this again from time to time, every time the WebKit base dependencies change:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">install-dependencies<br>update-webkitgtk-libs<\/pre>\n\n\n\n<p>Now just build WebKit and check that MiniBrowser works:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">build-webkit --gtk\nrun-minibrowser --gtk<\/pre>\n\n\n\n<p>I have automated the previous steps as <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/go\"><code>go full-rebuild<\/code><\/a> and <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/runtest.sh\"><code>runtest.sh<\/code><\/a>.<\/p>\n\n\n\n<p>This build process should have generated a <code>WebKit\/WebKitBuild\/GTK\/Release\/compile_commands.json<\/code><br> file with the right parameters and paths used to build each compilation unit in the project. This file can be leveraged by Qt Creator to get the right include paths and build flags after some preprocessing to translate the paths that make sense from inside Flatpak to paths that make sense from the perspective of your main distro. I wrote <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/compile_commands.sh\"><code>compile_commands.sh<\/code><\/a> to take care of those transformations. It can be run manually or automatically when calling <code>go full-rebuild<\/code> or <code>go update<\/code>.<\/p>\n\n\n\n<p>The WebKit way of managing includes is a bit weird. <a href=\"https:\/\/github.com\/WebKit\/webkit\/blob\/master\/Source\/WebCore\/html\/HTMLMediaElement.cpp#L26\">Most of the cpp files<\/a> include <a href=\"https:\/\/github.com\/WebKit\/webkit\/blob\/master\/Source\/WebCore\/config.h\"><code>config.h<\/code><\/a> and, only after that, they include the <a href=\"https:\/\/github.com\/WebKit\/webkit\/blob\/master\/Source\/WebCore\/html\/HTMLMediaElement.h\">header file<\/a> related to the cpp file. Those header files <a href=\"https:\/\/github.com\/WebKit\/webkit\/blob\/master\/Source\/WebCore\/html\/HTMLMediaElement.h#L28\">depend on defines<\/a> <a href=\"https:\/\/github.com\/WebKit\/webkit\/blob\/master\/Source\/WTF\/wtf\/PlatformEnable.h#L36\">declared transitively when including <code>config.h<\/code><\/a>, but that file isn&#8217;t directly included by the header file. This breaks the intuitive rule of &#8220;headers should include any other header they depend on&#8221; and, among other things, completely confuse code indexers. So, in order to give the Qt Creator code indexer a hand, the <code>compile_commands.sh<\/code> script <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/compile_commands.sh#L12\">pre-includes <code>WebKit.config<\/code> for every file<\/a> and <a href=\"https:\/\/github.com\/eocanha\/webkit-tools\/blob\/master\/WebKit.config\">includes <code>config.h<\/code> from it<\/a>.<\/p>\n\n\n\n<p>With all the needed pieces in place, it&#8217;s time to import the project into Qt Creator. To do that, click <em>File \u2192 Open File or Project<\/em>, and then select the <code>compile_commands.json<\/code> file that <code>compile_commands.sh<\/code> should have generated in the WebKit main directory.<\/p>\n\n\n\n<p>Now make sure that Qt Creator has the right plugins enabled in <em>Help \u2192 About Plugins&#8230;<\/em>. Specifically: GenericProjectManager, ClangCodeModel, ClassView, CppEditor, CppTools, ClangTools, TextEditor and LanguageClient (more on that later).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_plugins-640x1024.png\" alt=\"\" class=\"wp-image-547\" width=\"320\" height=\"512\" srcset=\"https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_plugins-640x1024.png 640w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_plugins-188x300.png 188w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_plugins-768x1229.png 768w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_plugins.png 910w\" sizes=\"(max-width: 320px) 100vw, 320px\" \/><\/figure><\/div>\n\n\n\n<p>With this setup, after a brief initial indexing time, you will have support for features like <em>Switch header\/source (F4)<\/em>, <em>Follow symbol under cursor (F2)<\/em>, shading of disabled if-endif blocks, <code>auto<\/code> variable type resolving and code outline. There are some oddities of <code>compile_commands.json<\/code> based projects, though. There are no compilation units in that file for header files, so indexing features for them only work sometimes. For instance, you can switch from a method implementation in the cpp file to its declaration in the header file, but not the opposite. Also, you won&#8217;t see all the source files under the <em>Projects<\/em> view, only the compilation units, which are often just a bunch of <code>UnifiedSource-*.cpp<\/code> files. That&#8217;s why I prefer to use the <em>File System<\/em> view.<\/p>\n\n\n\n<p>Additional features like <em>Open Type Hierarchy (Ctrl+Shift+T)<\/em> and <em>Find References to Symbol Under Cursor (Ctrl+Shift+U)<\/em> are only available when a Language Client for <a href=\"https:\/\/microsoft.github.io\/language-server-protocol\/overview\">Language Server Protocol<\/a> is configured. Fortunately, the new WebKit SDK comes with the <a href=\"https:\/\/github.com\/MaskRay\/ccls\">ccls<\/a> C\/C++\/Objective-C language server included. To configure it, open <em>Tools \u2192 Options&#8230; \u2192 Language Client<\/em> and add a new item with the following properties:<\/p>\n\n\n\n<ul><li>Name: ccls<\/li><li>Language: <code>*.c;.cpp;*.h<\/code><\/li><li>Startup behaviour: Always On<\/li><li>Executable: <code>\/home\/enrique\/work\/webkit\/WebKit\/Tools\/Scripts\/webkit-flatpak<\/code><\/li><li>Arguments: <code>--gtk -c ccls --index=\/home\/enrique\/work\/webkit\/WebKit<\/code><\/li><\/ul>\n\n\n\n<p>Some &#8220;<code>LanguageClient ccls: Unexpectedly finished. Restarting in 5 seconds.<\/code>&#8221; errors will appear in the <em>General Messages<\/em> panel after configuring the language client and every time you launch Qt Creator. It&#8217;s just ccls taking its time to index the whole source code. It&#8217;s &#8220;normal&#8221;, don&#8217;t worry about it. Things will get stable and start to work after some minutes.<\/p>\n\n\n\n<p>Due to the way the Locator file indexer works in Qt Creator, it can become confused, run out of memory and die if it finds cycles in the project file tree. This is common when using Flatpak and running the MiniBrowser or the tests, since <code>\/proc<\/code> and other large filesystems are accessible from inside <code>WebKit\/WebKitBuild<\/code>. To avoid that, open <em>Tools \u2192 Options&#8230; \u2192 Environment \u2192 Locator<\/em> and set <em>Refresh interval<\/em> to 0 min.<\/p>\n\n\n\n<p>I also prefer to call my own custom build and run scripts (<code>go<\/code> and <code>runtest.sh<\/code>) instead of letting Qt Creator build the project with the default builders and mess everything. To do that, from the <em>Projects mode (Ctrl+5)<\/em>, click on <em>Build &amp; Run \u2192 Desktop \u2192 Build<\/em> and edit the build configuration to be like this:<\/p>\n\n\n\n<ul><li>Build directory: <code>\/home\/enrique\/work\/webkit\/WebKit<\/code><\/li><li><em>Add build step \u2192 Custom process step<\/em><ul><li>Command: <code>go<\/code> (no absolute route because I have it in my PATH)<\/li><li>Arguments:<\/li><li>Working directory: <code>\/home\/enrique\/work\/webkit\/WebKit<\/code><\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Then, for <em>Build &amp; Run \u2192 Desktop \u2192 Run<\/em>, use these options:<\/p>\n\n\n\n<ul><li>Deployment: No deploy steps<\/li><li>Run:<ul><li>Run configuration: <em>Custom Executable \u2192 Add<\/em><ul><li>Executable: runtest.sh<\/li><li>Command line arguments:<\/li><li>Working directory:<\/li><\/ul><\/li><\/ul><\/li><\/ul>\n\n\n\n<p>With these configuration you can build the project with <em>Ctrl+B<\/em> and run it with <em>Ctrl+R<\/em>.<\/p>\n\n\n\n<p>I think I&#8217;m not forgetting anything more regarding environment setup.  With the instructions in this post you can end up with a pretty complete IDE. Here&#8217;s a screenshot of it working in its full glory:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"576\" src=\"https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-1024x576.png\" alt=\"\" class=\"wp-image-549\" srcset=\"https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-1024x576.png 1024w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-300x169.png 300w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-768x432.png 768w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-1536x864.png 1536w, https:\/\/eocanha.org\/blog\/wp-content\/uploads\/2020\/06\/qtcreator_ide-2048x1152.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Anyway, to be honest, nothing will ever reach the level of code indexing features <a href=\"https:\/\/eocanha.org\/blog\/2014\/10\/11\/hacking-on-chromium-for-android-from-eclipse-part-1\/\">I got with Eclipse<\/a> some years ago. I could find usages of a variable\/attribute and know where it was being read, written or read-written. Unfortunately, that environment stopped working for me long ago, so Qt Creator has been the best I&#8217;ve managed to get for a while.<\/p>\n\n\n\n<p>Properly configured web based indexers such as the <a href=\"https:\/\/webkit-search.igalia.com\/\">Searchfox instance configured in Igalia<\/a> can also be useful alternatives to a local setup, although they lack features such as type hierarchy.<\/p>\n\n\n\n<p>I hope you&#8217;ve found this post useful in case you try to setup an environment similar to the one described here. Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After the latest migration of WebKitGTK test bots to use the new SDK based on Flatpak, the old development environment based on jhbuild became deprecated. It can still be used with export WEBKIT_JHBUILD=1, though, but support for this way of working will gradually fade out. I used to work on a chroot because I love &hellip; <a href=\"https:\/\/eocanha.org\/blog\/2020\/06\/30\/developing-on-webkitgtk-with-qt-creator-4-12-2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Developing on WebKitGTK with Qt Creator 4.12.2<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,12],"tags":[],"_links":{"self":[{"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/posts\/540"}],"collection":[{"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/comments?post=540"}],"version-history":[{"count":9,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/posts\/540\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/posts\/540\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/media?parent=540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/categories?post=540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eocanha.org\/blog\/wp-json\/wp\/v2\/tags?post=540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}