{"id":13166,"date":"2022-09-20T07:48:00","date_gmt":"2022-09-20T05:48:00","guid":{"rendered":"https:\/\/www.opengis.ch\/?p=13166"},"modified":"2022-10-13T09:02:49","modified_gmt":"2022-10-13T07:02:49","slug":"how-we-build-qfield-for-many-platforms-a-look-behind-the-curtain","status":"publish","type":"post","link":"https:\/\/www.opengis.ch\/it\/2022\/09\/20\/how-we-build-qfield-for-many-platforms-a-look-behind-the-curtain\/","title":{"rendered":"How we build QField for many platforms &#8211; A look behind the curtain"},"content":{"rendered":"\n<p><em>In the past year, <strong>the build system behind QField has been ported to <a href=\"https:\/\/vcpkg.io\/en\/index.html\">vcpkg, a modern C++ dependency management system<\/a><\/strong>. It has been a great success for QField and considerably helped to streamline efforts, improve the development experience and to guarantee an outstanding stability of the application. In this blog post we will look at the history of building QGIS based applications for mobile systems and how it has become what it is today.<\/em><\/p>\n\n\n\n<p>When <a href=\"https:\/\/www.opengis.ch\/2011\/08\/24\/gsoc-2011-final-report\/\">Marco Bernasocchi (CEO of OPENGIS.ch and chair of QGIS.org) started working on <strong>QGIS for Android<\/strong> in Google Summer of Code<\/a> a decade ago, the main job was to also build all QGIS dependencies for Android. This includes well-known libraries like <strong>proj<\/strong> and <strong>gdal<\/strong> and less-known ones like libxml2 or iconv. Each of them has its particularities and specific build flags. Working on this appears to be an endless iterative trial-and-error journey where you hope each day that eventually you will see the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.opengis.ch\/2021\/06\/08\/qfieldcloud-now-opensource-happy-10-years-of-field-mapping-with-qgis\/\" target=\"_blank\">QGIS splash screen on your Android phone<\/a> while all you see are endless lines of code and compiler errors.<\/p>\n\n\n\n<p>As we know nowadays QGIS for Android has eventually seen the sunlight and its achievements are still the base for <a href=\"https:\/\/qfield.org\/\">QGIS-based mobile apps like QField<\/a>.<\/p>\n\n\n\n<p>Sometime later we decided to modernize the build infrastructure into OSGeo4A a set of scripts where each dependency was built with a &#8220;recipe&#8221;. Modularized this way, it was easier to maintain, and general build code common for all libraries could be isolated. It was good enough to help drive QField for a couple of years, and a copy of it is still in use <strong>as the base for nowadays <a href=\"https:\/\/github.com\/qgis\/QGIS-Mac-Packager\/tree\/master\/qgis_deps\">QGIS builds for macOS<\/a><\/strong>.<\/p>\n\n\n\n<p>When we decided to make QField also available on other platforms like <strong>iOS, Windows and macOS<\/strong> we quickly realized that duplicating build chains scales really bad and maintaining this is an immense effort we wanted to avoid. There are a couple of existing C++ dependency management systems, none of which convinced us ultimately. Lucky for us a mail on the <a href=\"https:\/\/www.mail-archive.com\/qgis-developer@lists.osgeo.org\/msg52302.html\">QGIS mailing list mentioned a new one called vcpkg<\/a> which looked very promising.<\/p>\n\n\n\n<p>A couple of days later we had a build for Windows and later in the same year for macOS. With many dependencies already available in modern versions. Cheers.<\/p>\n\n\n\n<p>What&#8217;s left to do than just enable it for Android, and all our problems are suddenly solved? Alas, it&#8217;s not so easy. <strong>Cross-compiling is always a bit trickier.<\/strong> And so we started another journey to improve the situation. After a while, we had a working build chain based on vcpkg for Android in our R&amp;D labs. Interestingly, this added a couple of features just because the community around vcpkg had already added them. For example using <a href=\"https:\/\/www.cogeo.org\/\">COG<\/a>-based raster data via HTTP was suddenly working <em>(for the record: thanks to the availability of curl which we never took care of adding ourselves in OSGeo4A)<\/em>.<\/p>\n\n\n\n<p>Soon after we also wanted to try building for <strong>iOS with vcpkg<\/strong>, which after a few attempts also was successful, and even managed to resolve some weird crashes and other issues we had experienced with the old buildchain.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"211\" src=\"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=750%2C211&#038;ssl=1\" alt=\"\" class=\"wp-image-13169\" srcset=\"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=1024%2C288&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=300%2C84&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=768%2C216&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=469%2C132&amp;ssl=1 469w, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/Peek-2022-09-19-17-01.gif?resize=1536%2C432&amp;ssl=1 1536w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p>The main benefit was that we could upgrade the QGIS base libraries in one single place for every platform, in an isolated branch without playing the Jenga game on each upgrade. <\/p>\n\n\n\n<p>The only unfinished business we still had was that support for iOS and Android was still available only in our own vcpkg fork.<\/p>\n\n\n\n<p>So the last few weeks and months <strong>we have been working closely with upstream<\/strong> to bring building for Android and iOS up to the same level as desktop platforms. The relevant parts are now in a clean state. <\/p>\n\n\n\n<p>Advantages of this approach:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u2022 Mutualized efforts on all the base libraries, also with programmers outside the geoverse<\/li><li>\u2022 A vibrant community that ensures a noticeably fast upgrade of libraries<\/li><li>\u2022 A clean dependency management system<\/li><li>\u2022 A consistent set of dependency versions (gdal, geos, libpq, &#8230;) across all platforms<\/li><li>\u2022 A clean caching system that will only recompile reverse dependencies on updates<\/li><li>\u2022 We can upgrade a dependency in an isolated branch and only release it when it works on all platforms<\/li><li>\u2022 We can optimize the code for a given set of dependency versions and if a bug is fixed in a certain dependency version, we are sure we can ship this fix on all platforms promptly<\/li><li>\u2022 We maintain the QField source code as well as dependency versions in a single repository, what makes development more streamlined<\/li><\/ul>\n\n\n\n<p>Big thanks go to Alexander Neumann and Kai Pastor who both stand out for doing things the right and future-proof way.<\/p>\n\n\n\n<p>As always, things come at a price, there was a steep learning curve involved, and some edge cases require attention. However, we are thrilled by the simplification this has brought us.<\/p>\n\n\n\n<p>If you are maintaining a customized fork of QField, it is now a good time to <strong>start upgrading to vcpkg<\/strong>, since <a href=\"https:\/\/github.com\/opengisch\/OSGeo4A\">OSGeo4A has been archived<\/a> and will no longer be maintained. The <a href=\"https:\/\/github.com\/opengisch\/QField\/blob\/master\/doc\/dev.md\">developer documentation of QField<\/a> has been updated with relevant instructions.<\/p>\n\n\n\n<p>If you have time to test the new build system, <a href=\"https:\/\/github.com\/opengisch\/QField\/discussions\">we will be happy to read about your experiences<\/a> with it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the past year, the build system behind QField has been ported to vcpkg, a modern C++ dependency management system. It has been a great success for QField and considerably helped to streamline efforts, improve the development experience and to guarantee an outstanding stability of the application. In this blog [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":13180,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_themeisle_gutenberg_block_has_review":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[38],"tags":[125],"class_list":["post-13166","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-qfield","tag-qgis-org"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2022\/09\/rocket.jpg?fit=1920%2C1237&ssl=1","jetpack-related-posts":[{"id":1923,"url":"https:\/\/www.opengis.ch\/it\/2015\/12\/01\/qfield-for-android-5\/","url_meta":{"origin":13166,"position":0},"title":"QField for Android 5","author":"Marco Bernasocchi","date":"1 Dicembre 2015","format":false,"excerpt":"It's done, QField runs on any android from 4.0.3 (ICS) with a seamless installing experience. We suggest using at least Android 4.3","rel":"","context":"In &quot;Android QGIS&quot;","block_context":{"text":"Android QGIS","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/android-qgis\/"},"img":{"alt_text":"QField app on Google Play","src":"https:\/\/i0.wp.com\/developer.android.com\/images\/brand\/en_app_rgb_wo_45.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":4737,"url":"https:\/\/www.opengis.ch\/it\/2019\/01\/08\/qfield-1-0-rc1\/","url_meta":{"origin":13166,"position":1},"title":"New Year&#8217;s present &#8211; QField 1.0 RC1","author":"Marco Bernasocchi","date":"8 Gennaio 2019","format":false,"excerpt":"It was a long and winding road but we are very excited to announce the General availability of QField 1.0 Release Candidate 1. We ask you to help us test as much as possible this Release Candidate so that we can iron out as many bugs as possible before the\u2026","rel":"","context":"In &quot;Android QGIS&quot;","block_context":{"text":"Android QGIS","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/android-qgis\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":9700,"url":"https:\/\/www.opengis.ch\/it\/2019\/01\/08\/qfield-1-0-rc1-2\/","url_meta":{"origin":13166,"position":2},"title":"New Year&#039;s present &#8211; QField 1.0 RC1","author":"Marco Bernasocchi","date":"8 Gennaio 2019","format":false,"excerpt":"It was a long and winding road but we are very excited to announce the General availability of QField 1.0 Release Candidate 1. We ask you to help us test as much as possible this Release Candidate so that we can iron out as many bugs as possible before the\u2026","rel":"","context":"In &quot;Android QGIS&quot;","block_context":{"text":"Android QGIS","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/android-qgis\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC.png?fit=1200%2C584&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":1700,"url":"https:\/\/www.opengis.ch\/it\/2015\/06\/15\/qfield-in-the-wild\/","url_meta":{"origin":13166,"position":3},"title":"QField in the wild","author":"Marco Bernasocchi","date":"15 Giugno 2015","format":false,"excerpt":"QField Experimental is out, after a couple of months of requirements gathering, private early alpha testing and foremost tons of emails requesting access to the testes group we decided today to put the current BETA version in the playstore. This means that from now on you can install QField just\u2026","rel":"","context":"In &quot;Android QGIS&quot;","block_context":{"text":"Android QGIS","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/android-qgis\/"},"img":{"alt_text":"QField app on Google Play","src":"https:\/\/i0.wp.com\/developer.android.com\/images\/brand\/en_app_rgb_wo_45.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":4939,"url":"https:\/\/www.opengis.ch\/it\/2019\/01\/31\/you-gave-us-feedback-we-give-you-qfield-1-0-rc2\/","url_meta":{"origin":13166,"position":4},"title":"You gave us feedback &#8211; we give you QField 1.0 RC3","author":"Marco Bernasocchi","date":"31 Gennaio 2019","format":false,"excerpt":"We are really happy to announce the release a new great milestone in QField's history, QField 1.0 Release Candidate 3! (Yes, you might have got a glimpse of the broken RC2 if you where very attentive) Thanks to the great feedback we received since releasing RC1 we were able to\u2026","rel":"","context":"In &quot;QField&quot;","block_context":{"text":"QField","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC3.png?fit=1200%2C584&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC3.png?fit=1200%2C584&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC3.png?fit=1200%2C584&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC3.png?fit=1200%2C584&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.opengis.ch\/wp-content\/uploads\/2019\/01\/QField_RC3.png?fit=1200%2C584&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":1149,"url":"https:\/\/www.opengis.ch\/it\/2015\/01\/11\/qgis-mobile-0-2-demo\/","url_meta":{"origin":13166,"position":5},"title":"QGIS Mobile 0.2 Demo","author":"Marco Bernasocchi","date":"11 Gennaio 2015","format":false,"excerpt":"It is with great pleasure the we want to share with you the demo video of version 0.2. of QGIS Mobile (temporary name) is a touch optimized interface for field work developed by OPENGIS.ch. The QGIS mobile 0.2 video demonstrates some basic functionality like navigation, feature identification and attribute editing.\u2026","rel":"","context":"In &quot;Android QGIS&quot;","block_context":{"text":"Android QGIS","link":"https:\/\/www.opengis.ch\/it\/category\/gis\/qfield\/android-qgis\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_shortlink":"https:\/\/wp.me\/pbdBtI-3qm","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/posts\/13166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/comments?post=13166"}],"version-history":[{"count":12,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/posts\/13166\/revisions"}],"predecessor-version":[{"id":13184,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/posts\/13166\/revisions\/13184"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/media\/13180"}],"wp:attachment":[{"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/media?parent=13166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/categories?post=13166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.opengis.ch\/it\/wp-json\/wp\/v2\/tags?post=13166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}