<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://amirmasoudabdol.name/feed.xml" rel="self" type="application/atom+xml" /><link href="https://amirmasoudabdol.name/" rel="alternate" type="text/html" /><updated>2023-12-14T09:05:16+00:00</updated><id>https://amirmasoudabdol.name/feed.xml</id><title type="html">Amir Masoud Abdol’s Personal Website</title><subtitle>JASP Core Developer. Previously, Comp. Psychology PostDoc Tilburg Uni., Comp. Biology PhD UvA</subtitle><entry><title type="html">Apple Notes vs. Hyperlinks</title><link href="https://amirmasoudabdol.name/apple-notes-vs-hyperlinks/" rel="alternate" type="text/html" title="Apple Notes vs. Hyperlinks" /><published>2022-07-11T00:00:00+00:00</published><updated>2022-07-11T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/apple-notes-vs-hyperlinks</id><content type="html" xml:base="https://amirmasoudabdol.name/apple-notes-vs-hyperlinks/">&lt;p&gt;Over the past years, &lt;a href=&quot;https://apple.co/3qy7gqc&quot;&gt;Apple Notes&lt;/a&gt; has transformed from a simple notepad to a full featured note-taking app. It provides a long list of useful features like Formatted Text, Support for Attachments/Photos/Videos, Folders, Smart Folders, Handwritten Notes, Quick Notes, Scribble, Secure Notes, Note Sharing, and Live Collaboration. In iOS 16, Apple Notes will have an improved Secure Notes integration, and the Quick Notes is making its way into the iPhone. Overall, Apple Notes is really starting to be a great app, and after using so many note-taking apps (Drafts, Agenda, GoodNotes, Notability, DEVONthink, Workflowy), I just prefer something simple, and well-integrated just to make simple notes. Apple Notes’ cross-platform support is sublime, the Apple Pencil support and integration is unmatched.&lt;/p&gt;

&lt;p&gt;Unfortunately though, these days, like most Apple software you start to notice inconsistencies and annoying behaviors here and there, e.g., there is no easy way to export your notes from Apple Notes. Unlike Apple Photos where you can simply export or drag/drop a photo out of the app, Apple Notes does not let you do that. Your only option is to export your entire library as a PDF, or use a third-party app which you’ll never know when it stops working.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Apple Notes does not know how to deal with hyperlinks&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Besides the lack of export functionality, one aspect of the app that I am particularly annoyed with is how Apple Notes manages hyperlinks. Apple Notes does not know how to deal with hyperlinks, and its behavior varies across systems and between methods. Here, I have listed the most consistent interactions and behaviors that I have found, but even these may not result in same outcomes based on the page that you are creating link from, or the time of the day I suppose!&lt;/p&gt;

&lt;h2 id=&quot;macos&quot;&gt;macOS&lt;/h2&gt;

&lt;h3 id=&quot;method-1&quot;&gt;Method 1&lt;/h3&gt;

&lt;p&gt;Copying (Cmd + C) a link from Safari’s address bar results in a formatted link with the hyperlink itself being the text, e.g., &lt;a href=&quot;https://support.apple.com/en-us/HT205773&quot;&gt;https://support.apple.com/en-us/HT205773&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You cannot neither change the text, nor the link afterward, at least not trivially. You can edit the text, but if you are not careful you might delete the link itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;method-2&quot;&gt;Method 2&lt;/h3&gt;

&lt;picture&gt;
	&lt;source srcset=&quot;/assets/posts/apple-notes-vs-hyperlinks-macOS-add-link-cmd-k-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
	&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-macOS-add-link-cmd-k-light.png&quot; width=&quot;50%&quot; align=&quot;right&quot; float=&quot;right&quot; /&gt;
&lt;/picture&gt;

&lt;p&gt;By using the “Cmd + K” command on a selected text, you can create your own text and link it to a destination as you can do within most apps.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;After creating a link, you cannot change the text anymore, at least not trivially. You can still change the link itself by using the “Cmd + K” command.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;method-3&quot;&gt;Method 3&lt;/h3&gt;

&lt;p&gt;You can create a rich link object by using the special “Add a link” toolbar button in the Apple Notes app. In this case, Apple Notes tries to guess which page you want to create a link from, and upon the selection, it &lt;strong&gt;appends&lt;/strong&gt; a rich link object to your note.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You cannot interact much with this object. You can only tell it to use the small image instead of the large image, or vice verse.&lt;/li&gt;
  &lt;li&gt;You cannot make a list of these objects.&lt;/li&gt;
  &lt;li&gt;The “Add a link” option is &lt;em&gt;only&lt;/em&gt; available via the toolbar, and it should not be confused by “Add link” shortcut which you can instantiate using “Cmd + K”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Notice&lt;/strong&gt; how Apple Notes picks up some random information from the Yahoo! Finance app, and does not give me the opportunity to see all the open tabs on Safari for instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;picture&gt;
	&lt;source srcset=&quot;/assets/posts/apple-notes-vs-hyperlinks-macOS-add-a-link-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
	&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-macOS-add-a-link-light.png&quot; /&gt;
&lt;/picture&gt;

&lt;h2 id=&quot;ios-and-ipados&quot;&gt;iOS and iPadOS&lt;/h2&gt;

&lt;h3 id=&quot;method-1-1&quot;&gt;Method 1&lt;/h3&gt;

&lt;p&gt;Copying a link from Safari’s address bar results in a formatted link with the hyperlink itself being the text, e.g., &lt;a href=&quot;https://support.apple.com/en-us/HT205773&quot;&gt;https://support.apple.com/en-us/HT205773&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You cannot neither change the text, nor the link; at least not trivially. You can very carefully edit it though.&lt;/li&gt;
  &lt;li&gt;You get the same behavior if you use “Cmd + C” shortcut when using an external keyboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;method-2-1&quot;&gt;Method 2&lt;/h3&gt;

&lt;picture&gt;
	&lt;source srcset=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-copy-dark.PNG&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
	&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-copy-light.PNG&quot; width=&quot;50%&quot; align=&quot;right&quot; float=&quot;right&quot; /&gt;
&lt;/picture&gt;

&lt;p&gt;Copying a link using the “Copy” option of the Shared Menu, &lt;em&gt;most of the times&lt;/em&gt;, results in a link with the page’s header as the text, e.g., &lt;a href=&quot;https://support.apple.com/en-us/HT205773&quot;&gt;Use Notes on your iPhone, iPad, and iPod touch&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you are copying a link to a list, this action will break the list and it creates a new line!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;method-3-1&quot;&gt;Method 3&lt;/h3&gt;

&lt;p&gt;You can create a rich link object by using the Share Menu, and creating a new note, or &lt;strong&gt;appending&lt;/strong&gt; the rich link object to an already existing notes.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Again, you cannot interact with this object much, and all the macOS rules are applied here.&lt;/li&gt;
&lt;/ul&gt;

&lt;picture&gt;
	&lt;source srcset=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-share-to-notes-dark.PNG&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
	&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-share-to-notes-light.PNG&quot; /&gt;
&lt;/picture&gt;

&lt;h2 id=&quot;from-ios-to-macos-and-vice-versa&quot;&gt;From iOS to macOS, and vice versa&lt;/h2&gt;

&lt;p&gt;With Universal Control, it is possible to copy a link from iOS, and bring it to the macOS; however,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you copy a link from the address bar of Safari on macOS and paste it into a note on iOS, you will get the first behavior of the above lists, i.e., a formatted link with the hyperlink itself being the text, e.g., &lt;a href=&quot;https://support.apple.com/en-us/HT205773&quot;&gt;https://support.apple.com/en-us/HT205773&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;If you copy the link using the “Copy” option from the Share Menu on iOS/iPadOS, you again you get the first behavior and not the link with the title.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;possible-solution&quot;&gt;Possible Solution&lt;/h2&gt;

&lt;p&gt;I can imagine that they wanted to keep the Notes app as simple as possible, and they didn’t want to add extra unnecessary features to it; however, here, it feels like that the hyperlink interactions’ have been mostly overlooked. I say it is not about simplicity because Apple Notes has a proper table creation tools which arguably is quite complicated, certainly more than providing a box to rename a text/link.&lt;/p&gt;

&lt;picture&gt;
	&lt;source srcset=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-macOS-formatting-panel-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
	&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-iOS-macOS-formatting-panel-light.png&quot; width=&quot;50%&quot; align=&quot;right&quot; float=&quot;right&quot; /&gt;
&lt;/picture&gt;

&lt;p&gt;On both macOS and iOS, Apple Notes comes with a text formatting option, and text formatting menu; however, there is no option for making or interacting with a link there. Long pressing a rich link object offers you an option to use a small or large image, but not an option to convert the item to a normal link. Similarly, long pressing a “normal” link does not offer you anything, e.g., converting to a rich link object, or pulling the title of the page, or editing the text!&lt;/p&gt;

&lt;p&gt;Apple Notes’ UI is well-suited to deal with these problems and it can offer a consistent behavior but at the moment it does not, and that is frustrating! Maybe we can just have what it has been there for years in Pages, or Mails app, and stop this madness, please!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/apple-notes-vs-hyperlinks-pages-solution.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content><author><name>amirmasoudabdol</name></author><category term="blog" /><category term="iOS" /><category term="iPadOS" /><category term="macOS" /><category term="UI" /><category term="UX" /><summary type="html">Over the past years, Apple Notes has transformed from a simple notepad to a full featured note-taking app. It provides a long list of useful features like Formatted Text, Support for Attachments/Photos/Videos, Folders, Smart Folders, Handwritten Notes, Quick Notes, Scribble, Secure Notes, Note Sharing, and Live Collaboration. In iOS 16, Apple Notes will have an improved Secure Notes integration, and the Quick Notes is making its way into the iPhone. Overall, Apple Notes is really starting to be a great app, and after using so many note-taking apps (Drafts, Agenda, GoodNotes, Notability, DEVONthink, Workflowy), I just prefer something simple, and well-integrated just to make simple notes. Apple Notes’ cross-platform support is sublime, the Apple Pencil support and integration is unmatched.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/posts/apple-notes-vs-hyperlinks-summary-large-image.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/posts/apple-notes-vs-hyperlinks-summary-large-image.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">From qmake to CMake: A Nontrivial Case Study</title><link href="https://amirmasoudabdol.name/qmake-to-cmake/" rel="alternate" type="text/html" title="From qmake to CMake: A Nontrivial Case Study" /><published>2022-05-15T00:00:00+00:00</published><updated>2022-05-15T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/qmake-to-cmake</id><content type="html" xml:base="https://amirmasoudabdol.name/qmake-to-cmake/">&lt;p&gt;In this article, I will walk you through the process of rewriting JASP’s build system from scratch using CMake. It is a long journey of moving the entire build and deployment process from &lt;a href=&quot;https://doc.qt.io/qt-6/qmake-manual.html&quot;&gt;qmake&lt;/a&gt; to &lt;a href=&quot;https://cmake.org&quot;&gt;CMake&lt;/a&gt;. In addition, I will discuss how we have used CMake to work with R framework, and how we have used Conan to manage our dependencies in order to achieve a robust cross-platform, multi-architecture build, and deployment.&lt;/p&gt;

&lt;p&gt;While this writing is very much focused on JASP project, and it might not directly apply to your project, I hope you can find bits and pieces of if helpful when you decide to go through the same process in your project. I should mention that I will not be covering every aspects of the software or the build process equally.&lt;/p&gt;

&lt;h2 id=&quot;about-jasp-and-its-architecture&quot;&gt;About JASP, and Its Architecture&lt;/h2&gt;

&lt;p&gt;JASP is an open-source alternative to SPSS, SAS, and other lookalikes. It is built on top of the Qt Framework, and R. This means that the main body of the app is written in C++, i.e., GUI, Data Management, Engine. In contrast, all the statistical analyses are done in R, and the results are being communicated back to the GUI using JSON objects. JASP modules are specialized R packages consist of R, and some QML codes. The R part is responsible for calculation, and it is being executed in an R instance using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt;, and the QML part is being parsed by JASP to construct an ocean of check boxes&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and controls for the user to interact with!&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt; runs as a separate process alongside JASP, and uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; ≅ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp&lt;/code&gt; to run the R analyses and commands, and ultimately retrieve their results. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; is a library developed by JASP Team. It encapsulates an interface to R, as well as some logic on how the two apps needs to communicate to each other.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I am not intending to describe the entire architecture of JASP. My goal is to provide a high level overview of its architecture and components in order for you to be able to observe its complexity and hopefully find similar situations or solutions to/for your project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;picture&gt;
  &lt;source srcset=&quot;/assets/posts/qmake-to-cmake-jasp-arch-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
  &lt;img src=&quot;/assets/posts/qmake-to-cmake-jasp-arch-light.png&quot; width=&quot;100%&quot; /&gt;
&lt;/picture&gt;

&lt;h3 id=&quot;r-framework-r-packages-and-jasp-modules&quot;&gt;R Framework, R Packages and JASP Modules&lt;/h3&gt;

&lt;p&gt;JASP uses R as its computational back-end. Every command or analysis, one way or another, is being passed to an instance of R (via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt;), and after a successful computation, the results are being communicated back to JASP’s GUI using a JSON object (via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt;). Upon the retrieval of results, JASP processes the results and generates a HTML page, and finally it displays it inside a Chromium WebEngine, i.e., &lt;a href=&quot;https://doc.qt.io/qt-6/qtwebengine-overview.html&quot;&gt;QtWebEngine&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;r-framework&quot;&gt;R Framework&lt;/h4&gt;

&lt;p&gt;On both Windows, and macOS, a copy of R Framework is being embedded into JASP’s binary so that JASP can communicate with R without needing to rely on system’s R, or asking the user to install an instance of R. On Linux, JASP uses Flatpak to manage a local copy of R.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;On Windows&lt;/strong&gt;, the entire R internal is being shipped. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface.dll&lt;/code&gt; links itself against three main libraries (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.dll&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside.dll&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp.dll&lt;/code&gt;) to be able to talk to R, and performs its calculation. One complication that raises here is the fact that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface.dll&lt;/code&gt; needs to be linked against R libraries, and that means that it needs to be compiled with GCC, or MinGW &lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; and linked against the JASP GUI that, in our case, is compiled with MSVC. &lt;del&gt;At the same time, Qt 6 does not like to be compiled using GCC; therefore, we ought to deal with two compilers. Later on, I will explain this problem and discuss how I used CMake toolchains to overcome this issue.&lt;/del&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;On macOS&lt;/strong&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; is being embedded into the Mac App Bundle, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface.dylib&lt;/code&gt; dynamically links against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.dylib&lt;/code&gt; (a.k.a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside.dylib&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp.dylib&lt;/code&gt;.&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both systems, I use CMake to glue everything together, more on this later.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;svg height=&quot;24&quot; class=&quot;octicon octicon-info color-fg-accent&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M13 7.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-3 3.75a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v4.25h.75a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5h.75V12h-.75a.75.75 0 0 1-.75-.75Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;p&gt;I will be using “R Framework” to refer to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R/&lt;/code&gt; folder on Windows, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; on macOS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;r-packages-and-jasp-modules&quot;&gt;R Packages, and JASP Modules&lt;/h4&gt;

&lt;p&gt;R packages that are necessary to the function of JASP needs to be installed inside the R Framework and shipped within the final binary.&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Some of the R packages like &lt;a href=&quot;http://dirk.eddelbuettel.com/code/rinside.html&quot;&gt;RInside&lt;/a&gt; and &lt;a href=&quot;https://www.rcpp.org&quot;&gt;Rcpp&lt;/a&gt; are needed during the build, as they need to be linked against the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; and consequently &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt;; as a results they need to be treated differently. More on this later.&lt;/p&gt;

&lt;p&gt;JASP modules are basically extended R packages with some QML files that are being used by JASP to construct the graphic user interface for each module, i.e., all those controls and checkboxes. In addition, they know how to prepare, and pass their results back to JASP. These modules need to be installed and shipped within the final binary, and they do not necessary need to be available during the build.&lt;/p&gt;

&lt;p&gt;The process of installing both the R packages and JASP modules are being handled by CMake either during the configuration or at the build step, more on this later.&lt;/p&gt;

&lt;h2 id=&quot;qt-5-qmake-and-dependencies&quot;&gt;Qt 5, qmake, and Dependencies&lt;/h2&gt;

&lt;p&gt;Prior to JASP 0.16.2, JASP was based on Qt 5, and it was using qmake as its build system generator. In order to manage the libraries, &lt;a href=&quot;https://github.com/jasp-stats/jasp-required-files&quot;&gt;a pool of pre-built libraries, headers, and frameworks&lt;/a&gt; for every platform and architecture was maintained by the developers, and in every build they were being manually linked to the final binary.&lt;/p&gt;

&lt;p&gt;As we decided to upgrade to Qt 6 and CMake, I set to get rid of the manually maintained pool of libraries and headers. Fortunately, CMake is much better at dealing with third-party libraries than qmake. In addition, I have adapted &lt;a href=&quot;https://conan.io&quot;&gt;Conan&lt;/a&gt; as our package manager to be able to build the dependencies for every target individually.&lt;/p&gt;

&lt;h2 id=&quot;qt6-cmake-and-conan&quot;&gt;Qt6, CMake, and Conan&lt;/h2&gt;

&lt;p&gt;As of Qt 6, CMake is the &lt;a href=&quot;https://www.qt.io/blog/qt-and-cmake-the-past-the-present-and-the-future&quot;&gt;default build system&lt;/a&gt; generator of the Qt Framework. Qt team has started adapting the CMake in their internal processes, and projects and they are continuously improving their CMake toolsets in past years. As Qt 6 is becoming more mature, more and more &lt;a href=&quot;https://doc.qt.io/Qt-6/cmake-commands-qtcore.html&quot;&gt;Qt-specific CMake commands&lt;/a&gt; are being added, and the gap between qmake and CMake is getting smaller.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;svg height=&quot;24&quot; class=&quot;octicon octicon-alert color-fg-attention&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;p&gt;From here onward, I assume that you are familiar with CMake, Qt, and at least have read &lt;a href=&quot;https://doc.qt.io/qt-6/cmake-get-started.html&quot;&gt;this article&lt;/a&gt; and are familiar with basics of CMake.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;cmake-setup&quot;&gt;CMake Setup&lt;/h3&gt;

&lt;p&gt;Now that we are somewhat familiar with the architecture of JASP, and its bits and pieces, let’s start looking into how the project is setup, and what are the tasks that needs to be done.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jasp-desktop/
  ├── CMakeLists.txt
  ├── Common
  │    └── CMakeLists.txt
  ├── R-Interface
  │    └── CMakeLists.txt
  ├── Engine
  │    └── CMakeLists.txt
  ├── Desktop
  │    └── CMakeLists.txt
  ├── Modules/
  ├── Resources/
  ├── Tools
  │    └── CMake
  │        ├── R.cmake
  │        ├── Conan.cmake
  │        ├── Modules.cmake
  │        ├── Programs.cmake
  │        ├── Libraries.cmake
  │        ├── Dependencies.cmake
  │        └── ...
  ├── R &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;R/ or R.framework&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  └── conanfile.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, JASP consists of several sub-projects. In addition to the following four main sub-projects, we have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Modules/&lt;/code&gt; folder that contains the JASP Modules, and finally a generic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resources/&lt;/code&gt; folder.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Common&lt;/strong&gt;, leading to the generation of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libCommon&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;R-Interface&lt;/strong&gt;, which compiles into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Engine&lt;/strong&gt;, which compiles into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASPEngine&lt;/code&gt; executable&lt;/li&gt;
  &lt;li&gt;and &lt;strong&gt;Desktop&lt;/strong&gt;, which is the main GUI of the app, and it mainly consists of Qt codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below you can see some of the main interactions and dependencies between all the entities of the project. I did not go into full length to describe whether the libraries are linked statically or dynamically; however, in general,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;on macOS&lt;/strong&gt; most libraries are linked statically except a few dependencies and Qt itself.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;on Windows&lt;/strong&gt; most libraries are linked dynamically except &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libCommon&lt;/code&gt; and few other exceptions (if I recall correctly)&lt;/li&gt;
&lt;/ul&gt;

&lt;picture&gt;
  &lt;source srcset=&quot;/assets/posts/qmake-to-cmake-jasp-dependencies-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;
  &lt;img src=&quot;/assets/posts/qmake-to-cmake-jasp-dependencies-light.png&quot; width=&quot;100%&quot; /&gt;
&lt;/picture&gt;
&lt;figcaption class=&quot;caption text-small&quot;&gt;JASP&apos;s Dependency Graph&lt;/figcaption&gt;

&lt;h3 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h3&gt;

&lt;p&gt;Before we start plugging things together using CMake, we need to make sure that all our dependencies are ready and available. I categorize the dependencies into 3 main categories,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;R Framework&lt;/li&gt;
  &lt;li&gt;Dependencies that can be managed using Conan&lt;/li&gt;
  &lt;li&gt;and dependencies that needs special care, e.g., &lt;a href=&quot;https://mcmc-jags.sourceforge.io&quot;&gt;JAGS&lt;/a&gt;, &lt;a href=&quot;https://github.com/WizardMac/ReadStat&quot;&gt;ReadStat&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;These are dependencies that do not offer a versatile build script, or cannot be found in Conan’s cellar&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;r-framework-1&quot;&gt;R Framework&lt;/h4&gt;

&lt;p&gt;R Framework is a package consists of libraries, binaries, header files, help files, and anything else that needed for R to function. Its main library is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.dll&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; on macOS) and its main executable is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.exe&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R&lt;/code&gt; on macOS, see &lt;a href=&quot;/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures/&quot;&gt;here&lt;/a&gt; for more on the anatomy of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;). As mentioned, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; and some other libraries in the JASP project will be linking to R Framework; therefore it needs to be available during the build process.&lt;/p&gt;

&lt;p&gt;In order to get the most recent version of the R Framework, and create a reproducible build, we use CMake to identify the architecture of the system, then download the R package, and place it inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/R.cmake&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.cmake&lt;/code&gt;&lt;/a&gt; is a CMake module written to manage this task. Based on the host/target system, it downloads the R package, unpack it, and place it in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt; folder. Additionally, if necessary, it downloads extra dependencies of R, e.g., Tk/Tcl, FORTRAN; and add them to the final package. Furthermore, it sets some of the R related parameters of the project.&lt;/p&gt;

&lt;h5 id=&quot;on-macos&quot;&gt;On macOS&lt;/h5&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/7c8c2a91fc914bc3a1c3b998611517d2fe0bdaf6/Tools/CMake/R.cmake#L98&quot;&gt;On macOS&lt;/a&gt;, a few key points needs to be dealt with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Setting path parameters&lt;/li&gt;
  &lt;li&gt;Downloading the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; based on the host system.&lt;/li&gt;
  &lt;li&gt;Downloading the corresponding FORTRAN compiler on the host system.&lt;/li&gt;
  &lt;li&gt;Unpacking everything, and moving them into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt; folder.&lt;/li&gt;
  &lt;li&gt;Patching the libraries, and resigning them using the Apple Developer Certificate&lt;/li&gt;
  &lt;li&gt;Downloading and installation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp&lt;/code&gt; inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; for later usage, and linking. Read more &lt;a href=&quot;/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures/&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setting parameters:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_FRAMEWORK_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Frameworks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_HOME_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_FRAMEWORK_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/R.framework/Versions/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_DIR_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Resources&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_LIBRARY_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/library&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_OPT_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/opt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_EXECUTABLE &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/R&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R_INCLUDE_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/include&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;RCPP_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Rcpp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;RINSIDE_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/RInside&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Declaring the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FetchContent&lt;/code&gt; object for downloading the R Framework:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;fetchcontent_declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  r_pkg
  URL &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_DOWNLOAD_URL&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  URL_HASH SHA1=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_PACKAGE_HASH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  DOWNLOAD_NO_EXTRACT ON
  DOWNLOAD_NAME &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_PACKAGE_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unpacking and moving the R.framework to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_pkg_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND tar -xf tcltk.pkg/Payload -C &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_pkg_r_home&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_pkg_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND tar -xf texinfo.pkg/Payload -C &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_pkg_r_home&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;make_directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/Frameworks&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_pkg_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND cp -Rpf R.framework &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/Frameworks&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Installing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp&lt;/code&gt; inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WRITE &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MODULES_RENV_ROOT_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/install-RInside.R
  &lt;span class=&quot;s2&quot;&gt;&quot;install.packages(c(&apos;RInside&apos;, &apos;Rcpp&apos;), type=&apos;binary&apos;, repos=&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_REPOSITORY&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;, INSTALL_opts=&apos;--no-multiarch --no-docs --no-test-load&apos;)&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  ERROR_QUIET OUTPUT_QUIET
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_EXECUTABLE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --slave --no-restore --no-save
          --file=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MODULES_RENV_ROOT_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/install-RInside.R&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;on-windows&quot;&gt;On Windows&lt;/h5&gt;

&lt;p&gt;Similarly, &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/7c8c2a91fc914bc3a1c3b998611517d2fe0bdaf6/Tools/CMake/R.cmake#L526&quot;&gt;on Windows&lt;/a&gt;, we need to download the R package, unpack it and place it inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt; folder, and finally we need to install the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp&lt;/code&gt; inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/R&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Downloading, unpacking and moving the R package to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;fetchcontent_declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  r_win_exe
  URL &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_DOWNLOAD_URL&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  URL_HASH SHA1=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_PACKAGE_HASH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  DOWNLOAD_NO_EXTRACT ON
  DOWNLOAD_NAME &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_PACKAGE_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_win_exe_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_PACKAGE_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; /CURRENTUSER /verysilent /sp
          /DIR=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_win_exe_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;COPY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;r_win_exe_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R DESTINATION &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Installing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp&lt;/code&gt; inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R/&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WRITE &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MODULES_RENV_ROOT_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/install-RInside.R
  &lt;span class=&quot;s2&quot;&gt;&quot;install.packages(c(&apos;RInside&apos;, &apos;Rcpp&apos;), type=&apos;binary&apos;, repos=&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_REPOSITORY&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;USE_LOCAL_R_LIBS_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, INSTALL_opts=&apos;--no-multiarch --no-docs --no-test-load&apos;)&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  ERROR_QUIET OUTPUT_QUIET
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_BIN_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_EXECUTABLE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --slave --no-restore --no-save
      --file=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MODULES_RENV_ROOT_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/install-RInside.R&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;svg height=&quot;24&quot; class=&quot;octicon octicon-alert color-fg-attention&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;p&gt;I am omitting a lot of details here; especially when it comes to how R packages installation works. As far as CMake concerns, you need to execute a process to call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${R_EXECUTABLE}&lt;/code&gt; and make sure that it can install your requested package.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5 id=&quot;on-linux&quot;&gt;On Linux&lt;/h5&gt;

&lt;p&gt;On Linux, since JASP uses Flatpak, we can rely on system’s R; therefore we only need to located the R libraries, and set some paths for later usage, so that we can link everything and use the headers when needed.&lt;/p&gt;

&lt;h4 id=&quot;conan&quot;&gt;Conan&lt;/h4&gt;

&lt;p&gt;Now that we have the R Framework ready to be used, and linked against. We need to deal with the rest of dependencies. Except a few libraries, all JASP dependencies can be found in ConanCenter, and therefore can simply be defined inside a &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/conanfile.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.txt&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[requires]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;boost/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.78.0&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;libiconv/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.16&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;libarchive/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.5.2&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;zlib/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.2.11&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;zstd/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.5.2&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;jsoncpp/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.9.5&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;openssl/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1.1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;m&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;bison/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.7.6&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;brotli/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0.9&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[generators]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;cmake_paths&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;cmake_find_package&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[options]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;brotli:shared&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While most of the time, running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan install ..&lt;/code&gt; inside the build directly is enough for setting up the libraries, we need to make sure that we can handle different architectures, especially on macOS where you can (need to) build both for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A savvy Conan user can often run the appropriate commands and set up the right environment, however, that’s not always straightforward; therefore, I decided to delegate this task to a CMake module, &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/Conan.cmake&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Conan.cmake&lt;/code&gt;&lt;/a&gt;. Here, based on the architecture, build type, and target properties’, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Conan.cmake&lt;/code&gt; decides what Conan command should be used:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;WIN32&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;STATUS &lt;span class=&quot;s2&quot;&gt;&quot;  &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_COMPILER_RUNTIME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    COMMAND_ECHO STDOUT
    WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    COMMAND
      conan install &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_FILE_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s build_type=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s
      compiler.runtime=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_COMPILER_RUNTIME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --build=missing&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;elseif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPLE&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CROSS_COMPILING&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      COMMAND_ECHO STDOUT
      WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
      COMMAND
        conan install &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_FILE_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s build_type=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s
        os.version=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_DEPLOYMENT_TARGET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s os.sdk=macosx -s
        arch=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_ARCH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s arch_build=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_ARCH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --build=missing&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;nb&quot;&gt;execute_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      COMMAND_ECHO STDOUT
      WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
      COMMAND
        conan install &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONAN_FILE_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s build_type=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s
        os.version=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_DEPLOYMENT_TARGET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -s os.sdk=macosx
        --build=missing&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Integrating Conan is often as simple as this. If you make sure that you are selecting the right libraries, and setting the right flags for your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan install ..&lt;/code&gt;, you can simply use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find_package&lt;/code&gt; command to link your Conan libraries to your project.&lt;/p&gt;

&lt;p&gt;Notice that I have used two generators in the Conan file, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake_paths&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake_find_package&lt;/code&gt;. This is because some of those libraries are not properly set up to work with CMake projects, and therefore I need to use Conan environment variables to tap into their header or libraries folders. In addition, as we see later on during the Windows build, I needed a more fine-grained control over which libraries to select, so this was necessary.&lt;/p&gt;

&lt;h4 id=&quot;miscproblematic-libraries&quot;&gt;Misc./Problematic Libraries&lt;/h4&gt;

&lt;p&gt;One of the problematic libraries that we had to deal with was ReadStat. ReadStat neither has support for CMake, nor (a proper) PkgConfig setup. This makes it challenging to integrate into a project, especially because we had to make sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libreadstat&lt;/code&gt; is build correctly for our selected host and target. Therefore, we had to dive deeper into its native build system, and make sure that appropriate parameters are set.&lt;/p&gt;

&lt;p&gt;As you can see below, based on the system and CMake configurations, we instruct the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoconf&lt;/code&gt; to configure the ReadStat’s Makefile accordingly. &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/Dependencies.cmake&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependencies.cmake&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;READSTAT_CFLAGS
    &lt;span class=&quot;s2&quot;&gt;&quot;-g -O2 -arch &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_ARCHITECTURES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; -mmacosx-version-min=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_DEPLOYMENT_TARGET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;READSTAT_EXTRA_FLAGS_1 &lt;span class=&quot;s2&quot;&gt;&quot;--with-sysroot=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_SYSROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;READSTAT_EXTRA_FLAGS_2 &lt;span class=&quot;s2&quot;&gt;&quot;--target=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONFIGURE_HOST_FLAG&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;READSTAT_CXXFLAGS &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_CFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_custom_command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  OUTPUT &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include/readstat.h
         &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/lib/libreadstat.a
  COMMAND
    export CFLAGS=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_CFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &amp;amp;&amp;amp; export CXXFLAGS=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_CXXFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &amp;amp;&amp;amp; ./configure --enable-static --prefix=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iconv_FLAGS_FOR_READSTAT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_EXTRA_FLAGS_1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_EXTRA_FLAGS_2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAKE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAKE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; install
  COMMENT &lt;span class=&quot;s2&quot;&gt;&quot;----- Preparing &apos;readstat&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_custom_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;readstat
                  DEPENDS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include/readstat.h&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;LIBREADSTAT_INCLUDE_DIRS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;LIBREADSTAT_LIBRARY_DIRS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readstat_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/lib&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;LIBREADSTAT_LIBRARIES &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LIBREADSTAT_LIBRARY_DIRS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/libreadstat.a&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Similar situation raised when we started dealing with JAGS. With JAGS, on macOS, we had to provide an appropriate FORTRAN compiler as well, and make sure that the FORTRAN compiler as well is aware of the environment variables. We went to this length to make sure that our build is consistent and we can cross-compile our software for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;. &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/7c8c2a91fc914bc3a1c3b998611517d2fe0bdaf6/Tools/CMake/Modules.cmake#L457&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Modules.cmake&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;fetchcontent_declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  jags
  URL &lt;span class=&quot;s2&quot;&gt;&quot;https://sourceforge.net/projects/mcmc-jags/files/JAGS/4.x/Source/JAGS-4.3.0.tar.gz&quot;&lt;/span&gt;
  URL_HASH
    SHA256=8ac5dd57982bfd7d5f0ee384499d62f3e0bb35b5f1660feb368545f1186371fc
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CHECK_START &lt;span class=&quot;s2&quot;&gt;&quot;Downloading &apos;jags&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;fetchcontent_makeavailable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;jags&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;jags_POPULATED&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CHECK_PASS &lt;span class=&quot;s2&quot;&gt;&quot;successful.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JAGS_F77_FLAG &lt;span class=&quot;s2&quot;&gt;&quot;F77=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FORTRAN_EXECUTABLE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JAGS_CFLAGS
      &lt;span class=&quot;s2&quot;&gt;&quot;-g -O2 -arch &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_ARCHITECTURES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; -mmacosx-version-min=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_DEPLOYMENT_TARGET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JAGS_EXTRA_FLAGS_1 &lt;span class=&quot;s2&quot;&gt;&quot;--with-sysroot=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OSX_SYSROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JAGS_EXTRA_FLAGS_2 &lt;span class=&quot;s2&quot;&gt;&quot;--target=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONFIGURE_HOST_FLAG&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JAGS_CXXFLAGS &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JAGS_CFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;add_custom_command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    JOB_POOL sequential
    WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;jags_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    OUTPUT &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;jags_VERSION_H_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    COMMAND
      export CFLAGS=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_CFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &amp;amp;&amp;amp; export
      CXXFLAGS=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;READSTAT_CXXFLAGS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JAGS_F77_FLAG&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; ./configure
      --disable-dependency-tracking --prefix=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;jags_HOME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JAGS_EXTRA_FLAGS_1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JAGS_EXTRA_FLAGS_2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAKE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAKE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; install
    COMMAND
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_COMMAND&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D
      NAME_TOOL_PREFIX_PATCHER=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PROJECT_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/Tools/macOS/install_name_prefix_tool.sh
      -D PATH=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;jags_HOME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D R_HOME_PATH=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D
      R_DIR_NAME=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_DIR_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D
      SIGNING_IDENTITY=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APPLE_CODESIGN_IDENTITY&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D
      SIGNING=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;IS_SIGNING&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -D
      CODESIGN_TIMESTAMP_FLAG=&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CODESIGN_TIMESTAMP_FLAG&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -P
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PROJECT_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/Tools/CMake/Patch.cmake
    COMMENT &lt;span class=&quot;s2&quot;&gt;&quot;----- Preparing &apos;jags&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;svg height=&quot;24&quot; class=&quot;octicon octicon-zap color-fg-done&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M15.716 1.329a1.341 1.341 0 0 1 2.109 1.55L15.147 9h4.161c1.623 0 2.372 2.016 1.143 3.075L8.102 22.721a1.148 1.148 0 0 1-1.81-1.317L8.996 15H4.674c-1.619 0-2.37-2.008-1.148-3.07l12.19-10.6Zm.452 1.595L4.51 13.061a.25.25 0 0 0 .164.439h5.45a.749.749 0 0 1 .692 1.041l-2.559 6.066 11.215-9.668a.25.25 0 0 0-.164-.439H14a.75.75 0 0 1-.687-1.05Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;p&gt;R is very particular about the FORTRAN compiler, and it uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran 8&lt;/code&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; architecture, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran 12&lt;/code&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt; architecture. To overcome this complication, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.cmake&lt;/code&gt; downloads the right FORTRAN, places it inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, and makes sure that R toolchain can find and use it. On Windows, things are simpler as Rtools42 bundles everything R needs into a MSYS environment, and we can just use that instead. Also, the ARM Windows is not yet a thing!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;managing-the-cmake-project&quot;&gt;Managing the CMake Project&lt;/h3&gt;

&lt;p&gt;Now that we have all our dependencies ready, let’s talk CMake project management. As shown below, we start by building each library separately using its own dedicated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; configuration file.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jasp-desktop/
  ├── CMakeLists.txt
  ├── Common
  │    └── CMakeLists.txt
  ├── R-Interface
  │    └── CMakeLists.txt
  ├── Engine
  │    └── CMakeLists.txt
  ├── Desktop
  │    └── CMakeLists.txt
  ├── Modules/
  ├── Resources/
  ├── Tools
  │    └── CMake
  │        ├── R.cmake
  │        ├── Conan.cmake
  │        ├── Modules.cmake
  │        ├── Programs.cmake
  │        ├── Libraries.cmake
  │        ├── Dependencies.cmake
  │        └── ...
  ├── R &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;R/ or R.framework&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  └── conanfile.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The top level &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/CMakeLists.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;&lt;/a&gt; file starts with the project definition, and system variable detection routines, e.g., arch, build type. Besides that it mainly consists of several &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/include.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/add_subdirectory.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_subdirectory&lt;/code&gt;&lt;/a&gt; commands loading various aspects of the project as you can see in the simplified version of the file below.&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# CMake Modules&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;###############&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Config&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Conan&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Programs&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Libraries&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Dependencies&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Sub Directories / Projects&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;############################&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Common&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;NOT WIN32&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R-Interface&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;add_custom_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    R-Interface
    WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface
    BYPRODUCTS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface/libR-Interface.dll
               &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface/libR-Interface.dll.a
    COMMAND
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_COMMAND&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -G &lt;span class=&quot;s2&quot;&gt;&quot;MinGW Makefiles&quot;&lt;/span&gt; -S . -B
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface &lt;span class=&quot;s2&quot;&gt;&quot;-DMINGW_PATH:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_C_COMPILER:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_C_COMPILER&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_CXX_COMPILER:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_CXX_COMPILER&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_MAKE_PROGRAM:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_MAKE_PROGRAM&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DJASP_BINARY_DIR:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_BUILD_TYPE:STRING=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_COMMAND&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --build &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface
    COMMENT &lt;span class=&quot;s2&quot;&gt;&quot;------ Configuring and Building the libR-Interface&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Engine&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Desktop&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Modules&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Installation and Packing&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;##########################&lt;/span&gt;
 
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Install&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;NOT LINUX&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Pack&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The first part, &lt;strong&gt;CMake Modules&lt;/strong&gt;, makes sure that dependencies are downloaded, prepared and if needed built on the &lt;em&gt;host system for the target system&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;The second part, &lt;strong&gt;Sub Directories / Projects&lt;/strong&gt;, loads every sub project one by one and run their dedicated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; and upon successful execution prepares the corresponding library or executable for the next subproject, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libCommon&lt;/code&gt; is needed for successful creation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt;. In addition, the &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/Modules.cmake&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Modules&lt;/code&gt;&lt;/a&gt; CMake module installs all the JASP Modules.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Common/CMakeLists.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Common/CMakeLists.txt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/R-Interface/CMakeLists.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-Interface/CMakeLists.txt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Engine/CMakeLists.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Engine/CMakeLists.txt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Desktop/CMakeLists.txt&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Desktop/CMakeLists.txt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The third part, &lt;strong&gt;Installation and Packing&lt;/strong&gt;, mocks the install process, deploys the project and prepares the it for the creation of the &lt;a href=&quot;https://wixtoolset.org&quot;&gt;WIX Installer&lt;/a&gt; or an &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html&quot;&gt;App Bundle&lt;/a&gt; on macOS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know the basic of CMake, you can see that nothing mysterious is happening in those &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; files; except maybe how some of those dependencies have been handled. There, I have utilized the &lt;a href=&quot;https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake-generator-expressions&lt;/code&gt;&lt;/a&gt; to link the appropriate libraries based on what is available where on different systems and/or different configurations. E.g., you can see below that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&amp;lt;$&amp;lt;BOOL:${USE_CONAN}&amp;gt;:jsoncpp::jsoncpp&amp;gt;&lt;/code&gt; instructs CMake to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jsoncpp::jsoncpp&lt;/code&gt; target if Conan has been used, i.e., on Windows and macOS; however, on Linux where we rely on system libraries, we use PkgConfig’s variables to access the header files, and link to libraries, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&amp;lt;$&amp;lt;PLATFORM_ID:Linux&amp;gt;:${_PKGCONFIG_LIB_JSONCPP_INCLUDEDIR}&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;target_include_directories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  Common
  PUBLIC &lt;span class=&quot;c1&quot;&gt;# JASP&lt;/span&gt;
         jaspColumnEncoder
         &lt;span class=&quot;c1&quot;&gt;# R&lt;/span&gt;
         &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_INCLUDE_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include
         &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;RCPP_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include
         &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
         $&amp;lt;$&amp;lt;PLATFORM_ID:Linux&amp;gt;:&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_PKGCONFIG_LIB_JSONCPP_INCLUDEDIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&amp;gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  Common
  PUBLIC &lt;span class=&quot;c1&quot;&gt;# jsoncpp&lt;/span&gt;
         $&amp;lt;$&amp;lt;BOOL:&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;USE_CONAN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&amp;gt;:jsoncpp::jsoncpp&amp;gt;
         $&amp;lt;$&amp;lt;PLATFORM_ID:Linux&amp;gt;:&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_PKGCONFIG_LIB_JSONCPP_LIBRARIES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&amp;gt;
         $&amp;lt;$&amp;lt;PLATFORM_ID:Linux&amp;gt;:&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_PKGCONFIG_LIB_JSONCPP_LINK_LIBRARIES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&amp;gt;
         &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
         LibArchive::LibArchive
         &lt;span class=&quot;c1&quot;&gt;# Boost&lt;/span&gt;
         Boost::filesystem
         Boost::system
         Boost::date_time
         Boost::timer
         Boost::chrono
         &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
         $&amp;lt;$&amp;lt;BOOL:&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_USES_QT_HERE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&amp;gt;:Qt::Core&amp;gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;building-r-interface-on-windows-rtools42-and-other-considerations-for-windows&quot;&gt;Building R-Interface on Windows, Rtools42, and Other Considerations for Windows&lt;/h4&gt;

&lt;p&gt;As briefly discussed, building &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; on Windows is not a trivial task. This is due to the fact that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; needs to be linked against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.dll&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RInside.dll&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rcpp.dll&lt;/code&gt;. In addition, by adding their headers to the project, we trigger their preprocessors which are going to stop us from compiling if we are not compiling against a GCC-compatible compiler.&lt;/p&gt;

&lt;p&gt;As a result, we need to build the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; differently (using GCC) and link it dynamically against our other libraries and executable. Fortunately, or unfortunately, R team maintains their own MSYS system. This allows us to use GCC friendly compilers on Windows and build the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-Interface.dll&lt;/code&gt; there and finally links it against the JASP executable (+ Qt6) which is going to be built using MSVC.&lt;/p&gt;

&lt;p&gt;In order to do this dance, we use the following code in the top-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;NOT WIN32&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;R-Interface&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;add_custom_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    R-Interface
    WORKING_DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface
    BYPRODUCTS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface/libR-Interface.dll
               &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface/libR-Interface.dll.a
    COMMAND
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_COMMAND&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -G &lt;span class=&quot;s2&quot;&gt;&quot;MinGW Makefiles&quot;&lt;/span&gt; -S . -B
      &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface &lt;span class=&quot;s2&quot;&gt;&quot;-DMINGW_PATH:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_PATH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_C_COMPILER:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_C_COMPILER&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_CXX_COMPILER:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_CXX_COMPILER&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_MAKE_PROGRAM:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MINGW_MAKE_PROGRAM&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DJASP_BINARY_DIR:PATH=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_BUILD_TYPE:STRING=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_COMMAND&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --build &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/R-Interface
    COMMENT &lt;span class=&quot;s2&quot;&gt;&quot;------ Configuring and Building the libR-Interface&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we tap out of our main CMake build process, and start a new process based on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-Interface/CMakeLists.txt&lt;/code&gt; which itself is constructed such that it behaves as a standalone CMake projects on Windows, see below. By asking the CMake to construct a “MinGW Makefiles”, and setting all the necessary paths to MINGW’s C and C++ compiler, we initiate the configuration and build process of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-Interface&lt;/code&gt; project from our main CMake project. If the build is successful, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/R-Interface&lt;/code&gt; will contains the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface.dll&lt;/code&gt; and it is ready to be used by the rest of the project.&lt;/p&gt;

&lt;p&gt;Note that in the snippet above we are passing several of our local variables to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${CMAKE_COMMAND}&lt;/code&gt; when we are initiating the config/build of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt;. This is because when you are taping out of the main CMake process, the new process does not have access to your local variable anymore and you need to provide them to the other project manually, or using a template file.&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;WIN32&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;QT_CREATOR_SKIP_CONAN_SETUP ON&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 3.21&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    R-Interface
    VERSION 11.5.0.0
    LANGUAGES C CXX&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND CMAKE_MODULE_PATH &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/../Tools/CMake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# More CMake commands for building the R-Interface&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Building for macOS, and Linux without defining a new projects&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is worth noting that there is a lot of detailed involved in here, and if you are interested you should study the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R-Interface/CMakeLists.txt&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Programs.Cmake&lt;/code&gt; and the main &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; file. One of the complication that we faced was the fact that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface.dll&lt;/code&gt; needs to be linked against Boost, and it could not be linked against the Boost that was already prepared by Conan for the main project using MSVC. Instead, it needed to be linked against a Boost that is build inside the MSYS (i.e., Rtools42) environment. Therefore, we had to make sure that Boost (and jsoncpp) is available inside the MSYS system. Since Rtools42 is a full-featured MSYS environment, we can achieve this by installing those packages using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pacman&lt;/code&gt;. After that, we only had to make sure that a copy of all those libraries sit next to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP&lt;/code&gt; executable because Windows. So, some manual (via CMake’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file&lt;/code&gt; command) copy/paste of libraries were needed.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;svg height=&quot;24&quot; class=&quot;octicon octicon-alert color-fg-attention&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;p&gt;I have mentioned Rtools42, but at the time that we implemented this method, R 4.0 was not released yet. Therefore, we had to use the combination of Rtool35 and MSYS to achieve a complete build. Most links to CMake files in this article are pointing to &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/tree/v0.16.2&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/0.16.2&lt;/code&gt;&lt;/a&gt;. If you are interested on how Rtools42 has simplified this process, you can study this pull request, &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/pull/4763&quot;&gt;Support for R-4.2.0&lt;/a&gt;. In this RP, I have replaced the MSYS environment with Rtools42. (The PR is closed, however, it is content is merged into this &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/pull/4801&quot;&gt;pull request&lt;/a&gt;.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;build&quot;&gt;Build&lt;/h3&gt;

&lt;p&gt;Now that all our dependencies, libraries, and packages ready, we should be able to simply run the CMake command, and compile everything. I am not going to go into details on how to initiate the build, and I assume that you are familiar with the following sequence, or, you are going to open the project in Qt Creator, and rely on its integration! 🤞🏼&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir build &amp;amp;&amp;amp; cd build
cmake .. -GNinja -DCMAKE_PREFIX_PATH=&amp;lt;path-to-qt&amp;gt;
ninja
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;installation-and-deployment&quot;&gt;Installation and Deployment&lt;/h3&gt;

&lt;p&gt;The one last thing to do is to deploy the project. I will not go into details of the deployment, rather I mention a few common issues or obstechales that we had to deal with, and leave you with a link to &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/Install.cmake&quot;&gt;Install&lt;/a&gt; and &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/v0.16.2/Tools/CMake/Pack.cmake&quot;&gt;Pack&lt;/a&gt; modules.&lt;/p&gt;

&lt;p&gt;Deployment of Qt projects are done using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;macdeployqt&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;windeployqt&lt;/code&gt;. Unfortunately, neither of these tools are robust enough to do everything and you will end up having to do several things manually. &lt;a href=&quot;https://cmake.org/cmake/help/latest/module/CPack.html&quot;&gt;CPack&lt;/a&gt; is designed to help you with the deployment of your project; however, to take advantages of the CPack, you must have a very standard project tree, libraries, and dependencies. In our case, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; and exceptions around the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR-Interface&lt;/code&gt; did not allow us to use CPack successfully.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;On macOS&lt;/strong&gt;, CPack can construct a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.app&lt;/code&gt; bundle form your project; however, you have a slim chance of getting this to work if you are using an external Framework, in our case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;On Windows&lt;/strong&gt;, we have already had a WIX template and we still ran into problem due to the complication caused by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R/&lt;/code&gt; and some of the modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both system, our approach was to stage the installation and fully deploy the project, and all its libraries inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Install/&lt;/code&gt; folder, and pass everything to WIX on Windows, and on macOS put everything precisely where they need to be according to &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1&quot;&gt;Apple’s Bundle Structure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/install.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install&lt;/code&gt;&lt;/a&gt; command is your friend. Set up your project structure, and handle as much as your installation logic using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install&lt;/code&gt; command, e.g.,&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;MACOS_BUNDLE_NAME JASP&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_PREFIX &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MACOS_BUNDLE_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.app&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_BINDIR &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Contents/MacOS&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_RESOURCEDIR &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Contents/Resources&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_FRAMEWORKDIR &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Contents/Frameworks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_MODULEDIR &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Contents/Modules&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;JASP_INSTALL_DOCDIR &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_RESOURCEDIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  TARGETS JASP JASPEngine
  RUNTIME DESTINATION &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_BINDIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  BUNDLE DESTINATION .&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  DIRECTORY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_R_Framework&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  DESTINATION &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JASP_INSTALL_FRAMEWORKDIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  REGEX &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FILES_EXCLUDE_PATTERN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; EXCLUDE
  REGEX &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FOLDERS_EXCLUDE_PATTERN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; EXCLUDE
  REGEX &lt;span class=&quot;s2&quot;&gt;&quot;.*/bin/R(Script)?$&quot;&lt;/span&gt; EXCLUDE
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;-caveats&quot;&gt;&lt;svg height=&quot;24&quot; class=&quot;octicon octicon-alert color-fg-danger&quot; viewBox=&quot;0 0 24 24&quot; version=&quot;1.1&quot; width=&quot;24&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Caveats&lt;/h3&gt;

&lt;p&gt;As mentioned before, due to the requirements of JASP project, we had to deal with several type of dependencies. Some managed by Conan, others fetched using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FetchContent&lt;/code&gt;, and the rest were downloaded directly from their repository. I have to emphasize that this is not an ideal scenario, and you should avoid it if you can. You should try to manage all your dependencies with one dependency manager. In our case, we could have improved our setup by writing a Conan recipe for ReadStat, and let Conan handle its build as well. However, we could have not moved everything to Conan, e.g., R Framework and JAGS (due to its FORTRAN dependency).&lt;/p&gt;

&lt;p&gt;Additionally, I should reiterate the fact that, &lt;em&gt;ideally&lt;/em&gt; you should not interact with Conan within your CMake files, and educate your team to use Conan command line instead. However, in our case, due to time pressure and because the team was not familiar with Conan, I decided to manage some of the Conan parameters with CMake. This is not ideal because you risk replying on deprecated Conan features’ as Conan evolves.&lt;sup id=&quot;fnref:7&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:7&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; In our case, I have made a note/task of this fact and encouraged the team to deprecate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Conan.cmake&lt;/code&gt; module, study Conan, and setup their environment manually for each build.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;CMake offers a lot more freedom compared to qmake. I am aware that CMake is not everyone’s cup of tea and many people do not like it. However, I feel if you have tried CMake before and had similar experience, you need to give it another try. A lot has changed from early days, and large and complicated projects like Qt or KDE heavily rely on it. In Modern CMake&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;, you have much more control over your targets, and libraries. CPack, although not perfect, can facilitate your deployment greatly if you have a relatively standard project. Finally, dependency managers like Conan are improving the CMake integration every day, and can generate CMake config files for packages that do not come with CMake support of the box.&lt;sup id=&quot;fnref:6&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;I should also reiterate that most of what I have discussed might not directly apply to your project; however, I hope this could come handy if you are trying to resolve some of your build system issues’, or rewriting it from scratch because you want to move away from qmake to CMake. Or at very least, I hope it gives you an idea on how far you can get with CMake when it comes to a rather complicated and irregular project, which is about every C/C++ project out there! 😅&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. I was expecting this article to become long, but not this long! Feel free to reach out on &lt;a href=&quot;https://twitter.com/amirmasoudabdol&quot;&gt;Twitter&lt;/a&gt;, or &lt;a href=&quot;cpplang.slack.com&quot;&gt;Cpplang Slack&lt;/a&gt; where I occasionally spend some time, and try to learn from very knowledgeable members of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#conan&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#cmake&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#qt&lt;/code&gt; channels!&lt;/em&gt; 🙏🏼&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://smallstep.com/blog/if-openssl-were-a-gui/&quot;&gt;If OpenSSL were a GUI&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.r-project.org/about.html&quot;&gt;R&lt;/a&gt; is a &lt;a href=&quot;http://www.gnu.org&quot;&gt;GNU Project&lt;/a&gt; and therefore it can only be compiled using the &lt;a href=&quot;https://gcc.gnu.org&quot;&gt;GNU GCC&lt;/a&gt; compiler. This means, anything that needs to be linked directly to R libraries needs to use a GCC-compatible compiler. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I have already covered the complicated and cumbersome process of successfully &lt;a href=&quot;/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures/&quot;&gt;embedding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; into the app bundle&lt;/a&gt;, as well as the process of signing and notarizing the app bundle for distribution. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Most of the R packages are being installed via &lt;a href=&quot;https://rstudio.github.io/renv/articles/renv.html&quot;&gt;Renv&lt;/a&gt;. &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:7&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://docs.conan.io/en/latest/conan_v2.html&quot;&gt;Conan 2.0&lt;/a&gt; &lt;a href=&quot;#fnref:7&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I highly recommend &lt;a href=&quot;https://crascit.com/professional-cmake/&quot;&gt;Professional CMake: A Practical Guide&lt;/a&gt; book by Craig Scott. I personally have learned a lot from it. You can often find him answering some question on &lt;a href=&quot;https://discourse.cmake.org&quot;&gt;CMake Discourse&lt;/a&gt; as well. &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:6&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The quality of the config file you get out of Conan depends on the quality of the Conan script but in general, chances are high that you get a good, and working config file, so that you can simply use the target, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jsoncpp::jsoncpp&lt;/code&gt;. &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>amirmasoudabdol</name></author><category term="blog" /><category term="CMake" /><category term="Qt6" /><category term="QtDev" /><category term="C" /><category term="Cpp" /><category term="qmake" /><category term="R" /><category term="Rstats" /><summary type="html">In this article, I will walk you through the process of rewriting JASP’s build system from scratch using CMake. It is a long journey of moving the entire build and deployment process from qmake to CMake. In addition, I will discuss how we have used CMake to work with R framework, and how we have used Conan to manage our dependencies in order to achieve a robust cross-platform, multi-architecture build, and deployment.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/posts/qmake-to-cmake-twitter-summary-card.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/posts/qmake-to-cmake-twitter-summary-card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Embedding R.framework in a Qt Mac App, and Cross Compiling for Two Architectures</title><link href="https://amirmasoudabdol.name/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures/" rel="alternate" type="text/html" title="Embedding R.framework in a Qt Mac App, and Cross Compiling for Two Architectures" /><published>2022-04-18T00:00:00+00:00</published><updated>2022-04-18T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures</id><content type="html" xml:base="https://amirmasoudabdol.name/embedding-rframework-in-a-qt-mac-app-and-cross-compiling-for-two-architectures/">&lt;picture&gt;&lt;source srcset=&quot;/assets/posts/embedding-r-framework-dark.png&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;&lt;img src=&quot;/assets/posts/embedding-r-framework-light.png&quot; width=&quot;50%&quot; align=&quot;right&quot; float=&quot;right&quot; /&gt;&lt;/picture&gt;
&lt;p&gt;Developing for Apple platform &lt;em&gt;can be&lt;/em&gt; fun if your app lives solely inside Xcode, and you only utilize standard libraries, or don’t interact with any alien libraries or frameworks. In that case, there is a high chance that you have never been worried about compatibility issues, linking problems, signing struggles and the notarization&lt;em&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, if your software is built on top of a different GUI framework rather than UIKit, e.g., Qt Framework, and you need all sort of other libraries; then you are familiar with the pain of getting them to know each other, link together properly, and build into one coherent piece of software. Finally, you are going to prepare your App Bundle, sign it, and send it to Apple for notarization and start praying! Now, add the &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;&lt;/strong&gt; or any other non-standard framework to the mix, and you are very close to the definition of nightmare.&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;JASP is one of these software, where in addition to embedding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, we include series of R packages and Modules. Some can be downloaded as binaries from CRAN, some need compilation, and some needs third-party libraries, e.g. &lt;a href=&quot;https://sourceforge.net/projects/mcmc-jags/&quot;&gt;JAGS&lt;/a&gt;. Now, add to all that the fact that we need to do all that for two architectures, i.e., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt;, and three platforms.&lt;/p&gt;

&lt;p&gt;In this article, I go through some of the challenges that we had to overcome to get all this to working in a stable manner on macOS. Most of the heavy-lifting of the build system is being taken care of by CMake which is not discussed here; instead, in this post I focus on preparing and embedding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;rframework&quot;&gt;R.framework&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; is inherently not portable. This means the entire Framework is built with hardcoded paths. It expects to be installed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/R.framework&lt;/code&gt;, and every other libraries and packages expect it to be there so that they can link to the R libraries and therefore function correctly. Placing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; to any other location on your system is merely asking for trouble. One of the biggest consequences of installing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; in a non-standard place is that none of the CRAN binary packages can navigate their ways to R’s home directory, consequently they cannot find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; and therefore they won’t work.&lt;/p&gt;

&lt;p&gt;For us, this is a big issue as we need to embed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; to our app such that it can sit and function inside the &lt;strong&gt;JASP.app&lt;/strong&gt; and work in our user’s system. In addition, we need to download several pre-build R packages from CRAN and inform them about the whereabouts of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt;. Finally, we need to make sure that JASP modules can be built on our build machines and work inside our app bundle.&lt;/p&gt;

&lt;h3 id=&quot;anatomy-of-rframework&quot;&gt;Anatomy of R.framework&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, i.e., R, is a complicated and busy framework. It is designed to comply with &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html&quot;&gt;Apple’s Framework Bundles Structure&lt;/a&gt;, but underneath its Apple’s flavored anatomy, everything is organized according to a standard &lt;a href=&quot;https://www.gnu.org/software/automake/manual/1.4/html_node/Install.html&quot;&gt;GNU Install Structure&lt;/a&gt; where binaries lives in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/&lt;/code&gt; and headers are in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include/&lt;/code&gt;, etc. This means when you are inside the GNU environment things get Linux-y as much as they could be on a Darwin subsystem.&lt;/p&gt;

&lt;p&gt;Apple’s Framework Bundle is wrapper around a dynamic library, and all the miscellaneous files needed by the library. In the case of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, everything from include files, fonts, libraries and modules are included in the Framework. One crucial aspect of designing a Framework is to make sure that components of the framework can reliably find each other. In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, this is insured by having everything route through R’s home directory, defined by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt; environment variable. If you install the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; in its default place, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt; is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/R.framework/Resources&lt;/code&gt; which is a symbolic link to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/R.framework/Versions/A/Resources&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; is the version of the R that you are using, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.1&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.1-arm64&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, we can see that everything is neatly placed in their respectable folder:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Frameworks/R.framework/Versions/4.1-arm64/Resources
├── bin
  ├── exec
    └── R
  └── R.sh
├── doc
├── etc
  ├── ldpaths
  └── Makeconf
├── fontconfig
├── include
├── lib
├── library
├── man1
├── modules
├── opt
├── share
└── tests
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/&lt;/code&gt; folder, you find &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec/R&lt;/code&gt; which is the actual R executable. However, this file is not simply being called by its own, instead, it is called from a bash script, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt;. This script does a lot of work, and one of them is to set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt; variable and to inform the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; about it.&lt;/p&gt;

&lt;p&gt;Another crucial step that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt; takes is to load the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/ldpaths&lt;/code&gt;. This file then makes sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; and all the other libraries needed during the execution of R can be found by the system during the loading and execution process. If you are familiar with the concept of library pathing, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldpaths&lt;/code&gt; sets the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DYLD_FALLBACK_LIBRARY_PATH&lt;/code&gt; so that when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; requests a library, the system knows where to look for them.&lt;/p&gt;

&lt;p&gt;Another important file is placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/&lt;/code&gt; folder, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt;. This file sets several environment and R variables, from compiler flags, library paths, header paths, to path of the Fortran compiler. These are useful and necessary information for when you are requesting R to build a package from source. More on this later.&lt;/p&gt;

&lt;h2 id=&quot;embedding-rframework&quot;&gt;Embedding R.framework&lt;/h2&gt;

&lt;p&gt;In order to make the framework portable, we need to make a few changes to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt;. First, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt; has to correctly point to our desired path, second, we need to make sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; and all the other libraries inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; can find each other during the loading process.&lt;/p&gt;

&lt;p&gt;On the very top of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt;, we need to set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME_DIR&lt;/code&gt; to &lt;em&gt;our&lt;/em&gt; custom R’s home directory path. Then, I set the following variables as follow&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;R_SHARE_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/share
&lt;span class=&quot;nv&quot;&gt;R_INCLUDE_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/include
&lt;span class=&quot;nv&quot;&gt;R_DOC_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;R_HOME_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/doc 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you are planning to simply run R from a different place in your system, and do not want to install any packages, you are done! However, if you are planning to install any other packages, and later place the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; inside an App Bundle, your journey is just starting&lt;em&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your first step is to disable the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_PATH&lt;/code&gt; that is being set in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/ldpaths&lt;/code&gt;. You can do this by commenting the following line so that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt; doesn’t try to overwrite/set the library path for you. While this is not strictly needed, it gives you more granular controls over your library pathing and simplifies your debugging later on.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# . &quot;${R_HOME}/etc${R_ARCH}/ldpaths&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After this, if you try to run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt;, you notice that the executable expectedly won’t work because system cannot find the libraries requested by the R executable.&lt;/p&gt;

&lt;p&gt;Now, in the rest of this post, we are going to take care that libraries inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; can find each other even though we have disabled the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldpaths&lt;/code&gt;; in addition, we are going to modify the CRAN binaries upon installation and replace their hard-coded paths. To be able to follow the upcoming section, you need to be familiar with the concept of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPATH&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt;.&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3 id=&quot;patching-library-path-and-install_name_tool&quot;&gt;Patching Library Path and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install_name_tool&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;At this point, we know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt; doesn’t know where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; and other libraries are. You can check the internal of a binary file using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;otool&lt;/code&gt; command on macOS. Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;otool -L bin/exec/R&lt;/code&gt; lists all the libraries that are linked to the executable:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ otool -L bin/exec/R
exec/R:
	/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib (compatibility version 4.1.0, current version 4.1.3)
	/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRblas.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; is looking for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; in the default path &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/&lt;/code&gt; which is in fact &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${R_HOME}/lib&lt;/code&gt; but since we have changed it, it will not be able to find any of them, and will be terminated before it can get far into its execution process.&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;After reading the above footnote, and refreshing your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt; knowledge, you now know how everything works, and that we are going to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;install_name_tool&lt;/code&gt; to change the library path&lt;em&gt;!&lt;/em&gt; 😬&lt;/p&gt;

&lt;p&gt;Since we are going to embed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; into an App Bundle, we are going to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path&lt;/code&gt; variable as our anchor point. Our executable is located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP.app/Contents/MacOS/JASP&lt;/code&gt; and our embedded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; will be placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP.app/Contents/Frameworks/R.framework&lt;/code&gt;, so, by changing all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks&lt;/code&gt; prefix with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path/../Frameworks&lt;/code&gt; we make sure that if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP&lt;/code&gt; executable calls the R executable, libraries can be found in the relative path to the main binary, ie. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP&lt;/code&gt;, therefore&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ otool -L bin/exec/R
exec/R:
	@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib (compatibility version 4.1.0, current version 4.1.3)
	@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRblas.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, this is not yet enough. If we are in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/&lt;/code&gt; and we try to run the already modified R executable, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib&lt;/code&gt; does not lead to anything. To overcome this issue, we need to create a symlink to the Frameworks folder inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${R_HOME}/bin/&lt;/code&gt; that points to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP.app/Contents/Frameworks&lt;/code&gt;. By doing so, when R executable is being called, and system starts looking for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib&lt;/code&gt; there will be a symlink that leads to the location of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt;. Basically, we are making sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frameworks&lt;/code&gt; folder is placed in the same relative location to R executable, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP&lt;/code&gt; executable, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib&lt;/code&gt; is always well-defined regardless of which executable is being called.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;├── bin
  ├── Frameworks -&amp;gt; ../../../../../../Frameworks
  ├── exec
    └── R
  ├── .
  ├── .
  ├── .
  └── R
├── lib
    ├── libR.dylib
    ├── libRblas.dylib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, you need to do the same things for all the libraries that are inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lib/&lt;/code&gt; folder.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ otool -L libR.dylib
libR.dylib:
	@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libR.dylib (compatibility version 4.1.0, current version 4.1.3)
	@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRblas.dylib (compatibility version 0.0.0, current version 0.0.0)
	@executable_path/../Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libgfortran.5.dylib (compatibility version 6.0.0, current version 6.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1853.0.0)
	/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
	/usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.8)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
	/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 68.2.0)
	/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dealing-with-other-libraries-in-library-modules-and-opt&quot;&gt;Dealing with Other Libraries in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library/&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modules/&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt/&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;If you look around the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, you will notice that there are a lot more libraries that all need to be patched with the same procedure. Most libraries are linked against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; and other libraries located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME/lib&lt;/code&gt;, so replacing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@executable_path/../Frameworks&lt;/code&gt; will resolves a lot of issues. However, it does not cover all the edge cases. At JASP, we use a &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/stable/Tools/CMake/PatchR.cmake&quot;&gt;CMake script&lt;/a&gt; to make sure that all libraries are patched.&lt;/p&gt;

&lt;h3 id=&quot;cran-packages&quot;&gt;CRAN Packages&lt;/h3&gt;

&lt;p&gt;When you are installing a CRAN binary package, you are requesting a pre-built version of the library. As discussed, this means, for instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MASS.so&lt;/code&gt; will except to find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Library/Frameworks/Resources/lib&lt;/code&gt;. If you have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; at its preferred place, every CRAN binary package will find the R library by following the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; is sitting in a non-default path, every CRAN binary package comes with a wrong library path; therefore, you have to patch every single of them manually as you did for all the first-party libraries and modules, as described before.&lt;/p&gt;

&lt;h3 id=&quot;macos-security-and-signing&quot;&gt;macOS Security and Signing&lt;/h3&gt;

&lt;p&gt;Modern macOS is quite strict about the identity and origin of the binaries and libraries that are allowed to run in a system. Every Framework or App needs to be signed, verified and notarized by Apple and it’s then and only then that macOS will fully trust and run them without complaining.[^This was a big issue for us where at some point due to the complexity of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP.app&lt;/code&gt;, we couldn’t continue notarizing our app with Apple, so our users ended up getting scary warnings when they tried to run the app.]&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; comes pre-signed and notarized; however, any tempering with its guts will avoid its notarizations and signature. In fact, everything that we did so far falls into the definition of tempering. On a Mac with all default security options enabled, the modified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/exec/R&lt;/code&gt; will not run, and macOS refuses to verify any of the libraries, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libR.dylib&lt;/code&gt;, and therefore terminates the R executable at runtime.&lt;/p&gt;

&lt;p&gt;Fortunately, we can resign a binary/library, and get around this issue. This means that you need to remember to sign every single binary/library that you are modifying during this process. For us, at JASP, we need to sign every libraries on the fly as we build our software. This is because at the same time where we are building our Desktop app, we are also calling the R executable to install our Modules inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;. You can see part of this process &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/blob/stable/Tools/CMake/Patch.cmake&quot;&gt;here&lt;/a&gt; where we are using a CMake module to automate this process during the configuration and build stages.&lt;/p&gt;

&lt;h3 id=&quot;cmake-qt-rframework-and-cross-compilation&quot;&gt;CMake, Qt, R.framework, and Cross Compilation&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/intel-and-apple-silicon.png&quot; style=&quot;float:right; width: 50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cross compilation is the process of compiling a program for different architectures and platforms. Most C/C++ compilers are capable of cross compiling, and most build system and build system generators, e.g., &lt;a href=&quot;https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html&quot;&gt;automake&lt;/a&gt;, &lt;a href=&quot;https://cmake.org&quot;&gt;CMake&lt;/a&gt;, simplify the cross compilation by providing higher level flags, or variables. For instance, when using CMake on macOS, setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MACOSX_DEPLOYMENT_TARGET&lt;/code&gt; variable ensures that the compiler builds your program for the specific architecture.&lt;/p&gt;

&lt;p&gt;JASP core is written in C++, and we are using Qt Framework and other C++ libraries; and on top of that, CMake is used to generate the build system command; therefore, we can target different architecture and version by configuring CMake correctly. However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; as an external pre-built framework doesn’t have any ideas about CMake, and it is only being linked to JASP App Bundle. The other problem is the Fortran compiler which is not fully stable on Apple Silicon; therefore its cross compilation is not to be trusted.&lt;/p&gt;

&lt;p&gt;In the rest of this post, I briefly walk through the steps necessary for treating the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; such that it can correctly cross compile R source packages.&lt;/p&gt;

&lt;h3 id=&quot;cross-compilation-of-r-source-packages&quot;&gt;Cross Compilation of R Source Packages&lt;/h3&gt;

&lt;p&gt;With JASP 0.16.2, we rewrote our build system from scratch, see &lt;a href=&quot;https://github.com/jasp-stats/jasp-desktop/pull/4658&quot;&gt;here&lt;/a&gt;. We committed to this effort to resolve some of the underlying issues in our backend. In addition, we wanted to have a native version of JASP for Apple Silicon, and that meant we had to deal with two different architectures, two different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.frameworks&lt;/code&gt; and a whole lot of other details. I am planning to write another post about this transition; here though, I would like to discuss what this cross compilation mean for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; and the process of embedding it to JASP.&lt;/p&gt;

&lt;p&gt;Everything that I have mentioned above applies to both versions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, ie., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;. Libraries and binaries should be patched similarly, the resigning procedure is as important and it should be done on the fly; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/R.sh&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_HOME&lt;/code&gt; need attentions. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; in different architectures do a good job of downloading the right binary from CRAN; so, if you have already taken care of the library paths, you embed the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; to the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JASP.app&lt;/code&gt;, either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;, and you can install R packages and you are guaranteed to get the right binary.&lt;/p&gt;

&lt;p&gt;However, the problem arises when you have to compile something! Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; does not come with its own compiler toolchain, you need to make sure that during the cross compilation, R’s internal are aware of your compiler flags.&lt;/p&gt;

&lt;h4 id=&quot;notes-on-makeconf-and-fortran&quot;&gt;Notes on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makeconf&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fortran&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;As mentioned, CRAN is doing a great job of providing binary packages, and the only thing you need to do is to patch and resign your downloaded libraries, and make sure that R can find them. However, sometimes, you need to build a package, in our case our JASP Modules. This means that R needs to have access to compilers, and development toolchains.&lt;/p&gt;

&lt;p&gt;On macOS, you can get your C/C++ compiler by downloading and installing Xcode, and after that, R can use system variables and find the compiler with no problem. However, Xcode doesn’t ship with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran&lt;/code&gt; and you often cannot use the Fortran that comes with Homebrew as you may ran into &lt;a href=&quot;https://en.wikipedia.org/wiki/Application_binary_interface&quot;&gt;ABI&lt;/a&gt; incompatibilities, even if your build passes. In addition, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; is very particular about the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran&lt;/code&gt;. So, what you want to do is to download the right Fortran, install it somewhere, and make sure that R can find it. This is a problematic step even without making R portable, or cross-compilation attempt. Even worst, on Apple Silicon, the Fortran is not yet stable, so you need to go with &lt;a href=&quot;https://github.com/fxcoudert/gfortran-for-macOS&quot;&gt;an experimental version&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since we are cross compiling, we need to have a Fortran compiler that is capable of cross compilation; however, considering the way R uses the Fortran compiler, at this moment, I would not recommend using the Fortran compiler for cross compilation. Instead, we need to download two versions of Fortran, ie., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;, and link the right compiler to the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, the problem is how to inform the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; about the location of Fortran.&lt;/p&gt;

&lt;h5 id=&quot;enters-etcmakeconf&quot;&gt;Enters &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt;&lt;/h5&gt;

&lt;p&gt;As mentioned, most of the compiler configurations, including the host system and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;’s build flags are set in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt;. In order to guide the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; to the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran&lt;/code&gt;, or any other tools, we need to modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt; file, and that’s what we are doing at JASP. During the configuration step, we set the target architecture, ie., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm64&lt;/code&gt;, download the right Fortran compiler, unpack and patch it; and finally, modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt; such that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FC&lt;/code&gt; variable points to the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran&lt;/code&gt; executable.&lt;/p&gt;

&lt;p&gt;To be precise, we download the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gfortran&lt;/code&gt; installer, unpack it inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${R_HOME}/opt/local/gfortran&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${R_HOME}/opt/R/arm64/gfortran&lt;/code&gt; and make sure that any references to the Fortran compiler (in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;etc/Makeconf&lt;/code&gt;) points to the right path, e.g.,&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt;.bak &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/opt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/R&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/arm64/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;R_HOME&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/opt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/R&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/arm64/g&quot;&lt;/span&gt; Makeconf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This guarantees that any R packages that needs building is being build for the target architecture, even if it needs to compile Fortran code.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this post, I have tried to &lt;em&gt;briefly&lt;/em&gt; summarize some of the most important steps needed to successfully patch and embed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; into a macOS App Bundle. I mainly focused on the process of preparing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt;, making sure that it can work from a non-default location, patching its executable and libraries, and modifying the CRAN binary packages such that they can live inside the altered framework. In addition, I touched upon the topic of cross compilation, and what needs to be done when it comes to R source packages.&lt;/p&gt;

&lt;p&gt;I hope that in the next post, I can dig deeper into the role of CMake, and explain how we utilize CMake tools and capabilities to glue different aspects of the build together. In the meantime, if you are struggling with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; please feel free to reach out on Twitter, or write to me. I’d be happy if I could be of any help&lt;em&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Embedding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; is such a cumbersome task that as far as I can tell, even the RStudio team gave up on it, and simply ask you to download the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R.framework&lt;/code&gt; if you don’t have it. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;You can refresh your knowledge by reading &lt;a href=&quot;https://amir.rachum.com/blog/2016/09/17/shared-libraries/#debugging-cheat-sheet&quot;&gt;Shared Libraries: Understanding Dynamic Loading&lt;/a&gt;. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;If you are not familiar with these concepts, you first need to read and understand a few things about how libraries are linked together, and how they can find each other if they are not placed in the same directory, see &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html#//apple_ref/doc/uid/TP40001873-SW1&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html#//apple_ref/doc/uid/TP40008306-SW1&quot;&gt;here&lt;/a&gt;. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>amirmasoudabdol</name></author><category term="blog" /><category term="C" /><category term="Cpp" /><category term="R" /><category term="Rstats" /><category term="macOS" /><category term="Notarization" /><summary type="html">Developing for Apple platform can be fun if your app lives solely inside Xcode, and you only utilize standard libraries, or don’t interact with any alien libraries or frameworks. In that case, there is a high chance that you have never been worried about compatibility issues, linking problems, signing struggles and the notarization!</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/posts/embedding-r-framework-twitter-summary-large-image.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/posts/embedding-r-framework-twitter-summary-large-image.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">San Francisco Themes</title><link href="https://amirmasoudabdol.name/sfthemes-r-package/" rel="alternate" type="text/html" title="San Francisco Themes" /><published>2020-12-26T00:00:00+00:00</published><updated>2020-12-26T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/sfthemes-r-package</id><content type="html" xml:base="https://amirmasoudabdol.name/sfthemes-r-package/">&lt;!-- # San Francisco Themes --&gt;

&lt;p&gt;There are many, many, many different color palettes available for {ggplot2}, and the list is growing daily. In short, {sfthemes} is technically an another set of colors and palettes that is inspired by &lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/&quot;&gt;iOS&lt;/a&gt;/&lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color/&quot;&gt;macOS&lt;/a&gt;/&lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/watchos/visual/color/&quot;&gt;watchOS&lt;/a&gt; system colors. These palettes are vibrant and are designed to be easily distinguishable in differnt screen sizes and brightness settings. Moreover, they offer optimized variants for light and dark mode.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://sfthemes.amirmasoudabdol.name/reference/figures/front-page-main.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From the project &lt;a href=&quot;https://sfthemes.amirmasoudabdol.name&quot;&gt;website&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;sfthemes is a pair of &lt;a href=&quot;https://ggplot2.tidyverse.org&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ggplot2&lt;/code&gt;&lt;/a&gt; themes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theme_sf_light()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theme_sf_dark()&lt;/code&gt;, and a collection of color scales based on &lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/&quot;&gt;Apple’s Human Interface Guidelines&lt;/a&gt;. Themes are inspired by the occasional appearances of charts used by Apple within different contexts, e.g., Apple Health app, Screen Time on iOS and macOS. And colors are adapted from iOS, macOS, and watchOS system colors. Each color scale has a light and dark variant as well that compliments the light/dark themes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scale_colour_ios_light()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scale_colour_ios_dark()&lt;/code&gt;, respectively. In addition, sfthemes uses &lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography/&quot;&gt;dynamic type sizing&lt;/a&gt; in order to provide a consistent and elegant overall resizing and re-scaling of plot elements. Read more &lt;a href=&quot;articles/typography.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;breaker&quot;&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Project website: &lt;a href=&quot;https://sfthemes.amirmasoudabdol.name&quot;&gt;{sfthemes} - An accessible ‘pkgdown’ template&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;GitHub Repo: &lt;a href=&quot;https://github.com/amirmasoudabdol/sfthemes/&quot;&gt;amirmasoudabdol/sfthemes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>amirmasoudabdol</name></author><category term="Projects" /><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/projects/sfthemes/twitter-summary-card.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/projects/sfthemes/twitter-summary-card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Preferably</title><link href="https://amirmasoudabdol.name/preferably-r-package/" rel="alternate" type="text/html" title="Preferably" /><published>2020-12-20T00:00:00+00:00</published><updated>2020-12-20T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/preferably-r-package</id><content type="html" xml:base="https://amirmasoudabdol.name/preferably-r-package/">&lt;!-- # Preferably --&gt;

&lt;p&gt;During this lockdown period with long hours of screentime every day, my eyes started to become very sensitive to white background. Luckily, these days most websites and operation systems offer &lt;a href=&quot;https://en.wikipedia.org/wiki/Light-on-dark_color_scheme&quot;&gt;Dark Mode&lt;/a&gt; by default. However, I realized that the documentation websites of most R packages do not support dark theme, and since I’m working with R packages every day, I had to do something about it. So, I decided to develop a template for &lt;a href=&quot;https://pkgdown.r-lib.org&quot;&gt;{pkgdown}&lt;/a&gt; that can take advantage of some of the modern capabalities of modern browsers.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://preferably.amirmasoudabdol.name/reference/figures/comparison.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From the project &lt;a href=&quot;https://preferably.amirmasoudabdol.name&quot;&gt;website&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;preferably is an &lt;strong&gt;accessible&lt;/strong&gt; template for &lt;a href=&quot;https://pkgdown.r-lib.org/&quot;&gt;pkgdown&lt;/a&gt; documentation websites. It uses a &lt;a href=&quot;https://bootswatch.com/flatly/&quot;&gt;light&lt;/a&gt; and a &lt;a href=&quot;https://bootswatch.com/darkly/&quot;&gt;dark&lt;/a&gt; theme and utilizes the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefers-color-scheme&lt;/code&gt;&lt;/a&gt; CSS variable to &lt;em&gt;automatically&lt;/em&gt; serve either of the two based on users’ operating system setting, or allowing them to manually toggle between them.&lt;/p&gt;

  &lt;p&gt;Besides offering light and dark mode, I spent some time making the overall reading experience of ‘pkgdown’ documentations just a bit nicer, by using richer fonts, adopting a better color scheme for codes, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;breaker&quot;&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Project website: &lt;a href=&quot;https://preferably.amirmasoudabdol.name&quot;&gt;{preferably} - An accessible ‘pkgdown’ template&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;GitHub Repo: &lt;a href=&quot;https://github.com/amirmasoudabdol/preferably/&quot;&gt;amirmasoudabdol/preferably&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>amirmasoudabdol</name></author><category term="Projects" /><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/projects/preferably/twitter-summary-card.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/projects/preferably/twitter-summary-card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Spatialtemporal Clustering of Gene Expression Level</title><link href="https://amirmasoudabdol.name/spatialtemporal-clustering-of-gene-expression-level/" rel="alternate" type="text/html" title="Spatialtemporal Clustering of Gene Expression Level" /><published>2018-05-10T00:00:00+00:00</published><updated>2018-05-10T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/spatialtemporal-clustering-of-gene-expression-level</id><content type="html" xml:base="https://amirmasoudabdol.name/spatialtemporal-clustering-of-gene-expression-level/">&lt;p&gt;I like data, colors, composition, design, and story-telling. Alternatively, I can say that I like &lt;em&gt;Data Visualization&lt;/em&gt;. To me, data visualization is the process of &lt;em&gt;designing&lt;/em&gt; — or &lt;em&gt;extracting&lt;/em&gt; — a story from the data. As a good design is selective, focused — and minimal —, a good visualization is clever, simple, and discerning. It often condenses a colossal dataset into bite-size visual facts; or it tells a gentle and informative story of a common statistic. Of course there are many other types and categories but I feel this definition and examples are quite descriptive.&lt;/p&gt;

&lt;p&gt;During my &lt;a href=&quot;https://amirmasoudabdol.name/phd&quot;&gt;Ph.D.&lt;/a&gt; project, I have tried to look at my dataset differently, clarify my results and produce nice charts and visualizations. I am quite proud of a few of them, namely, the &lt;em&gt;spatiotemporal clusters&lt;/em&gt; visualization. It clearly shows the distinction between the spatial and temporal clusters, and it makes it relatively easy to track the spatial or temporal correlation of genes. In the figure below, there are 4 spatial clusters, i.e., &lt;em&gt;nodes color&lt;/em&gt;, and 9 temporal clusters, i.e., &lt;em&gt;edges color&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/Spatiotemporal_Clusters.png&quot; alt=&quot;Spatiotemporal Clusters&quot; class=&quot;bigger-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You probably need some knowledge of biology and gene regulatory network &lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, but the main idea here is that if genes are connected to each others and are having the same colors, then are correlated both in time, and space, i.e., appearing at the same time and place in the organism.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/Nematostella_Patterning.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Amir M Abdol et al. “A novel technique to combine and analyse spatial and temporal expression datasets: A case study with the sea anemone Nematostella vectensis to identify potential gene interactions”. English. In: (June 2017). DOI: &lt;a href=&quot;https://www.sciencedirect.com/science/article/pii/S0012160617301008?via%3Dihub&quot;&gt;10.1016/j.ydbio. 2017.06.004&lt;/a&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>amirmasoudabdol</name></author><category term="blog" /><category term="A Better Visualization" /><summary type="html">I like data, colors, composition, design, and story-telling. Alternatively, I can say that I like Data Visualization. To me, data visualization is the process of designing — or extracting — a story from the data. As a good design is selective, focused — and minimal —, a good visualization is clever, simple, and discerning. It often condenses a colossal dataset into bite-size visual facts; or it tells a gentle and informative story of a common statistic. Of course there are many other types and categories but I feel this definition and examples are quite descriptive.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/posts/nematostella-gastrulation-twitter-summary-large-image.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/posts/nematostella-gastrulation-twitter-summary-large-image.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ph.D. Thesis</title><link href="https://amirmasoudabdol.name/phd/" rel="alternate" type="text/html" title="Ph.D. Thesis" /><published>2018-05-08T00:00:00+00:00</published><updated>2018-05-08T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/phd</id><content type="html" xml:base="https://amirmasoudabdol.name/phd/">&lt;h4 id=&quot;abstract&quot;&gt;Abstract&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;Over the last decade, the sea anemone &lt;em&gt;Nematostella vectensis&lt;/em&gt; has become a popular model to study bilaterian evolution, development and more recently also regeneration. Understanding genetic interactions during the early development of &lt;em&gt;N. vectensis&lt;/em&gt; is the first step toward unveiling the details of its early developmental processes, e.g., polarization, the formation of the &lt;em&gt;blastula&lt;/em&gt; and initiation of the &lt;em&gt;gastrulation&lt;/em&gt; process. Furthermore, the collective knowledge of gene interactions allows researchers to speculate about possible &lt;em&gt;Gene Regulatory Networks&lt;/em&gt; (GRNs) governing each process. The knowledge of gene interactions also provides an opportunity to reverse engineer gene interactions in a GRN model which potentially leads to detailed understanding of the early developmental processes, e.g., pattern formation and the mechanics of gastrulation. There is still a limited amount of knowledge available regarding &lt;em&gt;N. vectensis&lt;/em&gt; gene interactions and possible GRNs involved in each developmental process. This thesis introduces a method for extracting spatial gene expression profiles from &lt;em&gt;in situ&lt;/em&gt; hybridization images of &lt;em&gt;N. vectensis&lt;/em&gt; embryo. My collaborators and I have introduced a systematic procedure to combine and process the available data from different sources (e.g., &lt;em&gt;in situ&lt;/em&gt; and &lt;em&gt;qPCR&lt;/em&gt;) in order to understand gene interactions and reconstruct testable hypotheses for GRNs controlling development.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/assets/projects/PhD_Cover.png&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A. M. Abdol. Toward Reverse Engineering Spatiotemporal Gene Regulatory Networks of Nematostella Vectensis. Supervised by P. M. A. Sloot and J. A. Kaandorp. ISBN: 9789402810110. &lt;a href=&quot;https://hdl.handle.net/11245.1/b0077baa-217d-43f2-920e-6d602fa3a07d&quot;&gt;UvA-Dare&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>amirmasoudabdol</name></author><category term="blog" /><summary type="html">Abstract</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/projects/PhD_Cover_twitter-summary-card.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/projects/PhD_Cover_twitter-summary-card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">NimbleBox</title><link href="https://amirmasoudabdol.name/NimbleBox/" rel="alternate" type="text/html" title="NimbleBox" /><published>2012-06-14T00:00:00+00:00</published><updated>2012-06-14T00:00:00+00:00</updated><id>https://amirmasoudabdol.name/NimbleBox</id><content type="html" xml:base="https://amirmasoudabdol.name/NimbleBox/">&lt;p&gt;In early ages of the Evernote, I was trying to store and organize everything on the Evernote. I remember being inspired by the &lt;a href=&quot;https://en.wikipedia.org/wiki/Getting_Things_Done&quot;&gt;Getting Things Done&lt;/a&gt; technique and I set up a very sophisticated GTD system. I’ve defined several notebooks and tags for everything, &lt;em&gt;Inbox, Later, Today&lt;/em&gt;, etc. The Evernote and my GTD system was working reasonably in my favor, I have collected a few thousand notes and managed to organize and finish some projects while keeping my sanity!&lt;/p&gt;

&lt;p&gt;One of the problem with Evernote client at that time was adding stuff to it was not very convenient, especially when you have large number of notes then the client would have been sluggish and rather buggy to work with. The Mac version was faster and more well-behaved. It was also equipped with this small version of Evernote called &lt;em&gt;Evernote Mini&lt;/em&gt;. The Evernote Mini was a small app living in the menubar and it can be summoned by a HotKey to quickly capture a note, screenshot, or an audio recording. This was perfect for capturing quite notes and just dump them into the &lt;em&gt;Inbox&lt;/em&gt; for later processing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/projects/nimblebox/EvernoteMini.png&quot; alt=&quot;Evernote Mini&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I love the idea of Evernote Mini, and I’ve tried to convince Evernote team to implement something similar for the Windows client. Unfortunatly that was not the priority at the time and it is still not in the Windows version. So, I’ve decided to implement something similar for Windows.&lt;/p&gt;

&lt;p&gt;I’ve started with the main idea, &lt;em&gt;a simple and minimal app that can be used to quickly capture notes and send them to the Evernote.&lt;/em&gt; Back then I was doing some C# programming and has never touched a real web API, but I knew about UI Design and I had the core experience in mind. Also, I was inspired by the &lt;em&gt;iA Writer&lt;/em&gt; and I wanted to reproduce the same simplicity and experience. The video below shows my attempts to recreate Evernote Mini for the Windows. I called it &lt;strong&gt;NimbleBox&lt;/strong&gt;.&lt;/p&gt;

&lt;iframe src=&quot;https://player.vimeo.com/video/68486671&quot; width=&quot;640&quot; height=&quot;483&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;In term of features, I’ve added a few neat tricks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Markdown&lt;/li&gt;
  &lt;li&gt;Support for Right-to-Left languages like Farsi, Arabic, and Hebrew.&lt;/li&gt;
  &lt;li&gt;Inline shortcut for adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#Tags&lt;/code&gt;, sending a note to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Notebook&lt;/code&gt; or adding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^DueDate&lt;/code&gt; to a note.&lt;/li&gt;
  &lt;li&gt;Twitter support&lt;/li&gt;
  &lt;li&gt;Etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was and I am still very happy with the outcome. Unfortunately, at around one year after I released the project, Aug 2013, one of the API that I was using stopped working and I didn’t have time to reimplement it myself. So the project effectively dead after that.&lt;/p&gt;</content><author><name>amirmasoudabdol</name></author><category term="Projects" /><summary type="html">In early ages of the Evernote, I was trying to store and organize everything on the Evernote. I remember being inspired by the Getting Things Done technique and I set up a very sophisticated GTD system. I’ve defined several notebooks and tags for everything, Inbox, Later, Today, etc. The Evernote and my GTD system was working reasonably in my favor, I have collected a few thousand notes and managed to organize and finish some projects while keeping my sanity!</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://amirmasoudabdol.name/assets/projects/nimblebox/NimbleBox_Evernote_Logo.png" /><media:content medium="image" url="https://amirmasoudabdol.name/assets/projects/nimblebox/NimbleBox_Evernote_Logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>