<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Velho</title>
    <description>The latest articles on DEV Community by David Velho (@theprogrammerdavid).</description>
    <link>https://dev.to/theprogrammerdavid</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F367806%2F761af767-a4ce-48df-930c-f78234e082b5.png</url>
      <title>DEV Community: David Velho</title>
      <link>https://dev.to/theprogrammerdavid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/theprogrammerdavid"/>
    <language>en</language>
    <item>
      <title>Stop-gap measure to debug a Native Node Addon on Windows</title>
      <dc:creator>David Velho</dc:creator>
      <pubDate>Mon, 07 Aug 2023 12:50:59 +0000</pubDate>
      <link>https://dev.to/theprogrammerdavid/stop-gap-measure-to-debug-a-native-node-addon-on-windows-25mf</link>
      <guid>https://dev.to/theprogrammerdavid/stop-gap-measure-to-debug-a-native-node-addon-on-windows-25mf</guid>
      <description>&lt;p&gt;While working on building a &lt;a href="https://github.com/P2PFlix/libtorrent"&gt;project&lt;/a&gt; that includes a &lt;code&gt;NodeJs&lt;/code&gt; addon using &lt;code&gt;N-API&lt;/code&gt; for &lt;code&gt;Windows&lt;/code&gt; (and *nix), I found that binaries built on my machine work but the same binaries do not work on another machine. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ND9beEuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a948fj0kv2u9auya215g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ND9beEuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a948fj0kv2u9auya215g.png" alt="loading libtorrent on my machine" width="728" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qxBAgPX7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkr0tf1j9atkoi0o5lq4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qxBAgPX7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkr0tf1j9atkoi0o5lq4.png" alt="loading libtorrent on another machine" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the file(s) are all present. What is happening? The same behaviour was observed on Linux and MacOS machines other than mine.&lt;/p&gt;

&lt;p&gt;I would have switched to Linux and used &lt;code&gt;strace&lt;/code&gt; to see what was happening, but I wanted to see if Windows has any good alternatives. After some quick Google searching, I realized that I could use the built-in &lt;code&gt;Visual Studio&lt;/code&gt; debugger. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I assume that you have the Visual Studio environment setup for C++ development on windows, along with the required SDKs installed&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The commands I used to load and test the &lt;code&gt;libtorrent&lt;/code&gt; build are (in a NodeJs shell) -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./libtorrent.node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I tried to find a Debug target (using the CMake extension that populates Visual Studio with stuff)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EX9JNa-q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wie6wun681kgocachzhy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EX9JNa-q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wie6wun681kgocachzhy.png" alt="Debug targets" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No luck. Next, I opened Visual Studio and tried to start a &lt;code&gt;NodeJs&lt;/code&gt; process using the debugger - &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kPh6Alx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta59erhyyukq6hmuobks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kPh6Alx4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta59erhyyukq6hmuobks.png" alt="Visual Studio debug menu" width="541" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the "Start Debugging" option was greyed out. However, the "Attach to Process" option is available. Choosing that option opens the following menu - &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TLhiGhz6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxjyi2ikyy1z8kdl44fy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TLhiGhz6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxjyi2ikyy1z8kdl44fy.png" alt="Attach to process menu" width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Module&lt;/code&gt; window will be of interest to us&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tXhDcHkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up52hz4nkkrpbukg2q8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tXhDcHkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up52hz4nkkrpbukg2q8n.png" alt="Visual Studio Module window" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the timestamp column. Lets sort the list by timestamp and focus on the rows with a timestamp -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m-lfmz9v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbql6tfn45yok7tymnd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m-lfmz9v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbql6tfn45yok7tymnd1.png" alt="Close-up of module window last few rows" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes sense as we haven't loaded the addon yet. Let's load the addon through &lt;code&gt;Node&lt;/code&gt; and check the window again&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--glLbgXLk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t48rk2sncpf0rax7azpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--glLbgXLk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t48rk2sncpf0rax7azpg.png" alt="loading libtorrent" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see a few more entries. On observing them, we see the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;libcrypto-3-x64.dll&lt;/li&gt;
&lt;li&gt;libssl-3-x64.dll&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going through the dependencies, we see that our project's main dependency &lt;a href="https://github.com/arvidn/libtorrent"&gt;libtorrent&lt;/a&gt; depends on &lt;code&gt;OpenSSL&lt;/code&gt;. Finally it clicked that I installed &lt;code&gt;OpenSSL&lt;/code&gt; through &lt;code&gt;choco&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 1: Bundle and distribute required DLLs
&lt;/h2&gt;

&lt;p&gt;Let's try to bundle the required DLLs with the project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V1CDpmfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yftsoggbbik2bmsi9j0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V1CDpmfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yftsoggbbik2bmsi9j0.png" alt="libtorrent with additional DLLs" width="652" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we see that &lt;code&gt;libtorrent&lt;/code&gt; is successfully loaded&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--77KOELkv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1n9qudcldza7cwd764i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--77KOELkv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1n9qudcldza7cwd764i.png" alt="successfully loading libtorrent" width="794" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that's not a feasible solution. There might be scenarios where one cannot bundle multiple &lt;code&gt;DLLs&lt;/code&gt; due to some restriction. How do we proceed?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 2: If it works, it ain't stupid
&lt;/h2&gt;

&lt;p&gt;We know that the project depends on &lt;code&gt;libcrypto&lt;/code&gt; and &lt;code&gt;libssl&lt;/code&gt;, but probably uses a few functions or items from them. To test this theory out, I modified my project's &lt;code&gt;CMakeLists.txt&lt;/code&gt; file to fetch &lt;code&gt;openssl&lt;/code&gt; from &lt;code&gt;Github&lt;/code&gt; using CMake's built in (version &lt;code&gt;3.11&lt;/code&gt; and later) &lt;code&gt;FetchContent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The following is an extract of the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;FetchContent&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;FetchContent_Declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    openssl
    GIT_REPOSITORY https://github.com/janbar/openssl-cmake.git
    SOURCE_DIR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/lib/openssl
    GIT_TAG 392d455cd0b0fe992b312c9648eb5ea87e3afcea
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;FetchContent_MakeAvailable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;openssl&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;OPENSSL_ROOT_DIR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/lib/openssl/*&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_BUILD_TYPE STREQUAL &lt;span class="s2"&gt;"Debug"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;OPENSSL_CRYPTO_LIBRARY &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/build/_deps/openssl-build/crypto/Debug&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;elseif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_BUILD_TYPE STREQUAL &lt;span class="s2"&gt;"Release"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;OPENSSL_CRYPTO_LIBRARY &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/build/_deps/openssl-build/crypto/Release&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The statement to set &lt;code&gt;OPENSSL_CRYPTO_LIBRARY&lt;/code&gt; can be optimised further&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This resulted in the following files being generated - &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Foq4SUBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nrap4tadj6a7jdju3fnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Foq4SUBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nrap4tadj6a7jdju3fnv.png" alt="Image description" width="671" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the &lt;code&gt;openssl&lt;/code&gt; binary is built as default behaviour that can be customized &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2co49Gtw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjn3izluglfn4981wvfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2co49Gtw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjn3izluglfn4981wvfs.png" alt="libtorrent with statically linked openssl" width="720" height="997"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Shaky cam courtesy of a friend&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Include custom CMake modules</title>
      <dc:creator>David Velho</dc:creator>
      <pubDate>Tue, 28 Feb 2023 15:24:47 +0000</pubDate>
      <link>https://dev.to/theprogrammerdavid/include-custom-cmake-modules-1914</link>
      <guid>https://dev.to/theprogrammerdavid/include-custom-cmake-modules-1914</guid>
      <description>&lt;p&gt;Lets abstract some configuration of our project to a user defined &lt;code&gt;Config.cmake&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Let's assume your project uses CMake and has a directory structure similar to the one shown below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qftd0_QA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uatgiz7qehl68emgd8ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qftd0_QA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uatgiz7qehl68emgd8ej.png" alt="C++ project with directory structure with custom CMake modules" width="182" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Config.cmake&lt;/code&gt; file has the following stuff -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;set_target_properties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  PROPERTIES CXX_STANDARD 17
             CXX_STANDARD_REQUIRED YES
             CXX_EXTENSIONS NO&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CheckIPOSupported&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;check_ipo_supported&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;RESULT result&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;result&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;set_target_properties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nb"&gt;find_program&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CCACHE_PROGRAM ccache&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CCACHE_PROGRAM&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_CXX_COMPILER_LAUNCHER &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CCACHE_PROGRAM&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_CUDA_COMPILER_LAUNCHER &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CCACHE_PROGRAM&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# CMake 3.9+&lt;/span&gt;
&lt;span class="nb"&gt;endif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in our root &lt;code&gt;CMakeLists.txt&lt;/code&gt; file, lets add the following lines -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;APPEND CMAKE_MODULE_PATH &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROJECT_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/cmake/Modules"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This line must go &lt;em&gt;after&lt;/em&gt; your &lt;code&gt;project&lt;/code&gt; configuration&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And finally,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;Config&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;Config&lt;/code&gt; is the name of file with our abstractions&lt;/p&gt;

</description>
      <category>cmake</category>
      <category>module</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Dockerize Apache Tomcat Servlets</title>
      <dc:creator>David Velho</dc:creator>
      <pubDate>Tue, 01 Jun 2021 11:47:13 +0000</pubDate>
      <link>https://dev.to/theprogrammerdavid/dockerize-apache-tomcat-servlets-33jj</link>
      <guid>https://dev.to/theprogrammerdavid/dockerize-apache-tomcat-servlets-33jj</guid>
      <description>&lt;h2&gt;
  
  
  Step 1 - Dependencies
&lt;/h2&gt;

&lt;p&gt;Make sure you have &lt;code&gt;Java EE&lt;/code&gt;, a compatible version of &lt;code&gt;JDK&lt;/code&gt; and &lt;code&gt;Docker&lt;/code&gt; installed.&lt;br&gt;
If you don't have &lt;code&gt;Java EE&lt;/code&gt; installed, or if you have &lt;code&gt;OpenJDK&lt;/code&gt; , you can use the &lt;code&gt;Java EE&lt;/code&gt; jar file downloaded from &lt;a href="http://www.java2s.com/Code/Jar/j/Downloadjavaeejar.htm" rel="noopener noreferrer"&gt;this link&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2 - Compile source code
&lt;/h2&gt;

&lt;p&gt;Let's use the Java source code from &lt;a href="https://www.informit.com/articles/article.aspx?p=26920&amp;amp;seqNum=4" rel="noopener noreferrer"&gt;this link&lt;/a&gt; and compile it using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;javac &lt;span class="nt"&gt;-cp&lt;/span&gt; .:&amp;lt;path to javaee jar&amp;gt; &lt;span class="nt"&gt;-target&lt;/span&gt; 1.7 &lt;span class="nt"&gt;-source&lt;/span&gt; 1.7 TestingServlet.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you're using windows, you have to use &lt;code&gt;;&lt;/code&gt; instead of &lt;code&gt;:&lt;/code&gt; in classpath&lt;br&gt;
The &lt;code&gt;-target&lt;/code&gt; is the version number of the runtime environment of tomcat. Similarly for &lt;code&gt;-source&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 3 - Environment Setup
&lt;/h2&gt;

&lt;p&gt;Let's use the &lt;code&gt;Dockerfile&lt;/code&gt; from &lt;a href="https://github.com/softwareyoga/docker-tomcat-tutorial" rel="noopener noreferrer"&gt;here&lt;/a&gt; and let's add some stuff.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; tomcat:8.0-alpine&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; maintainer="deepak@softwareyoga.com"&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./web.xml /usr/local/tomcat/webapps/ROOT/WEB-INF&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./TestingServlet.class /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/TestingServlet.class&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./tomcat-users.xml /usr/local/tomcat/conf/tomcat-users.xml&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["catalina.sh", "run"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We define &lt;code&gt;web.xml&lt;/code&gt; and &lt;code&gt;tomcat-users.xml&lt;/code&gt; later. The file &lt;code&gt;TestingServlet.class&lt;/code&gt; is important and we'll remember the name for later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4 - Configuration
&lt;/h2&gt;

&lt;p&gt;Let's define &lt;code&gt;web.xml&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;web-app&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://xmlns.jcp.org/xml/ns/javaee"&lt;/span&gt;
  &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
  &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"&lt;/span&gt;
  &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"3.1"&lt;/span&gt;
  &lt;span class="na"&gt;metadata-complete=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;display-name&amp;gt;&lt;/span&gt;Welcome to Tomcat&lt;span class="nt"&gt;&amp;lt;/display-name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;
     Welcome to Tomcat
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;servlet&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;servlet-name&amp;gt;&lt;/span&gt;Testing&lt;span class="nt"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;servlet-class&amp;gt;&lt;/span&gt;TestingServlet &lt;span class="nt"&gt;&amp;lt;/servlet-class&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/servlet&amp;gt;&lt;/span&gt;

 &lt;span class="nt"&gt;&amp;lt;servlet-mapping&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;servlet-name&amp;gt;&lt;/span&gt;Testing&lt;span class="nt"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;url-pattern&amp;gt;&lt;/span&gt;/servlet/TestingServlet&lt;span class="nt"&gt;&amp;lt;/url-pattern&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/web-app&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;servlet-class&lt;/code&gt; is the name of the &lt;code&gt;.class&lt;/code&gt; file and &lt;code&gt;url-pattern&lt;/code&gt; is the &lt;code&gt;HTTP&lt;/code&gt; url you want to access it by.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's define &lt;code&gt;tomcat-users.xml&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version='1.0' encoding='utf-8'?&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;tomcat-users&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://tomcat.apache.org/xml"&lt;/span&gt;
              &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
              &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://tomcat.apache.org/xml tomcat-users.xsd"&lt;/span&gt;
              &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--
  NOTE:  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary. It is
  strongly recommended that you do NOT use one of the users in the commented out
  section below since they are intended for use with the examples web
  application.
--&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--
  NOTE:  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the &amp;lt;!.. ..&amp;gt; that surrounds
  them. You will also need to set the passwords to something appropriate.
--&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;role&lt;/span&gt; &lt;span class="na"&gt;rolename=&lt;/span&gt;&lt;span class="s"&gt;"manager"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;role&lt;/span&gt; &lt;span class="na"&gt;rolename=&lt;/span&gt;&lt;span class="s"&gt;"manager-gui"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;user&lt;/span&gt; &lt;span class="na"&gt;username=&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt; &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt; &lt;span class="na"&gt;roles=&lt;/span&gt;&lt;span class="s"&gt;"manager-gui"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/tomcat-users&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Apache Tomcat defines a list of roles &lt;a href="http://tomcat.apache.org/migration-7.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 5 - Deployment
&lt;/h2&gt;

&lt;p&gt;Let's build the &lt;code&gt;Docker&lt;/code&gt; image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; tomcat &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;--name&lt;/span&gt; tomcat tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Apache Tomcat runs on port &lt;code&gt;8080&lt;/code&gt; in the container&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can now visit &lt;code&gt;http://localhost:8080/servlet/TestingServlet&lt;/code&gt; and see the following message&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadrey0a3xxy8iyt61jgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadrey0a3xxy8iyt61jgh.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 - Debugging
&lt;/h2&gt;

&lt;p&gt;If you see an error like this &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcqmir1sdr65blvdifdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcqmir1sdr65blvdifdy.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
It means that you have to select a differente &lt;code&gt;target&lt;/code&gt; and &lt;code&gt;source&lt;/code&gt; version, either higher or lower depending on the version of the target runtime. You can check the Java Runtime version through the &lt;a href="http://localhost:8080/manager/html" rel="noopener noreferrer"&gt;Tomcat UI&lt;/a&gt; at the bottom of the page&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F291eg56nc7zhvj2burvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F291eg56nc7zhvj2burvi.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can run &lt;code&gt;bash version.sh&lt;/code&gt; in &lt;code&gt;/usr/local/tomcat/bin&lt;/code&gt; when inside the running Docker container&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ogab8ldnxtbr1r6dv4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ogab8ldnxtbr1r6dv4w.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/softwareyoga/docker-tomcat-tutorial" rel="noopener noreferrer"&gt;Tomcat Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#crosscomp-example" rel="noopener noreferrer"&gt;Java cross compile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.slideshare.net/tusharkute/java-servlet-programming-under-ubuntu-linux-by-tushar-b-kute" rel="noopener noreferrer"&gt;Servlet setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.informit.com/articles/article.aspx?p=26920&amp;amp;seqNum=4" rel="noopener noreferrer"&gt;Servlet setup 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tomcat.apache.org/migration-7.html" rel="noopener noreferrer"&gt;Apache Tomcat Roles&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>tomcat</category>
      <category>apache</category>
      <category>java</category>
      <category>docker</category>
    </item>
    <item>
      <title>Packaging with CMake CPack and NSIS on Windows</title>
      <dc:creator>David Velho</dc:creator>
      <pubDate>Tue, 27 Apr 2021 10:06:35 +0000</pubDate>
      <link>https://dev.to/theprogrammerdavid/packaging-with-cmake-cpack-and-nsis-on-windows-4gnb</link>
      <guid>https://dev.to/theprogrammerdavid/packaging-with-cmake-cpack-and-nsis-on-windows-4gnb</guid>
      <description>&lt;p&gt;Assuming you have your base project(ABC) setup with CMake, let's get started. &lt;/p&gt;

&lt;p&gt;Download and Install &lt;code&gt;NSIS&lt;/code&gt; from &lt;a href="https://nsis.sourceforge.io/Download"&gt;here&lt;/a&gt;. We'll need this to use CPack with NSIS.&lt;/p&gt;

&lt;p&gt;Let's add an icon to our built application by creating a file called &lt;code&gt;abc.rc&lt;/code&gt; which is a &lt;code&gt;resource file&lt;/code&gt; used by MSVCC to apply icons, among other stuff.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IDI_ICON1               ICON        DISCARDABLE            "abc.ico"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this definition to our &lt;code&gt;add_executable&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;abc 
&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ABC_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/assets/abc.rc
&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SOURCES&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 
&lt;span class="c1"&gt;# other stuff&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we need to define our install targets that CPack will pick up on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;install&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;TARGETS abc 
         &lt;span class="c1"&gt;#other stuff&lt;/span&gt;
         DESTINATION bin
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, bin is any folder you want to put your built application in. In this case, running the installer will install &lt;code&gt;abc.exe&lt;/code&gt; into &lt;code&gt;C:\Program Files(x86)\abc\bin\abc.exe&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Normally, you would set the install target's &lt;code&gt;DESTINATION&lt;/code&gt; to &lt;code&gt;${CMAKE_INSTALL_PREFIX}&lt;/code&gt;. However, CPack will give you an error :&lt;br&gt;
&lt;code&gt;&lt;br&gt;
ABSOLUTE path INSTALL DESTINATION forbidden (by caller):&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After what seemed like an eternity of google searching, I came across &lt;a href="https://cmake.org/pipermail/cmake/2013-May/054656.html"&gt;a solution&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are trying to install some files using an ABSOLUTE path DESTINATION.&lt;br&gt;
99.999% of the time this is an error on the Windows platform.&lt;/p&gt;

&lt;p&gt;Normally you should be installing files to a RELATIVE path DESTINATION.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Cpack Config
&lt;/h2&gt;

&lt;p&gt;Additional stuff that you can configure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;    &lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;InstallRequiredSystemLibraries&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_PACKAGE_INSTALL_DIRECTORY &lt;span class="s2"&gt;"
    set(CPACK_GENERATOR "&lt;/span&gt;NSIS&lt;span class="s2"&gt;")
    set(CPACK_PACKAGE_NAME &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROJECT_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)
    set(CPACK_PACKAGE_VERSION "&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ABC_VERSION_MAJOR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;.&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ABC_VERSION_MINOR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;")
    set(CPACK_PACKAGE_VERSION_PATCH "&lt;/span&gt;0&lt;span class="s2"&gt;")
    set(CPACK_PACKAGE_VENDOR "&lt;/span&gt;David Velho&lt;span class="s2"&gt;")
    set (CPACK_NSIS_MODIFY_PATH "&lt;/span&gt;ON&lt;span class="s2"&gt;")
    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROJECT_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)
    set(CPACK_SOURCE_GENERATOR "&lt;/span&gt;TGZ&lt;span class="s2"&gt;")
    set(CPACK_SOURCE_PACKAGE_FILE_NAME "&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CPACK_PACKAGE_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;-&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CPACK_PACKAGE_VERSION&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;")
    set(CPACK_SOURCE_IGNORE_FILES &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CPACK_IGNORE_FILES&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some additional fields&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_INSTALLED_ICON_NAME &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ABC_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/assets/abc.ico"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_HELP_LINK &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APP_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_URL_INFO_ABOUT &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APP_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_CONTACT &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APP_EMAIL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_CREATE_ICONS_EXTRA
    &lt;span class="s2"&gt;"CreateShortCut '$SMPROGRAMS&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;$STARTMENU_FOLDER&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;abc.lnk' '$INSTDIR&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;bin&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;abc.exe' "&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's give the generated installer an icon&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPACK_NSIS_MUI_ICON &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ABC_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/assets/abc.ico"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And last, the NSIS installer script that CMake will read from and substitute the values into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_MODULE_PATH  &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROJECT_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/assets/nsis &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MODULE_PATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;assets/nsis&lt;/code&gt; has a file called &lt;code&gt;NSIS.definitions.nsh.in&lt;/code&gt; which is a script file needed by NSIS. CMake will read this file and substitute the values in so that &lt;code&gt;NSIS&lt;/code&gt; can read it&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NSIS.definitions.nsh.in&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!define VERSION "@APP_VERSION@"
!define APP_VERSION "@APP_VERSION@"
!define APP_NAME "@APP_NAME@"
!define EXE_NAME "@EXE_NAME@"
!define README_FILE "README"
!define LICENSE_FILE "@PROJECT_SOURCE_DIR@resourcestextLICENSE"
!define MUI_ICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico"
!define MUI_UNICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp"
!define PATCH  "0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's include &lt;code&gt;CPack&lt;/code&gt; and some NSIS config files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;    &lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CPack&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;configure_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROJECT_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/assets/nsis/NSIS.definitions.nsh.in
    &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_CURRENT_BINARY_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/assets/nsis/NSIS.definitions.nsh
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you've added &lt;code&gt;CMake&lt;/code&gt; to &lt;code&gt;PATH&lt;/code&gt; during installation, you should have &lt;code&gt;cpack&lt;/code&gt; in path. You can (while in the build directory) build the installer with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;build
&lt;span class="nb"&gt;cd &lt;/span&gt;build
cmake &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Release ..
MSBuild.exe abc.sln
cpack &lt;span class="nt"&gt;-C&lt;/span&gt; Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cmake.org/cmake/help/latest/cpack_gen/nsis.html"&gt;CPack NSIS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://crascit.com/2015/08/07/cmake_cpack_nsis_shortcuts_with_parameters/"&gt;CPack Start Menu Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://embeddeduse.com/2020/03/21/creating-simple-installers-with-cpack/"&gt;CMake CPack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://foonathan.net/2016/07/cmake-dependency-handling/"&gt;CMake tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://martinrotter.github.io/it-programming/2014/05/09/integrating-nsis-cmake/"&gt;CMake NSIS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cmake.org/pipermail/cmake/2013-May/054656.html"&gt;Absolute Path CPack error fix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cmake</category>
      <category>nsis</category>
      <category>cpack</category>
      <category>windows</category>
    </item>
    <item>
      <title>Not so pro tips for mail-in-a-box users</title>
      <dc:creator>David Velho</dc:creator>
      <pubDate>Wed, 14 Oct 2020 15:17:40 +0000</pubDate>
      <link>https://dev.to/theprogrammerdavid/not-so-pro-tips-for-mail-in-a-box-users-5dnh</link>
      <guid>https://dev.to/theprogrammerdavid/not-so-pro-tips-for-mail-in-a-box-users-5dnh</guid>
      <description>&lt;p&gt;Disclaimer: I am in no way a professional. I'm just a student who has had the (un)fortunate experience of maintaining a mailinabox server. I thought i would share my experiences along the way so that i may save some time for those looking for it.&lt;br&gt;
I've used DigitalOcean here , but similar steps can be followed with your cloud provider of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  I want to move Mail-in-a-box to another Digital Ocean account (The Shortcut, but not recommended)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you have any important data, be sure to always keep a backup&lt;/li&gt;
&lt;li&gt;Create a snapshot of your droplet (you can power off the droplet after the snapshot)&lt;/li&gt;
&lt;li&gt;Change the owner of your snapshot, see &lt;a href="https://www.digitalocean.com/docs/images/snapshots/how-to/change-owners/"&gt;this guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Resume the transferred snapshot&lt;/li&gt;
&lt;li&gt;Change the DNS records to point to the new droplet&lt;/li&gt;
&lt;li&gt;Log into the web admin panel at /admin . If there are no errors, everything is good.
If there are errors (red text), re-install Mail-in-a-box&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do i re-install Mail-in-a-box ? (Unofficial, however, this should work in most cases)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Delete the mailinabox directory commonly located at ~/mailinabox&lt;/li&gt;
&lt;li&gt;Rename the

&lt;code&gt;/etc/nginx/conf.d/local.conf&lt;/code&gt;

to

&lt;code&gt;/etc/nginx/conf.d/local.conf.deleted&lt;/code&gt;

if you would want a copy
- Rename the

&lt;code&gt;/etc/nginx/conf.d/ssl.conf&lt;/code&gt;

to

&lt;code&gt;/etc/nginx/conf.d/ssl.conf.deleted&lt;/code&gt;

if you want to keep a copy
- Restart nginx

&lt;code&gt;systemctl reload nginx&lt;/code&gt;

.
- Run the installer from the official website and once its done, everything should continue to work as normal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  BCC-ing people: (credits &lt;a href="https://gist.github.com/namsnath/8b23394967d202e126c3539cd391ac88"&gt;namsnath&lt;/a&gt; )
&lt;/h2&gt;

&lt;h3&gt;
  
  
  BCC all mails sent to a given address:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;nano /etc/postfix/main.cnf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;add to the end: &lt;code&gt;sender_bcc_maps = hash:/etc/postfix/sender_bcc_maps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nano /etc/postfix/sender_bcc_maps&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add lines in this format: &lt;code&gt;&amp;lt;sender@email.com&amp;gt; &amp;lt;bcc@email.com&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  BCC all mails recieved on a given address:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nano /etc/postfix/main.cnf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;add to the end: &lt;code&gt;recipient_bcc_maps = hash:/etc/postfix/recipient_bcc_maps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nano /etc/postfix/recipient_bcc_maps&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add lines in this format: &lt;code&gt;&amp;lt;recipient@email.com&amp;gt; &amp;lt;bcc@email.com&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fancy Skins:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/EstudioNexos/mabola"&gt;Custom Roundcube skin installation guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mailinabox</category>
      <category>smtp</category>
    </item>
  </channel>
</rss>
