<?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: Amin Khozaei</title>
    <description>The latest articles on DEV Community by Amin Khozaei (@khozaei).</description>
    <link>https://dev.to/khozaei</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%2F187597%2F83746bd5-dcaa-4a30-8f2d-626246204fe9.jpg</url>
      <title>DEV Community: Amin Khozaei</title>
      <link>https://dev.to/khozaei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khozaei"/>
    <language>en</language>
    <item>
      <title>Reproducible Dev Environments</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Thu, 13 Nov 2025 15:02:36 +0000</pubDate>
      <link>https://dev.to/khozaei/reproducible-dev-environments-10mk</link>
      <guid>https://dev.to/khozaei/reproducible-dev-environments-10mk</guid>
      <description>&lt;p&gt;Modern projects need consistent, repeatable environments across developer machines, CI, and production. Discrepancies between development, testing, and production environments can lead to countless hours of debugging, configuration drift, and frustrating deployment failures. The core challenge is ensuring that every developer, and every server, is working with the exact same set of tools, libraries, and dependencies.&lt;/p&gt;

&lt;p&gt;This post explains the ideas behind Nix and Flakes first, then shows how Devbox lets you use those ideas day to day, &lt;strong&gt;without writing Nix expressions&lt;/strong&gt;, and how direnv turns it into a seamless, per‑directory experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Nix
&lt;/h2&gt;

&lt;p&gt;Nix represents a paradigm shift in package management by utilizing the principles of functional programming to achieve deterministic, reproducible software environments. Unlike traditional systems like &lt;code&gt;apt&lt;/code&gt; that modify a global state, Nix manages packages in a purely functional way. This means builds are isolated, dependencies are version-controlled, and state does not interfere across installations. This approach enhances reliability and simplifies configuration management by allowing entire environments to be rolled back, rebuilt, or replicated with precision.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1. Core Concepts
&lt;/h3&gt;

&lt;p&gt;Central to Nix’s philosophy is the concept of immutability. In computing, immutability refers to the inability to modify a data object after its creation. In the context of Nix, this means software packages and configurations are never altered once they are built. Each package is associated with a unique identifier, derived from applying a cryptographic hash function to its source code and all its dependencies. This approach ensures that identical builds always produce identical outputs, leading to perfect reproducibility across systems.&lt;/p&gt;

&lt;p&gt;A key feature of the Nix package manager is its use of a store, typically located at &lt;code&gt;/nix/store&lt;/code&gt;. This directory holds all installed packages. Packages are stored in paths determined by hashing their build instructions and dependencies, ensuring that identical configurations always yield identical paths. For example, a specific version of gcc might live at a path like &lt;code&gt;/nix/store/s66j5b...-gcc-11.3.0/&lt;/code&gt;. This thorough approach prevents unplanned modifications or interferences, offering a robust foundation for any reproducible build system.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2. Installing Nix
&lt;/h3&gt;

&lt;p&gt;The installation process for Nix varies slightly depending on your operating system. The recommended method is to use the official installer from the &lt;a href="https://nixos.org/download/" rel="noopener noreferrer"&gt;Nix Package Manager&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  1.2.1. Linux
&lt;/h4&gt;

&lt;p&gt;If you are on Linux running &lt;code&gt;systemd&lt;/code&gt;, use Multi-user installation (with &lt;code&gt;root&lt;/code&gt; permission):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-L&lt;/span&gt; https://nixos.org/nix/install&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--daemon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, use Single-user installation (with normal user):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-L&lt;/span&gt; https://nixos.org/nix/install&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--no-daemon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.2.2. MacOS
&lt;/h4&gt;

&lt;p&gt;On MacOS, the only available option is Multi-user, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-L&lt;/span&gt; https://nixos.org/nix/install&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.2.3. Windows
&lt;/h4&gt;

&lt;p&gt;Implementation on Windows environments is markedly different. Windows users need to use the Windows Subsystem for Linux (WSL), which provides a Linux kernel interface within a Windows environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, you are required to enable WSL through Windows PowerShell with administrative privileges:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--install&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Following the WSL installation, you must install a Linux distribution, such as Ubuntu, from the Microsoft Store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upon launching the installed Linux distribution, you can perform the Linux-based installation as described in section &lt;code&gt;1.2.1&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installation, you may need to source the Nix script in your shell's configuration file (e.g., .zshrc, .bashrc) to make the nix command available in new terminal sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3. Creating Isolated Environments with &lt;code&gt;nix-shell&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An essential feature of Nix is the ability to define temporary, isolated environments called Nix shells. This is done by creating a shell.nix file in your project directory. This file declaratively lists all the packages your project needs.&lt;/p&gt;

&lt;p&gt;Let's create a simple &lt;code&gt;shell.nix&lt;/code&gt; file that provides the &lt;code&gt;hello&lt;/code&gt; utility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="c"&gt;# shell.nix&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkShell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# buildInputs is the list of packages you want in your environment.&lt;/span&gt;
  &lt;span class="nv"&gt;buildInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; 
    &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;hello&lt;/span&gt; 
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c"&gt;# shellHook is a script that runs when you enter the shell.&lt;/span&gt;
  &lt;span class="nv"&gt;shellHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;    export MY_VAR="Hello, Nix!"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  ''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To activate this environment, navigate to the project directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix-shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your shell prompt will change, indicating you are now inside the Nix shell. Here, the &lt;code&gt;hello&lt;/code&gt; command is available, and the &lt;code&gt;MY_VAR&lt;/code&gt; environment variable is set.&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="o"&gt;[&lt;/span&gt;nix-shell:~/my-project]&lt;span class="nv"&gt;$ &lt;/span&gt;hello
Hello, world!

&lt;span class="o"&gt;[&lt;/span&gt;nix-shell:~/my-project]&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$MY_VAR&lt;/span&gt;
Hello, Nix!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you exit the shell (&lt;code&gt;exit&lt;/code&gt;), your original environment is restored, and &lt;code&gt;hello&lt;/code&gt; is no longer in your &lt;code&gt;PATH&lt;/code&gt;. This powerful feature ensures that project dependencies don't pollute your global system.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Nix Flakes
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;nix-shell&lt;/code&gt; is powerful, it has some reproducibility issues. For instance, import  {} points to a "channel" of packages on your system that can change over time, meaning your &lt;code&gt;shell.nix&lt;/code&gt; file could produce different environments on different days or different machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flakes&lt;/strong&gt; are the modern solution to this problem. They are a new feature in Nix designed to improve reproducibility, composability, and usability. Flakes allow hermetic, reproducible evaluation of multi-repository Nix projects, impose a discoverable standard structure, and replace older mechanisms like Nix channels.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Anatomy of a Flake
&lt;/h3&gt;

&lt;p&gt;A flake is simply a directory containing a &lt;code&gt;flake.nix&lt;/code&gt; file. This file has a standardized structure with two main sections: &lt;code&gt;inputs&lt;/code&gt; and &lt;code&gt;outputs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;inputs&lt;/code&gt;: These are the dependencies of your flake. They can be other flakes, such as the official &lt;code&gt;nixpkgs&lt;/code&gt; repository, and are pinned to a specific Git commit.&lt;br&gt;
&lt;code&gt;outputs&lt;/code&gt;: These are the things your flake provides, such as packages, development shells (&lt;code&gt;devShells&lt;/code&gt;), or NixOS configurations.&lt;br&gt;
All flake inputs are pinned to specific revisions in a lockfile called &lt;code&gt;flake.lock&lt;/code&gt;. This file, which is automatically generated and updated, ensures that every evaluation of the flake uses the exact same versions of its dependencies, achieving true reproducibility.&lt;/p&gt;

&lt;p&gt;If you've worked with JavaScript (&lt;code&gt;package.json&lt;/code&gt;/&lt;code&gt;package-lock.json&lt;/code&gt;), Go (&lt;code&gt;go.mod&lt;/code&gt;/&lt;code&gt;go.sum&lt;/code&gt;), or Rust (&lt;code&gt;Cargo.toml&lt;/code&gt;/&lt;code&gt;Cargo.lock&lt;/code&gt;), this concept will feel very familiar. &lt;code&gt;flake.nix&lt;/code&gt; is like &lt;code&gt;package.json&lt;/code&gt;, describing the project, and &lt;code&gt;flake.lock&lt;/code&gt; is like &lt;code&gt;package-lock.json&lt;/code&gt;, ensuring deterministic builds.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.2. Enabling Flakes
&lt;/h3&gt;

&lt;p&gt;Flakes are still considered an experimental feature, so you need to enable them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Temporarily: Add the &lt;code&gt;--experimental-features 'nix-command flakes'&lt;/code&gt; flag to any &lt;code&gt;nix&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Permanently (Recommended): Add the following line to your Nix configuration file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On Linux, this is typically &lt;code&gt;/etc/nix/nix.conf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On macOS, it's &lt;code&gt;~/.config/nix/nix.conf&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;experimental-features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;nix-command flakes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Devbox
&lt;/h2&gt;

&lt;p&gt;As you can see, Nix and Flakes provide a robust and powerful system for managing development environments. However, this power comes with a significant learning curve. Mastering the Nix language, which is a purely functional language, understanding its evaluation model, and learning the structure of &lt;code&gt;flake.nix&lt;/code&gt; can be a daunting task for developers who just want to install Python and get to work.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Devbox&lt;/strong&gt; comes in. Devbox is a command-line tool that simplifies the creation and management of isolated, reproducible development environments. It uses Nix and Flakes under the hood, but provides a simple, intuitive interface that feels familiar to anyone who has used tools like &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.1. Devbox Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible Environments with Nix&lt;/strong&gt;: Devbox uses Nix to create isolated environments. By specifying dependencies in a &lt;code&gt;devbox.json&lt;/code&gt; file, Devbox ensures that all team members and CI/CD systems run the same versions of every dependency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project-Specific Shell Environments&lt;/strong&gt;: When you activate a Devbox shell, you enter a dedicated environment where all project-specific dependencies and tools are available, isolated from your system’s global packages.
Shell Hooks for Enhanced Customization: Devbox supports shell hooks, which are commands that execute automatically when the environment starts. You can use them to initialize a database, load environment variables, or run setup scripts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Scripts for Task Automation&lt;/strong&gt;: You can define custom scripts in your &lt;code&gt;devbox.json&lt;/code&gt; to automate routine tasks like starting a dev server (&lt;code&gt;devbox run dev&lt;/code&gt;), running tests (&lt;code&gt;devbox run test&lt;/code&gt;), or building the project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic &lt;code&gt;devcontainer.json&lt;/code&gt; Generation for VSCode&lt;/strong&gt;: Devbox can generate a &lt;code&gt;devcontainer.json&lt;/code&gt; file, enabling seamless integration with VSCode’s Dev Containers feature. This is perfect for onboarding new developers or working in containerized setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Compatibility&lt;/strong&gt;: Devbox supports Linux, macOS, and Windows (via WSL), ensuring consistent environments across diverse operating systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3.2. Quickstart
&lt;/h3&gt;

&lt;p&gt;Devbox requires the Nix Package Manager. If Nix is not detected when running a command, Devbox will install it for you in single-user mode for Linux.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.jetify.com/devbox | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix-env &lt;span class="nt"&gt;-iA&lt;/span&gt; nixpkgs.devbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix profile &lt;span class="nb"&gt;install &lt;/span&gt;nixpkgs#devbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see how easy it is to create a deterministic shell with Devbox.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new directory and &lt;code&gt;cd&lt;/code&gt; to it and initialize devbox:
&lt;/li&gt;
&lt;/ul&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;dirbox
&lt;span class="nb"&gt;cd &lt;/span&gt;dirbox
devbox init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add command-line tools&lt;/strong&gt;. Let's add Python 3.10 and NodeJS 20. You can search for thousands of available packages on &lt;a href="https://www.nixhub.io/" rel="noopener noreferrer"&gt;Nixhub.io&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devbox add python@3.10 nodejs@22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;devbox.json&lt;/code&gt; file now tracks these packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"python@3.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"nodejs@22"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"init_hook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"echo 'Welcome to devbox!' &amp;gt; /dev/null"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Start a new shell that has these tools installed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devbox shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your shell prompt will change to indicate you're in the Devbox shell.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use your favorite tools. The versions you specified are now available in your &lt;code&gt;PATH&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;devbox&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; python &lt;span class="nt"&gt;--version&lt;/span&gt;
Python 3.10.19

&lt;span class="o"&gt;(&lt;/span&gt;devbox&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; node &lt;span class="nt"&gt;--version&lt;/span&gt;
v22.14.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your regular system tools and environment variables are also still available.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To exit the Devbox shell and return to your regular shell, simply run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;devbox&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In just a few commands, you've created a reproducible, isolated development environment without writing a single line of Nix code. Devbox handled the generation of the underlying Nix configuration for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Automating with Direnv
&lt;/h2&gt;

&lt;p&gt;Devbox makes creating environments easy, but you still have to remember to run &lt;code&gt;devbox shell&lt;/code&gt; every time you start working on a project. We can make this even smoother with direnv.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Direnv&lt;/strong&gt; is an extension for your shell that loads and unloads environment variables depending on your current directory. When you &lt;code&gt;cd&lt;/code&gt; into a directory with a &lt;code&gt;.envrc&lt;/code&gt; file, direnv automatically executes it, setting up your environment. When you cd out, it cleans up.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1. Why Is This Useful?
&lt;/h3&gt;

&lt;p&gt;An isolated environment per project is crucial for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency Version Mismatching: Your work project might need NodeJS 18, while a personal project uses NodeJS 20. Devbox solves this, and direnv automates switching between them.&lt;/li&gt;
&lt;li&gt;Application Settings: Environment variables like &lt;code&gt;DATABASE_URL&lt;/code&gt; or &lt;code&gt;HTTP_PROXY&lt;/code&gt; can be set automatically on a per-project basis.&lt;/li&gt;
&lt;li&gt;Secrets: API keys and other secrets can be loaded into your environment securely without hardcoding them.&lt;/li&gt;
&lt;li&gt;Compiler Options: Flags like &lt;code&gt;LDFLAGS&lt;/code&gt; or &lt;code&gt;JAVA_HOME&lt;/code&gt; can be configured specifically for the project you're working on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditionally, setting up direnv with Nix required writing a custom &lt;code&gt;.envrc&lt;/code&gt; file with a command like use nix. This, again, required some knowledge of the Nix ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2. Automatic Devbox Environments with Direnv
&lt;/h3&gt;

&lt;p&gt;The Devbox team created a seamless integration with direnv that removes this final piece of manual configuration. With this integration, you don't need to write any &lt;code&gt;.envrc&lt;/code&gt; files yourself.&lt;/p&gt;

&lt;p&gt;Here’s how to set it up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install direnv
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix-env &lt;span class="nt"&gt;-iA&lt;/span&gt; nixpkgs.direnv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For direnv to work properly it needs to be hooked into the shell. Each shell has its own extension mechanism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bash&lt;/strong&gt;: Add the following line at the end of the &lt;code&gt;~/.bashrc&lt;/code&gt; file:&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;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;direnv hook bash&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;&lt;strong&gt;zsh&lt;/strong&gt;: Add the following line at the end of the &lt;code&gt;~/.zshrc&lt;/code&gt; file:&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;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;direnv hook zsh&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;ul&gt;
&lt;li&gt;In your Devbox project directory, Generate the direnv integration file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devbox generate direnv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a &lt;code&gt;.envrc&lt;/code&gt; file with the content use devbox. You'll be prompted by direnv to allow it to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;direnv allow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Now, whenever you &lt;code&gt;cd&lt;/code&gt; into your project directory, your Devbox environment will be activated automatically. When you &lt;code&gt;cd&lt;/code&gt; out, it will be unloaded. You get a fully automated, reproducible, and isolated development environment with almost zero effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fj4vj5nnd12hcq4jwu16p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fj4vj5nnd12hcq4jwu16p.png" alt="Nix Mastery: Reproducible Systems and Functional Package Management" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://books.google.at/books?id=7uYrEQAAQBAJ" rel="noopener noreferrer"&gt;Johnson, R. (2024). Nix Mastery: Reproducible Systems and Functional Package Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nixos.wiki/wiki/Flakes" rel="noopener noreferrer"&gt;Flakes wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nix.dev/concepts/flakes.html" rel="noopener noreferrer"&gt;Flakes - nix.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tweag/rfcs/blob/flakes/rfcs/0049-flakes.md" rel="noopener noreferrer"&gt;Flakes - RFC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zero-to-nix.com/concepts/flakes/" rel="noopener noreferrer"&gt;Flakes - zero-to-nix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://serokell.io/blog/practical-nix-flakes" rel="noopener noreferrer"&gt;Flakes - serokell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xeiaso.net/blog/nix-flakes-1-2022-02-21/" rel="noopener noreferrer"&gt;Flakes - xeiaso&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nixos-and-flakes.thiscute.world/nixos-with-flakes/introduction-to-flakes" rel="noopener noreferrer"&gt;Flakes - thiscute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Devbox - Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jetify.com/docs/devbox" rel="noopener noreferrer"&gt;Devbox - homepage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/vafion/devbox-a-user-friendly-approach-to-reproducible-development-environments-with-nix-83dbcd0ab8d8" rel="noopener noreferrer"&gt;Devbox - medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nixhub.io/" rel="noopener noreferrer"&gt;Devbox - package repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://direnv.net/" rel="noopener noreferrer"&gt;Direnv - homepage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jetify.com/blog/automated-dev-envs-with-devbox-and-direnv" rel="noopener noreferrer"&gt;Direnv - jetify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devbox</category>
      <category>development</category>
      <category>nix</category>
      <category>flake</category>
    </item>
    <item>
      <title>PlatformIO: A Better Way to Code for STM32 Microcontrollers</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Thu, 05 Dec 2024 20:21:14 +0000</pubDate>
      <link>https://dev.to/khozaei/platformio-a-better-way-to-code-for-stm32-microcontrollers-2iki</link>
      <guid>https://dev.to/khozaei/platformio-a-better-way-to-code-for-stm32-microcontrollers-2iki</guid>
      <description>&lt;h2&gt;
  
  
  1. STM32 Microcontrollers
&lt;/h2&gt;

&lt;p&gt;The STM32 series is a popular, affordable, and high-performance family of microcontrollers. They enjoy extensive support from various development software suites tailored for microcontrollers. STM32 microcontrollers provide numerous peripherals that can be connected to a wide range of electronic components, such as sensors, displays, and electric motors. &lt;/p&gt;

&lt;p&gt;The performance range of STM32 microcontrollers is quite broad. The most basic models, like the STM32F0 and STM32F1 series, start with a clock frequency of 24 MHz and are available in packages with as few as 16 pins. In contrast, the STM32H7 series can operate at speeds of up to 400 MHz and comes in packages with 240 pins. Additionally, the STM32L series is specifically designed for low-power applications that run on small batteries.&lt;/p&gt;

&lt;p&gt;To develop code, program the microcontroller, and debug applications, development software is necessary. This software suite should include a compiler, a debugger, and an in-circuit serial programmer (ICSP).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo37pjosw3pl5r0bg4vha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo37pjosw3pl5r0bg4vha.png" alt="ICSP programmer diagram" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. PlatformIO
&lt;/h2&gt;

&lt;p&gt;PlatformIO supports a wide range of platforms, architectures, and frameworks, offering modern development capabilities. It is available as an extension in VSCode, making it easy to install and configure with just a few clicks. &lt;/p&gt;

&lt;p&gt;To install it, launch VSCode and navigate to the Extensions screen by pressing Ctrl+Shift+X. In the marketplace search bar, type "platformio." It will appear at the top of the search results. Click the Install button, and you're all set!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxo6siw4x6s6pzsytjcep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxo6siw4x6s6pzsytjcep.png" alt="Installing PlatformIO" width="800" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a few minutes, the installation is complete, and we now have PlatformIO installed in the VSCode IDE. PlatformIO offers some unique features, the most notable being its declarative development environment. With PlatformIO, we only need to specify the components we will use in our project, including the chip type, the framework, the version of that framework, and any additional libraries with their version constraints. We'll explore the meaning of these components and how to configure a project shortly. Additionally, PlatformIO provides all the essential tools needed for developing embedded projects, such as debugging, unit testing, static code analysis, and firmware memory inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ST-LINK
&lt;/h2&gt;

&lt;p&gt;The ST-LINK debugger is a versatile in-circuit debugger and programmer designed for STM32 microcontrollers, developed by STMicroelectronics. It provides a seamless interface for debugging and programming STM32 devices through the SWD (Serial Wire Debug) or JTAG interfaces. The ST-LINK is widely used in development environments due to its compatibility with popular IDEs such as STM32CubeIDE and Keil MDK. It offers features like real-time debugging, breakpoints, and flash programming. Its compact design and ease of use make it an essential tool for developers working with STM32 microcontrollers, facilitating efficient development and troubleshooting of embedded applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Prepare ST-LINK on Linux
&lt;/h3&gt;

&lt;p&gt;In  order for OpenOCD to properly access and communicate with USB devices on Linux, it’s essential to add a custom udev rule. By default, OpenOCD  may not have the necessary permissions to interact with USB devices like ST-Link. The udev rule grants the appropriate permissions to  these devices, ensuring that OpenOCD can successfully connect to them.  To do this, you need to create a udev rule file in the /etc/udev/rules.d/ directory, specifying the correct vendor and product IDs of the  connected debugger.&lt;/p&gt;

&lt;p&gt;By executing the command below, we can find information about our device, including the vendor ID and product ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsusb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fmmt5vpzf0bd50qwxvrpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmmt5vpzf0bd50qwxvrpt.png" alt="lsusb output" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now utilize the device information to create a rule in udev with the following content.&lt;/p&gt;

&lt;p&gt;file: /etc/udev/rules.d/99-openocd.rules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Simple LED Blink and USART Project
&lt;/h2&gt;

&lt;p&gt;The blinking LED is often referred to as the “Hello World” of embedded systems because it allows you to verify the basic functionality of the hardware while also providing immediate, visual feedback. When your LED blinks correctly, it means the system is initialized properly and you have control over the microcontroller’s peripherals.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1. Go to the PlatformIO Home screen.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fig9fr9eq8j2erwm8z844.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fig9fr9eq8j2erwm8z844.png" alt="PlatformIO Home" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2. Click on the New Project button on the right of the same screen.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffwq23wgyirtr6c4i6rej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffwq23wgyirtr6c4i6rej.png" alt="Quick access buttons on the PlatformIO Home" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3. PlatformIO Project Wizard
&lt;/h3&gt;

&lt;p&gt;A pop-up window appears. Set the project name, select &lt;strong&gt;BlackPill F103C8 (Generic)&lt;/strong&gt; for the board, and specify the framework as &lt;strong&gt;STM32Cube&lt;/strong&gt; Development Framework. You can choose a directory for the project or leave it at the PlatformIO default. Click on Finish to let PlatformIO do its job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fy2ahjn356q1vrraj4pg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy2ahjn356q1vrraj4pg2.png" alt="PlatformIO Project Wizard" width="587" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4. Directory Structure
&lt;/h3&gt;

&lt;p&gt;When the project is created, we have the following directory structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flt0pjulsc2fjrhnurmpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flt0pjulsc2fjrhnurmpi.png" alt="Directory Structure" width="335" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.5. Peripheral Configuration in STM32CubeMX
&lt;/h3&gt;

&lt;p&gt;STM32CubeMX is an essential tool for anyone working with STM32 microcontrollers. It greatly simplifies the process of configuring microcontroller peripherals and generating initialization code. Without STM32CubeMX, you would have to manually configure each peripheral, set up the clock system, manage pin mappings, and handle low-level register manipulations, all of which can be error-prone and time-consuming.&lt;/p&gt;

&lt;p&gt;With STM32CubeMX, you get a graphical interface that streamlines the configuration process, making it easier to start your development work.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.5.1. Clock Configuration
&lt;/h4&gt;

&lt;p&gt;The Black Pill STM32F103C8 board, which is based on the STM32F103C8 microcontroller, provides several clock sources to operate the system clock and its peripherals.&lt;/p&gt;

&lt;p&gt;To achieve a system clock frequency of 72 MHz on the STM32F103C8, you should utilize the Phase-Locked Loop (PLL) along with the High-Speed External (HSE) oscillator as the input clock source.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6f3mipo8si7wlsvgt72i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6f3mipo8si7wlsvgt72i.png" alt="High-Speed External" width="637" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in the clock configuration choose 72 MHz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6bau9rv6znaa9qonb3sj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6bau9rv6znaa9qonb3sj.png" alt="Clock Configuration" width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4.5.2. Pin Configuration
&lt;/h4&gt;

&lt;p&gt;For this project we used PB7 GPIO pin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzqw0c3vbaszmokdgpwl6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzqw0c3vbaszmokdgpwl6.png" alt="Pin Configuration" width="398" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4.5.3. USART Configuration
&lt;/h4&gt;

&lt;p&gt;For this project we used USART1 to sending message from microcontroller. You should Configuring PA9 and PA10 for RX and TX.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F52t5h77qv3wwrew0qmtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F52t5h77qv3wwrew0qmtm.png" alt="USART Configuration" width="430" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After Configuring PA9 and PA10 you should select USART mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftisccq0mncvgscnpxp73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftisccq0mncvgscnpxp73.png" alt="USART mode" width="638" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4.5.4. Code Generating
&lt;/h4&gt;

&lt;p&gt;After configuring the microcontroller, you can generate the necessary initialization code. This code typically involves setting up the clock configuration registers to select the HSE as the PLL source and configuring the PLL multiplier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa0tfj4pu5jhujw8aop1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa0tfj4pu5jhujw8aop1a.png" alt="Code Generating" width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4.5.5. Generated Code Structure
&lt;/h4&gt;

&lt;p&gt;The generated code structure is something like the following figure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fztkpo6lg2rghqu9nxvnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fztkpo6lg2rghqu9nxvnw.png" alt="Generated Code Structure" width="333" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the PlatformIO project, we only need the &lt;code&gt;Inc&lt;/code&gt; and &lt;code&gt;Src&lt;/code&gt; folders in the &lt;code&gt;Core&lt;/code&gt; directory. Copy them from the current location to the corresponding directory in the PlatformIO project structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.6. Coding
&lt;/h3&gt;

&lt;p&gt;The generated code includes multiple comments that guide us on how to modify and add our own code. To achieve our goal, we need to locate the main function, which signifies the start of the program. Inside the main function, we should find the while loop and incorporate the LED toggling logic within it, along with a delay to blink the LED connected to pin B7. Additionally, before entering the while loop, we should send the message "Hello dev.to" at the beginning of the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE BEGIN 1 */&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE END 1 */&lt;/span&gt;

  &lt;span class="cm"&gt;/* MCU Configuration--------------------------------------------------------*/&lt;/span&gt;

  &lt;span class="cm"&gt;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */&lt;/span&gt;
  &lt;span class="n"&gt;HAL_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE BEGIN Init */&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE END Init */&lt;/span&gt;

  &lt;span class="cm"&gt;/* Configure the system clock */&lt;/span&gt;
  &lt;span class="n"&gt;SystemClock_Config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE BEGIN SysInit */&lt;/span&gt;

  &lt;span class="cm"&gt;/* USER CODE END SysInit */&lt;/span&gt;

  &lt;span class="cm"&gt;/* Initialize all configured peripherals */&lt;/span&gt;
  &lt;span class="n"&gt;MX_GPIO_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;MX_USART1_UART_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="cm"&gt;/* USER CODE BEGIN 2 */&lt;/span&gt;
  &lt;span class="n"&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;huart1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"Hello dev.to"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="cm"&gt;/* USER CODE END 2 */&lt;/span&gt;

  &lt;span class="cm"&gt;/* Infinite loop */&lt;/span&gt;
  &lt;span class="cm"&gt;/* USER CODE BEGIN WHILE */&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIOB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GPIO_PIN_7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;HAL_Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="cm"&gt;/* USER CODE END WHILE */&lt;/span&gt;
    &lt;span class="cm"&gt;/* USER CODE BEGIN 3 */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="cm"&gt;/* USER CODE END 3 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HAL_GPIO_TogglePin:&lt;/strong&gt; This function toggles the state of the LED pin (turning the LED on and off).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HAL_Delay:&lt;/strong&gt; This introduces a 500ms delay between toggles, giving the LED a blinking effect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HAL_UART_Transmit:&lt;/strong&gt; This transmits the “Hello dev.to” string over USART1 to a connected serial terminal. The huart1 variable is automatically generated in STM32CubeMX and refers to the USART1 handler.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.7. Build and Run
&lt;/h3&gt;

&lt;p&gt;To build the project, you can use the build button, and to run it, you can click on the Upload button in the PlatformIO extension. Alternatively, you can use the following commands in the PlatformIO terminal emulator inside VSCode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pio run &lt;span class="nt"&gt;--environment&lt;/span&gt; blackpill_f103c8
pio run &lt;span class="nt"&gt;--target&lt;/span&gt; upload &lt;span class="nt"&gt;--environment&lt;/span&gt; blackpill_f103c8 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fb1kfgnn6oz8sdbean0om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fb1kfgnn6oz8sdbean0om.png" alt="Build and Run" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/khozaei/platformio_stm32" rel="noopener noreferrer"&gt;Project Source&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://platformio.org" rel="noopener noreferrer"&gt;PlatformIO&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.st.com" rel="noopener noreferrer"&gt;STMicroelectronics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pakdel, M. (2020). Advanced Programming with STM32 Microcontrollers. Elektor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F21pjulbf8tx0k1984nvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F21pjulbf8tx0k1984nvu.png" alt="Advanced Programming with STM32 Microcontrollers" width="583" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oner, V. O. (2021). Developing IoT Projects with ESP32: Automate your home or business with inexpensive Wi-Fi devices. Packt Publishing Ltd.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftcojyy8led82tux2z6ao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftcojyy8led82tux2z6ao.png" alt="Developing IoT Projects with ESP32" width="692" height="867"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>stm32</category>
      <category>microcontroller</category>
      <category>embedded</category>
      <category>platformio</category>
    </item>
    <item>
      <title>Automate Versioning with Git and CMake</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Tue, 12 Nov 2024 22:25:03 +0000</pubDate>
      <link>https://dev.to/khozaei/automating-semver-with-git-and-cmake-2hji</link>
      <guid>https://dev.to/khozaei/automating-semver-with-git-and-cmake-2hji</guid>
      <description>&lt;h2&gt;
  
  
  1. What is Software Versioning?
&lt;/h2&gt;

&lt;p&gt;Software versioning is the practice of assigning unique version numbers to different states or releases of software. This process helps track the software's development, including bug fixes and feature changes over time. It enables developers, teams, and users to understand how the software evolves, what new features have been added, which bugs have been resolved, and what improvements to stability or performance have been made in each release.&lt;/p&gt;

&lt;p&gt;Versioning is essential for preserving change histories, ensuring compatibility across various systems, managing dependencies, and providing clarity for end-users and other developers.&lt;/p&gt;

&lt;p&gt;Using a formal convention for software versioning is highly beneficial. Once a clear convention is established, it informs all stakeholders—both internal and external—about the software's current state. Without a standardized versioning system, version numbers become meaningless to users and ineffective for managing dependencies. A well-structured version number conveys important information about the version's purpose and the extent of the changes it includes. One widely adopted convention for software versioning is semantic versioning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fi55x7k5phw6qr2yrj4yy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fi55x7k5phw6qr2yrj4yy.png" alt="SemVer" width="800" height="819"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1. SemVer
&lt;/h3&gt;

&lt;p&gt;Semantic Versioning, often abbreviated as SemVer, is a versioning system used to manage and communicate the evolution of software over time. It provides a structured, predictable way to number software releases, making it clear to developers and users what kind of changes have been made in a particular release.&lt;/p&gt;

&lt;p&gt;The version number follows a three-part structure: &lt;strong&gt;MAJOR.MINOR.PATCH&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a version number could be 1.5.2, where:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 is the MAJOR version
5 is the MINOR version
2 is the PATCH version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  1.1.1. MAJOR version
&lt;/h4&gt;

&lt;p&gt;The MAJOR version is incremented when there are &lt;strong&gt;backward-incompatible&lt;/strong&gt; changes to the software. This means that changes are significant enough to  break existing functionality or APIs that depend on the previous  version.&lt;br&gt;
Examples of such changes include removing or renaming functions,  changing expected behavior, or modifying core components that affect the user interface or workflow.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; If you were to upgrade from &lt;strong&gt;1.0.0&lt;/strong&gt; to &lt;strong&gt;2.0.0&lt;/strong&gt;, this would indicate that the software has undergone significant changes that require users to adjust their workflows or code to remain  compatible.&lt;/p&gt;
&lt;h4&gt;
  
  
  1.1.2. MINOR version
&lt;/h4&gt;

&lt;p&gt;The MINOR version is incremented when &lt;strong&gt;backward-compatible&lt;/strong&gt; features are added to the software. This includes the addition of new features,  improvements to existing functionality, or changes that do not disrupt  the existing behavior or compatibility of the software.&lt;br&gt;
The key idea here is that users can safely update to the new minor  version without worrying about breaking their current workflows.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Upgrading from &lt;strong&gt;1.2.0&lt;/strong&gt; to &lt;strong&gt;1.3.0&lt;/strong&gt; signifies that new features or improvements were added, but the software remains fully compatible with older versions.&lt;/p&gt;
&lt;h4&gt;
  
  
  1.1.3. PATCH version
&lt;/h4&gt;

&lt;p&gt;The PATCH version is incremented when &lt;strong&gt;backward-compatible&lt;/strong&gt; bug fixes or minor improvements are made. These changes should not affect the software’s core functionality but are intended to fix issues like bugs, security vulnerabilities, or performance optimizations.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; If a release goes from &lt;strong&gt;1.5.2&lt;/strong&gt; to &lt;strong&gt;1.5.3&lt;/strong&gt;, it indicates that bug fixes or minor improvements have been made, but the core functionality of the software has not changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3ngqudli9bmdifdj9mxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3ngqudli9bmdifdj9mxk.png" alt="Pre-release Versions" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1.2. Pre-release Versions
&lt;/h3&gt;

&lt;p&gt;Pre-release versions are crucial for software testing and early feedback. Users and developers can install and test pre-release versions, report bugs, and give feedback before the final stable release.&lt;br&gt;
It’s important to note that pre-release versions are considered &lt;strong&gt;unstable&lt;/strong&gt;, and their behavior may change dramatically between versions. SemVer ensures that developers and users know when to expect such instability and to use these versions with caution.&lt;br&gt;
SemVer also allows for pre-release versions, which are versions of the software that are still under development and might be unstable. These versions can be labeled using a &lt;strong&gt;hyphen&lt;/strong&gt; followed by one or more identifiers.&lt;br&gt;
Pre-release versions are typically assigned to versions before the software is considered ready for general use. These versions can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alpha&lt;/strong&gt; versions, which are early-stage releases that may be incomplete and have many bugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beta&lt;/strong&gt; versions, which are more stable than alpha releases but still may have bugs and are intended for broader testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release candidate (RC)&lt;/strong&gt; versions, which are considered feature-complete and are under final testing before the full release.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  2. Automating SemVer with Git
&lt;/h2&gt;

&lt;p&gt;Utilizing Git for source code management alongside automated generation of Semantic Versioning (SemVer) numbers can significantly enhance the efficiency of development and release processes. By integrating Git with appropriate tools, organizations can automate versioning based on repository commits and tags. This methodology proves particularly beneficial for teams engaged in Continuous Integration and Continuous Deployment (CI/CD), promoting a more streamlined workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbkilh1i0mp8aw5by0c31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbkilh1i0mp8aw5by0c31.png" alt="Integrating SemVer with CMake" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2.1. Integrating SemVer with CMake
&lt;/h3&gt;

&lt;p&gt;Integrating semantic versioning with CMake provides a structured approach to ensuring that builds are consistently versioned in alignment with Git history. This practice is particularly beneficial for maintaining clarity and consistency across releases.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.1.1. Template Files
&lt;/h4&gt;

&lt;p&gt;In C/C++ projects, particularly when using build systems like CMake, template files serve as a way to automate the generation of source or header files with specific content that can be configured at build time.&lt;br&gt;
Template files are essentially placeholder files that contain variables or markers. These variables are replaced with specific values during the build process. This approach is useful for dynamically generating configuration headers, version files, or other source files that need to change based on the build context.&lt;br&gt;
Template files often have distinctive suffixes, such as &lt;strong&gt;.in&lt;/strong&gt;. The .in suffix helps developers and build systems recognize that a file is a template, not a regular source or header file. This suffix indicates that the file contains placeholders that need to be replaced with actual values during the build process.&lt;/p&gt;

&lt;p&gt;file: &lt;code&gt;version.h.in&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifndef GSMAPP_VERSION_H
#define GSMAPP_VERSION_H
&lt;/span&gt;
&lt;span class="cp"&gt;#define PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define PROJECT_VERSION "@PROJECT_VERSION@"
#define FULL_VERSION "@FULL_VERSION@"
&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Placeholders (@...@):&lt;/strong&gt; Each placeholder will be replaced by CMake (or any build system used) with the actual values specified in the CMake configuration process. For example, @PROJECT_VERSION_MAJOR@ might be replaced with 1, @PROJECT_VERSION_MINOR@ with 0, etc.&lt;/p&gt;

&lt;p&gt;file: &lt;code&gt;CMakeLists.txt&lt;/code&gt;&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;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;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/version.h.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;/version.h
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;configure_file&lt;/code&gt; command in CMake is used to read a template file, replace placeholders with actual values, and write the results to a new file.&lt;/p&gt;

&lt;p&gt;file: &lt;code&gt;CMakeLists.txt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;target_include_directories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PROJECT_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;PRIVATE&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CMAKE_CURRENT_BINARY_DIR&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CMake command target_include_directories specifies the include directories to be used by a target (typically an executable or a library) in a project.&lt;/p&gt;

&lt;h4&gt;
  
  
  2.2. Extract version information from a Git repository
&lt;/h4&gt;

&lt;p&gt;file: &lt;code&gt;cmake/GitVersion.cmake&lt;/code&gt;&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;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;get_version_from_git&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;Git QUIET&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;NOT Git_FOUND&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;WARNING &lt;span class="s2"&gt;"Git not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;return&lt;/span&gt;&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;execute_process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        COMMAND &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_EXECUTABLE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; describe --tags --always
        WORKING_DIRECTORY &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;
        OUTPUT_VARIABLE GIT_TAG
        OUTPUT_STRIP_TRAILING_WHITESPACE
        RESULT_VARIABLE GIT_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;NOT GIT_RESULT EQUAL 0&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;WARNING &lt;span class="s2"&gt;"Failed to get git tag"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;return&lt;/span&gt;&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;execute_process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        COMMAND &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_EXECUTABLE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; rev-parse --short=7 HEAD
        WORKING_DIRECTORY &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;
        OUTPUT_VARIABLE GIT_COMMIT_SHORT_HASH
        OUTPUT_STRIP_TRAILING_WHITESPACE
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;REGEX REPLACE &lt;span class="s2"&gt;"^v"&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; CLEAN_TAG &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_TAG&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;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CLEAN_TAG MATCHES &lt;span class="s2"&gt;"^([0-9]+)&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;.([0-9]+)&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;.([0-9]+)(-.*)?$"&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;PROJECT_VERSION_MAJOR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&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;PROJECT_VERSION_MAJOR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; PARENT_SCOPE&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;PROJECT_VERSION_MINOR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&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;PROJECT_VERSION_MINOR &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; PARENT_SCOPE&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;PROJECT_VERSION_PATCH &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&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;PROJECT_VERSION_PATCH &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; PARENT_SCOPE&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;FULL_VERSION &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_COMMIT_SHORT_HASH&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;FULL_VERSION &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_COMMIT_SHORT_HASH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; PARENT_SCOPE&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;PROJECT_VERSION &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&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;PROJECT_VERSION &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_MATCH_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; PARENT_SCOPE&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;else&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nb"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;WARNING &lt;span class="s2"&gt;"Tag '&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CLEAN_TAG&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' does not match semver format"&lt;/span&gt;&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;endfunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Finding Git:  Checks whether Git is installed and available. The &lt;code&gt;find_package(Git QUIET)&lt;/code&gt; command attempts to locate the Git executable without printing messages upon finding Git.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Obtaining the Git Tag: Uses the &lt;code&gt;git describe --tags --always&lt;/code&gt; command to retrieve the most descriptive version string possible, based on tags. This command returns the tag name or, if no tag is available, a commit hash.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting the Commit Hash: Retrieves the short hash of the current commit, limited to 7 characters. This is useful for constructing unique build identifiers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Processing the Tag: Removes a leading ‘v’ from the tag name to normalize it using &lt;code&gt;string(REGEX REPLACE "^v" "" CLEAN_TAG "${GIT_TAG}")&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Semantic Versioning Check: Checks if CLEAN_TAG matches a semantic versioning pattern (e.g., 1.0.0). It captures the major, minor, and patch versions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2.3. using our custom CMake module
&lt;/h4&gt;

&lt;p&gt;file: &lt;code&gt;CMakeLists.txt&lt;/code&gt;&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;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/cmake"&lt;/span&gt;&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;GitVersion&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;get_version_from_git&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Appending to CMAKE_MODULE_PATH: &lt;code&gt;CMAKE_MODULE_PATH&lt;/code&gt; is a list of directories that CMake uses to search for modules when processing &lt;code&gt;include()&lt;/code&gt; or &lt;code&gt;find_package()&lt;/code&gt; commands. This line adds a directory named cmake (located in the root source directory of the project) to the list of paths where CMake looks for custom modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Including the GitVersion Module: The include() command in CMake is used to include and run another CMake script or module file. This command will look for a file named &lt;code&gt;GitVersion.cmake&lt;/code&gt; in the directories listed in CMAKE_MODULE_PATH.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling get_version_from_git(): This function, defined within the included GitVersion.cmake, is called here to extract version information from the Git repository. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2.4. Printing Version Information
&lt;/h4&gt;

&lt;p&gt;This C code provides a simple function to print version information about an application, highlighting the use of versioning data integrated into the build process. &lt;/p&gt;

&lt;p&gt;file: &lt;code&gt;main.c&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"version.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;print_version&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Application Version: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROJECT_VERSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Full Version: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FULL_VERSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Version Details:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Major: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROJECT_VERSION_MAJOR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Minor: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROJECT_VERSION_MINOR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Patch: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROJECT_VERSION_PATCH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Build Date: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__DATE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Build Time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__TIME__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://semver.org" rel="noopener noreferrer"&gt;SemVer.org&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gitversion.net" rel="noopener noreferrer"&gt;gitversion.net&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Full project: &lt;a href="https://github.com/khozaei/gsmapp" rel="noopener noreferrer"&gt;gsmapp&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>semver</category>
      <category>cmake</category>
      <category>versioning</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Conan: Your Embedded Cross-Compilation Champion</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Sat, 13 Jul 2024 11:21:31 +0000</pubDate>
      <link>https://dev.to/khozaei/conan-your-embedded-cross-compilation-champion-5bb9</link>
      <guid>https://dev.to/khozaei/conan-your-embedded-cross-compilation-champion-5bb9</guid>
      <description>&lt;p&gt;In the continuously changing field of software development, modern programming languages such as Rust and Go have established new standards by integrating built-in package managers. These tools have greatly simplified the development process, allowing developers to easily handle dependencies, improve their workflows, and boost productivity. The convenience provided by these package managers underscores the necessity for a strong solution for C++ development.&lt;/p&gt;

&lt;p&gt;Conan is a revolutionary package manager created for C++ developers. Conan simplifies and streamlines package management within the C++ ecosystem, making library and dependency management easier than ever. One of Conan's standout features is its strong support for cross-compiling, which is essential for developers working on embedded systems and applications that target multiple architectures.&lt;/p&gt;

&lt;p&gt;Conan's cross-compiling capabilities simplify the development process by enabling developers to build and test their applications for different target environments from a single setup. This feature is especially beneficial for projects that need to run on various hardware configurations, ensuring compatibility and performance across the board.&lt;/p&gt;

&lt;p&gt;Moreover, Conan supports a wide range of libraries, offering a vast repository that developers can leverage to enhance their projects. This extensive library support ensures that developers have access to the tools and resources they need, reducing the time spent on configuring and managing dependencies.&lt;/p&gt;

&lt;p&gt;For organizations with specific requirements, Conan provides the flexibility to manage private packages using Artifactory Community Edition. This integration ensures that sensitive or proprietary packages remain secure and accessible only to authorized personnel, maintaining the integrity and confidentiality of the development process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsndkppb1u2jp0dqme4e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsndkppb1u2jp0dqme4e7.png" alt="CMake" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Integrate Conan as a Dependency Using CMake
&lt;/h2&gt;

&lt;p&gt;CMake's &lt;code&gt;FetchContent&lt;/code&gt; module is a powerful feature introduced in CMake 3.11 that allows you to download and incorporate external content (such as source code or scripts) directly into your build process. It is particularly useful for managing project dependencies without requiring pre-installed libraries or packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1. Key Features of &lt;code&gt;FetchContent&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Download and Include External Projects&lt;/strong&gt;: &lt;code&gt;FetchContent&lt;/code&gt; can download content from URLs, Git repositories, or local paths. This content can then be included in your build as if it were part of your source tree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: By specifying the exact URL or Git tag/branch/commit, you can ensure that your project always uses a specific version of the external content, providing stability and reproducibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Integration&lt;/strong&gt;: The fetched content can be automatically integrated into the CMake build system, making it straightforward to compile and link against the downloaded content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration and Customization&lt;/strong&gt;: You can configure the fetched content using CMake variables, enabling customization and fine-tuning of how the external content is built and used.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2. Resolve Canon Dependency in CMake
&lt;/h3&gt;

&lt;p&gt;To handle different host operating systems using CMake's FetchContent, you can conditionally fetch and configure dependencies based on the detected operating system. For our example, we focused on implementing it on a Linux host machine.&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;conan
URL https://github.com/conan-io/conan/releases/download/2.3.2/conan-2.3.2-linux-x86_64.tgz
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;FetchContent_Populate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;conan&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;conan_POPULATED&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;CONANEXE &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;conan_SOURCE_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conan&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;CONAN_AVAILABLE 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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fet2kgncl2wxe40tx8oni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fet2kgncl2wxe40tx8oni.png" alt="Configuration Profile" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Defining Profiles for Cross-Compiling
&lt;/h2&gt;

&lt;p&gt;In Conan, profiles are used to define settings, options, environment variables, and tools that should be used during the package creation and consumption process. When cross-compiling, it's essential to distinguish between the build and host profiles, and define appropriate toolchains for each.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Build Profile
&lt;/h3&gt;

&lt;p&gt;The build profile specifies the environment where the build tools will run. This is typically your native machine (e.g., x86_64 Linux) which compiles code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[settings]&lt;/span&gt;
&lt;span class="py"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;x86_64&lt;/span&gt;
&lt;span class="py"&gt;build_type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Release&lt;/span&gt;
&lt;span class="py"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gcc&lt;/span&gt;
&lt;span class="py"&gt;compiler.cppstd&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gnu17&lt;/span&gt;
&lt;span class="py"&gt;compiler.libcxx&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;libstdc++11&lt;/span&gt;
&lt;span class="py"&gt;compiler.version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;12&lt;/span&gt;
&lt;span class="py"&gt;os&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2. Host Profile
&lt;/h3&gt;

&lt;p&gt;The host profile specifies the environment where the compiled package will run. This can be a different architecture or platform, such as ARM for embedded systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[settings]&lt;/span&gt;
&lt;span class="py"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;armv8&lt;/span&gt;
&lt;span class="py"&gt;build_type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Release&lt;/span&gt;
&lt;span class="py"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;clang&lt;/span&gt;
&lt;span class="py"&gt;compiler.cppstd&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;17&lt;/span&gt;
&lt;span class="py"&gt;compiler.libcxx&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;libc++&lt;/span&gt;
&lt;span class="py"&gt;compiler.version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;12&lt;/span&gt;
&lt;span class="py"&gt;os&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;
&lt;span class="nn"&gt;[buildenv]&lt;/span&gt;
&lt;span class="py"&gt;CC&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/bin/clang&lt;/span&gt;
&lt;span class="py"&gt;CXX&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/bin/clang++&lt;/span&gt;
&lt;span class="py"&gt;LD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/bin/lld&lt;/span&gt;
&lt;span class="py"&gt;SYSROOT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/sysroot&lt;/span&gt;
&lt;span class="py"&gt;CXXFLAGS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;--sysroot=/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/sysroot&lt;/span&gt;
&lt;span class="py"&gt;CFLAGS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;--sysroot=/usr/local/mdc_sdk_llvm/dp_gea/mdc_cross_compiler/sysroot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fb0k67h237zx4pw79plye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fb0k67h237zx4pw79plye.png" alt="Third-Party Libraries" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Third-Party Libraries Using Conan
&lt;/h2&gt;

&lt;p&gt;Conan Center is a central repository of open-source packages, which includes a wide range of libraries ready to be integrated into your projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Searching for Libraries in Conan Center
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visit Conan Center&lt;/strong&gt;: Go to &lt;a href="https://conan.io/center" rel="noopener noreferrer"&gt;Conan Center&lt;/a&gt; to browse or search for libraries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search for a Library&lt;/strong&gt;: Use the search bar to find the library you need. For example, if you are looking for the &lt;code&gt;eigen&lt;/code&gt; library, type "eigen" in the search bar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select the Library&lt;/strong&gt;: Click on the library from the search results to view its details, including versions, available options, and usage instructions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2. Creating a &lt;code&gt;conanfile.txt&lt;/code&gt; File
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;conanfile.txt&lt;/code&gt; file is used to define the dependencies and configurations for your project. Here’s an example &lt;code&gt;conanfile.txt&lt;/code&gt; for a project that depends on &lt;code&gt;Eigen&lt;/code&gt; and &lt;code&gt;Boost&lt;/code&gt; libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[requires]&lt;/span&gt;
&lt;span class="err"&gt;eigen/3.4.0&lt;/span&gt;
&lt;span class="err"&gt;boost/1.85.0&lt;/span&gt;
&lt;span class="nn"&gt;[generators]&lt;/span&gt;
&lt;span class="err"&gt;CMakeDeps&lt;/span&gt;
&lt;span class="err"&gt;CMakeToolchain&lt;/span&gt;
&lt;span class="nn"&gt;[layout]&lt;/span&gt;
&lt;span class="err"&gt;cmake_layout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fzdsieb7ueqyyyfd4hzwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzdsieb7ueqyyyfd4hzwn.png" alt="CMake" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Integrating Conan with CMake
&lt;/h2&gt;

&lt;p&gt;Integrating Conan with CMake is a common practice to streamline dependency management in C++ projects. Conan handles the downloading and management of dependencies, while CMake orchestrates the build process.&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONAN_AVAILABLE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;execute_process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;COMMAND &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONANEXE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; install conanfile.txt --build=missing  --profile:build=conan.build --profile:host=conan.host
    WORKING_DIRECTORY &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="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;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;CMAKE_MODULE_PATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/Release/generators&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;conan_toolchain&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;Eigen3 REQUIRED&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;Boost REQUIRED COMPONENTS filesystem&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&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_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; main.cpp&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;target_link_libraries&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_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Eigen3::Eigen Boost::filesystem&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fpszyr7d2d65zyvkbi26t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpszyr7d2d65zyvkbi26t.png" alt="Libraries" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Use Libraries in Your Code
&lt;/h2&gt;

&lt;p&gt;Now you can include and use the &lt;code&gt;Eigen&lt;/code&gt; and &lt;code&gt;Boost&lt;/code&gt; libraries in your &lt;code&gt;main.cpp&lt;/code&gt; or other source files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Eigen/Dense&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/filesystem.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create a 2x2 matrix&lt;/span&gt;
  &lt;span class="n"&gt;Eigen&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MatrixXd&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Add another matrix&lt;/span&gt;
  &lt;span class="n"&gt;Eigen&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MatrixXd&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Print the resulting matrix&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Resulting matrix:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;my_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if the file exists&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;my_file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" exists."&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;my_file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" does not exist."&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a directory (if it doesn't exist)&lt;/span&gt;
  &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;my_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test_dir"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_dir&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;create_directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Created directory: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;my_dir&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.conan.io/2/" rel="noopener noreferrer"&gt;Conan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cmake.org/documentation/" rel="noopener noreferrer"&gt;CMake&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>conan</category>
      <category>cmake</category>
      <category>embedded</category>
      <category>crosscompile</category>
    </item>
    <item>
      <title>Design Patterns for C</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Sat, 29 Jun 2024 19:50:26 +0000</pubDate>
      <link>https://dev.to/khozaei/design-patterns-for-c-32an</link>
      <guid>https://dev.to/khozaei/design-patterns-for-c-32an</guid>
      <description>&lt;p&gt;In the world of programming languages, C may not have flashy interfaces or trendy web apps. But underneath the surface, C is a key player, powering many of the technologies we rely on every day. It's efficient and has the ability to directly engage with hardware, making it essential in creating the strong foundations for countless technologies, from the computers in our vehicles to the operating systems that manage our devices. Even video games depend on C for seamless gameplay and outstanding performance. While other languages may handle the visuals, C ensures that the engine operates smoothly.&lt;/p&gt;

&lt;p&gt;C's power and control come with complexity. Making large, maintainable C projects can be hard. Design patterns help with this. They are proven solutions to common design problems. They help bridge the gap between C's low-level nature and the need for well-structured code. Design patterns help you write cleaner, more readable C code that's easier for you and your team to understand and modify. They make your code flexible and adaptable to future changes. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. What is a design pattern?
&lt;/h2&gt;

&lt;p&gt;A design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system. These patterns focus on the relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved.&lt;/p&gt;

&lt;p&gt;Design patterns are typically classified into three main categories, each addressing a different aspect of software design:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creational Patterns:&lt;/strong&gt; These patterns concentrate on creating objects in a controlled and flexible manner, decoupling object creation from specific use to promote reusability and better control over object instantiation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structural Patterns:&lt;/strong&gt; These patterns focus on how classes and objects are organized to create larger structures and functionalities. They provide methods for dynamically altering the code structure or adding new functionalities without significant modifications to the existing code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral Patterns:&lt;/strong&gt; These patterns define how objects communicate with each other, enabling complex interactions and collaboration between different parts of your code. They promote loose coupling and improve the overall organization and maintainability of your software.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.1. Object-oriented Paradigm
&lt;/h3&gt;

&lt;p&gt;Design patterns are largely influenced by object-oriented programming (OOP) and are categorized using objects, although some patterns can be implemented without them. It is possible to apply design patterns in C by utilizing fundamental concepts such as functions, pointers, and structs. This can enhance code cleanliness and maintainability without relying on object-oriented features.&lt;/p&gt;

&lt;p&gt;Even though C lacks built-in object-oriented features like classes and inheritance, it can still achieve object-oriented-like behavior using clever techniques with functions, pointers, and structs. Popular libraries like GLib showcase this by implementing object-oriented features within the C language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fr2uzuc53wsj4tpwxwiox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fr2uzuc53wsj4tpwxwiox.png" alt="Creational Design Patterns" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Creational Patterns
&lt;/h2&gt;

&lt;p&gt;Creational design patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Factory design pattern
&lt;/h3&gt;

&lt;p&gt;It provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. The primary goal of the Factory pattern is to encapsulate the object creation process, making it more modular, scalable, and maintainable.&lt;/p&gt;

&lt;h4&gt;
  
  
  2.1.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulation of Object Creation&lt;/strong&gt;: The Factory pattern encapsulates the logic of creating objects, which means that the client code does not need to know the specific classes being instantiated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decoupling&lt;/strong&gt;: It decouples the code that uses the objects from the code that creates the objects, promoting loose coupling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: The pattern allows for adding new types of objects easily without changing the client code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2.1.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw_circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Drawing a Circle&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;draw_circle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw_square&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Drawing a Square&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Square&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_square&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Square&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Square&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;draw_square&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SHAPE_CIRCLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;SHAPE_SQUARE&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;ShapeType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;shape_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ShapeType&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;SHAPE_CIRCLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;create_circle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;SHAPE_SQUARE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;create_square&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nl"&gt;default:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a Circle using the factory&lt;/span&gt;
    &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;shape1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shape_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SHAPE_CIRCLE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape1&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;shape1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a Square using the factory&lt;/span&gt;
    &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;shape2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shape_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SHAPE_SQUARE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;shape2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2.1.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;libcurl&lt;/strong&gt; uses factory functions to create and initialize different types of handles for various I/O operations. This is essential for setting up the appropriate environment for the different kinds of operations it supports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;curl/curl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize CURL globally&lt;/span&gt;
    &lt;span class="n"&gt;curl_global_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURL_GLOBAL_DEFAULT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create and initialize an easy handle using the factory function&lt;/span&gt;
    &lt;span class="n"&gt;CURL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curl_easy_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Set options for the easy handle&lt;/span&gt;
        &lt;span class="n"&gt;curl_easy_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CURLOPT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"http://example.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;curl_easy_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CURLOPT_FOLLOWLOCATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Perform the transfer&lt;/span&gt;
        &lt;span class="n"&gt;CURLcode&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curl_easy_perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;CURLE_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"curl_easy_perform() failed: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curl_easy_strerror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Clean up the easy handle&lt;/span&gt;
        &lt;span class="n"&gt;curl_easy_cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;easy_handle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Clean up CURL globally&lt;/span&gt;
    &lt;span class="n"&gt;curl_global_cleanup&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2. Singleton Pattern
&lt;/h3&gt;

&lt;p&gt;This pattern is useful when exactly one object is needed to coordinate actions across a system. Common examples include configuration objects, connection pools, and logging mechanisms.&lt;/p&gt;

&lt;h4&gt;
  
  
  2.2.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Instance&lt;/strong&gt;: Ensures that only one instance of the struct is created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global Access&lt;/strong&gt;: Provides a global point of access to the instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lazy Initialization&lt;/strong&gt;: The instance is created only when it is needed for the first time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2.2.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Singleton structure&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Other members...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Static variable to hold the single instance&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Function to get the instance of the singleton&lt;/span&gt;
&lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;get_instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Initialize with default values&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to free the instance (optional, for cleanup)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;free_instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the singleton instance and use it&lt;/span&gt;
    &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton data: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the singleton instance again&lt;/span&gt;
    &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Singleton data: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;free_instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;static&lt;/code&gt; keyword in the statement &lt;code&gt;static Singleton* instance = NULL;&lt;/code&gt; makes the variable private to the file in C. This means that when included in other files, they can't access the &lt;code&gt;instance&lt;/code&gt; variable directly and must access it through corresponding functions. The &lt;code&gt;%p&lt;/code&gt; in the statement &lt;code&gt;printf("Singleton data: %p\n", s1);&lt;/code&gt; prints the address of the &lt;code&gt;s1&lt;/code&gt; variable.&lt;/p&gt;

&lt;h4&gt;
  
  
  2.2.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;Here's an example of using &lt;code&gt;GLib&lt;/code&gt;'s main loop in C to handle a simple timer event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;glib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;gboolean&lt;/span&gt; &lt;span class="nf"&gt;timer_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gpointer&lt;/span&gt; &lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Timer fired!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Keep the timer running&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;GMainLoop&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_main_loop_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Create the main loop&lt;/span&gt;

  &lt;span class="c1"&gt;// Set up a timer to fire every 1 second&lt;/span&gt;
  &lt;span class="n"&gt;guint&lt;/span&gt; &lt;span class="n"&gt;timer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_timeout_add_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GSourceFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;timer_callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting the main loop...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;g_main_loop_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Run the main loop&lt;/span&gt;

  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stopping the main loop...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;g_source_remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timer_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Remove the timer source&lt;/span&gt;
  &lt;span class="n"&gt;g_main_loop_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Free the loop resources&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fedhneos1byg2yvh29y5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fedhneos1byg2yvh29y5q.png" alt="Structural Design Pattern" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Structural Patterns
&lt;/h2&gt;

&lt;p&gt;Structural patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities. These patterns focus on how classes and objects are composed to form larger structures, providing solutions for creating flexible and efficient structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Adapter Patterns
&lt;/h3&gt;

&lt;p&gt;The Adapter design pattern, also known as Wrapper, is a structural pattern that allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces by converting the interface of a class into another interface that the client expects. This pattern is particularly useful when integrating existing components with new systems without modifying the existing components.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Target Interface&lt;/strong&gt;: The interface that the client expects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adaptee&lt;/strong&gt;: The existing interface that needs to be adapted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adapter&lt;/strong&gt;: A class that implements the target interface and translates the requests from the client to the adaptee.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.1.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Old printer interface (Adaptee)&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;print_old&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;old_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Old Printer: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_old_printer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;print_old&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;old_print&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// New printer interface (Target)&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;NewPrinter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Adapter&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;NewPrinter&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;old_printer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;PrinterAdapter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;adapter_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Adapt the old print method to the new print method&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adapter: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;old_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;NewPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_printer_adapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;old_printer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PrinterAdapter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PrinterAdapter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PrinterAdapter&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adapter_print&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;old_printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;old_printer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Client code&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create the old printer (Adaptee)&lt;/span&gt;
    &lt;span class="n"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;old_printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_old_printer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Create the adapter that adapts the old printer to the new interface&lt;/span&gt;
    &lt;span class="n"&gt;NewPrinter&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;new_printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_printer_adapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_printer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Use the new interface to print a message&lt;/span&gt;
    &lt;span class="n"&gt;new_printer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Cleanup&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_printer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_printer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.1.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;Here is an example that demonstrates an adapter-like approach in &lt;code&gt;GTK+&lt;/code&gt; which provides widgets and functionalities for building graphical user interfaces (GUIs).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;gtk/gtk.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;config_data_t&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;option_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;option_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;config_data_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Adapter function &lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;config_data_to_combobox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GtkComboBoxText&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config_data_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Adaptee&lt;/span&gt;
  &lt;span class="n"&gt;gtk_combo_box_text_append_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;option_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;g_object_set_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;G_OBJECT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"option-value"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GINT_TO_POINTER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;option_value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GtkWidget&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gpointer&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;gtk_main_quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;gtk_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a window&lt;/span&gt;
  &lt;span class="n"&gt;GtkWidget&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gtk_window_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_WINDOW_TOPLEVEL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;gtk_window_set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_WINDOW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Configuration Options"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;g_signal_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"destroy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_CALLBACK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a vertical box container&lt;/span&gt;
  &lt;span class="n"&gt;GtkWidget&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gtk_box_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_ORIENTATION_VERTICAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;gtk_container_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_CONTAINER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;vbox&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a label for the combobox&lt;/span&gt;
  &lt;span class="n"&gt;GtkWidget&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gtk_label_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Select an option:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;gtk_box_pack_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_BOX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vbox&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a GtkComboBoxText widget&lt;/span&gt;
  &lt;span class="n"&gt;GtkWidget&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gtk_combo_box_text_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;gtk_box_pack_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_BOX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vbox&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;config_data_t&lt;/span&gt; &lt;span class="n"&gt;data1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Option 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;config_data_t&lt;/span&gt; &lt;span class="n"&gt;data2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Option 2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Populate the combobox using the adapter function&lt;/span&gt;
  &lt;span class="n"&gt;config_data_to_combobox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_COMBO_BOX_TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;data1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;config_data_to_combobox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GTK_COMBO_BOX_TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combobox&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;data2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Show all widgets&lt;/span&gt;
  &lt;span class="n"&gt;gtk_widget_show_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;gtk_main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2. Facade Design Pattern
&lt;/h3&gt;

&lt;p&gt;The Facade Design Pattern is a structural pattern that offers a simplified interface to a complex subsystem. It consists of creating a single class (the Facade) that provides simplified methods, which then delegate calls to the more complex underlying system, making it easier to use. This pattern provides a unified interface to a set of interfaces in a subsystem, defining a higher-level interface that makes the subsystem easier to use.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.2.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Interface&lt;/strong&gt;: The Facade offers a high-level interface that makes the subsystem easier to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulation&lt;/strong&gt;: It hides the complexities of the subsystem from the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delegation&lt;/strong&gt;: The Facade delegates the client requests to appropriate components within the subsystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.2.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// TV component&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;is_on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TV&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tv_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TV&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TV is ON&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tv_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TV&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TV is OFF&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// DVD Player component&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;is_on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;DVDPlayer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dvd_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DVDPlayer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DVD Player is ON&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dvd_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DVDPlayer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DVD Player is OFF&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dvd_play_movie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DVDPlayer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;strcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Playing movie: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DVD Player is OFF. Cannot play movie.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Sound System component&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;is_on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;SoundSystem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sound_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SoundSystem&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sound System is ON&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sound_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SoundSystem&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sound System is OFF&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TV&lt;/span&gt; &lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;DVDPlayer&lt;/span&gt; &lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SoundSystem&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_home_theater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;theater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;home_theater_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tv_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;dvd_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sound_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Home Theater is ON&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;home_theater_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tv_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;dvd_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sound_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Home Theater is OFF&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;home_theater_play_movie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;home_theater_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;dvd_play_movie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dvd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create the home theater system&lt;/span&gt;
    &lt;span class="n"&gt;HomeTheaterFacade&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;theater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_home_theater&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Use the Facade to play a movie&lt;/span&gt;
    &lt;span class="n"&gt;home_theater_play_movie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"The Matrix"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Turn off the home theater system&lt;/span&gt;
    &lt;span class="n"&gt;home_theater_off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Cleanup&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theater&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;GStreamer uses the Facade pattern to offer a simple interface for creating and managing multimedia pipelines, hiding the complexity of the underlying media processing components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;gst/gst.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GstElement&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GstBus&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GstMessage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* Initialize GStreamer */&lt;/span&gt;
    &lt;span class="n"&gt;gst_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* Build the pipeline using playbin as Facade pattern */&lt;/span&gt;
    &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gst_parse_launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"playbin uri=file:///path/to/video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* Start playing */&lt;/span&gt;
    &lt;span class="n"&gt;gst_element_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_PLAYING&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* Wait until error or EOS */&lt;/span&gt;
    &lt;span class="n"&gt;bus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gst_element_get_bus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gst_bus_timed_pop_filtered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_CLOCK_TIME_NONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_MESSAGE_ERROR&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;GST_MESSAGE_EOS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* Free resources */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;gst_message_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;gst_object_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;gst_element_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;gst_object_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3. Proxy Pattern
&lt;/h3&gt;

&lt;p&gt;The Proxy Design Pattern is a structural design pattern that provides a surrogate or placeholder for another object to control access to it. A proxy can perform additional operations, such as access control, lazy initialization, logging, or even caching, before or after forwarding the request to the real object.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Proxy&lt;/strong&gt;: The proxy object, which implements the same interface as the real object and controls access to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Subject&lt;/strong&gt;: The actual object that performs the operations. The proxy forwards the requests to this object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.3.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Image interface&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// RealImage implementation&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;RealImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;real_image_display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RealImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Displaying image: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;RealImage&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_real_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;RealImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RealImage&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RealImage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)())&lt;/span&gt;&lt;span class="n"&gt;real_image_display&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ProxyImage implementation&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;RealImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;ProxyImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;proxy_image_display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProxyImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Add logging functionality&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Proxy: Logging display request for image: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Lazy initialization of the RealImage&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_real_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Forward the request to the RealImage&lt;/span&gt;
    &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ProxyImage&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_proxy_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ProxyImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProxyImage&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProxyImage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proxy_image_display&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strdup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Client code&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create the proxy image&lt;/span&gt;
    &lt;span class="n"&gt;ProxyImage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_proxy_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.jpg"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Use the proxy to display the image&lt;/span&gt;
    &lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Clean up&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;real_image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.3.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;Here’s an example demonstrating how the STM32 HAL library acts as a proxy for hardware, specifically for configuring and using a GPIO pin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"stm32f4xx_hal.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Initialization function for GPIO&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GPIO_Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;__HAL_RCC_GPIOA_CLK_ENABLE&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Enable the GPIOA clock&lt;/span&gt;

    &lt;span class="n"&gt;GPIO_InitTypeDef&lt;/span&gt; &lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Configure GPIO pin : PA5 (typically the onboard LED)&lt;/span&gt;
    &lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPIO_PIN_5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPIO_MODE_OUTPUT_PP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pull&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPIO_NOPULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPIO_SPEED_FREQ_LOW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;HAL_GPIO_Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIOA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GPIO_InitStruct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to toggle the GPIO pin&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Toggle_LED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIOA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GPIO_PIN_5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// HAL initialization&lt;/span&gt;
    &lt;span class="n"&gt;HAL_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Configure the system clock&lt;/span&gt;
    &lt;span class="n"&gt;SystemClock_Config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialize GPIO&lt;/span&gt;
    &lt;span class="n"&gt;GPIO_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Main loop&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Toggle_LED&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;HAL_Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Delay 1 second&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SystemClock_Config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// System Clock Configuration code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2For4tsup1slx8mda8bnfq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2For4tsup1slx8mda8bnfq.png" alt="Behavioral Design Pattern" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Behavioral Patterns
&lt;/h2&gt;

&lt;p&gt;Behavioral design patterns are concerned with algorithms and the assignment of responsibilities between objects. These patterns describe not just patterns of objects or classes but also the patterns of communication between them. They help in defining the flow of control and communication between objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1. Observer Pattern
&lt;/h3&gt;

&lt;p&gt;The Observer Pattern (Publish-Subscribe) is a behavioral design pattern that defines a one-to-many dependency between objects. When one object (the subject) changes state, all its dependents (observers) are notified and updated automatically. This pattern is particularly useful for implementing distributed event-handling systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.1.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subject&lt;/strong&gt;: The object that holds the state and notifies observers of changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observers&lt;/strong&gt;: The objects that are notified and updated when the subject changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4.1.2. Example Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Subject (weather sensor)&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;update_observers&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Function pointer for notifications&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;weather_sensor_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Observer (thermostat)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;thermostat_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Temperature changed to: %.2f degrees Celsius&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Simulate thermostat adjustment based on temperature&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registering observer with sensor&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;register_thermostat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;update_observers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thermostat_update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Assign observer function&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Simulating temperature change and notification&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;weather_sensor_set_temperature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;update_observers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;update_observers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Call observer function if registered&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;weather_sensor_t&lt;/span&gt; &lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;register_thermostat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Register thermostat&lt;/span&gt;

  &lt;span class="n"&gt;weather_sensor_set_temperature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sensor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Simulate temperature change&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.1.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;The signal/slot mechanism in GLib is a great way to illustrate the Observer pattern. In GLib, signals are emitted by objects when certain events occur, and slots (callbacks) are functions that are called in response to those signals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;glib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Subject (GObject that emits signals)&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GObject&lt;/span&gt; &lt;span class="n"&gt;parent_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;MySubject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GObjectClass&lt;/span&gt; &lt;span class="n"&gt;parent_class&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;MySubjectClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;STATE_CHANGED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LAST_SIGNAL&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;guint&lt;/span&gt; &lt;span class="n"&gt;my_subject_signals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;LAST_SIGNAL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Signal emission function&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;my_subject_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;g_signal_emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;my_subject_signals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATE_CHANGED&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#define MY_TYPE_SUBJECT (my_subject_get_type())
&lt;/span&gt;&lt;span class="n"&gt;G_DECLARE_FINAL_TYPE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;my_subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SUBJECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;G_DEFINE_TYPE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;my_subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_TYPE_OBJECT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;my_subject_class_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubjectClass&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;my_subject_signals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;STATE_CHANGED&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_signal_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"state-changed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;G_TYPE_FROM_CLASS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;G_SIGNAL_RUN_FIRST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;G_TYPE_NONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;G_TYPE_INT&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;my_subject_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Observer (callback function)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;on_state_changed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySubject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gpointer&lt;/span&gt; &lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Observer: State changed to %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Main function&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize GType system&lt;/span&gt;
    &lt;span class="n"&gt;g_type_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Create subject instance&lt;/span&gt;
    &lt;span class="n"&gt;MySubject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_object_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MY_TYPE_SUBJECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect observer to the signal&lt;/span&gt;
    &lt;span class="n"&gt;g_signal_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"state-changed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_CALLBACK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;on_state_changed&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Change state and emit signal&lt;/span&gt;
    &lt;span class="n"&gt;my_subject_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;my_subject_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Cleanup&lt;/span&gt;
    &lt;span class="n"&gt;g_object_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2. Strategy Pattern
&lt;/h3&gt;

&lt;p&gt;The Strategy Design Pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows the algorithm to vary independently from the clients that use it. The Strategy pattern is particularly useful when you need to switch between different algorithms or behaviors at runtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.2.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strategy Interface&lt;/strong&gt;: Defines a common interface for all supported algorithms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concrete Strategies&lt;/strong&gt;: Implement the algorithm using the Strategy interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: Maintains a reference to a Strategy object and uses it to execute the algorithm.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4.2.2. Example Code
&lt;/h4&gt;

&lt;p&gt;‍‍‍&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Interface for sorting algorithms&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sort_function_t&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete strategy - Bubble sort implementation&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;bubble_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete strategy - Selection sort implementation&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;selection_sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;min_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;min_index&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;min_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;min_index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;min_index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;min_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Context (sorting utility) using strategy pattern&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort_function_t&lt;/span&gt; &lt;span class="n"&gt;sort_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sort_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sorting successful!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error during sorting!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Choose sorting strategy (can be dynamic based on criteria)&lt;/span&gt;
  &lt;span class="n"&gt;sort_function_t&lt;/span&gt; &lt;span class="n"&gt;sort_strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bubble_sort&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort_strategy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.2.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;This example will show how to compress data using different zlib compression strategies: default, best speed, and best compression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;zlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;input_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"This is some data to be compressed."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;input_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;output_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Using default compression level&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compress2&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uLongf&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Z_DEFAULT_COMPRESSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Z_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Default compression success. Compressed size: %zu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Default compression failed.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset output size for the next test&lt;/span&gt;
    &lt;span class="n"&gt;output_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Using best speed compression level&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compress2&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uLongf&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Z_BEST_SPEED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Z_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Best speed compression success. Compressed size: %zu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Best speed compression failed.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset output size for the next test&lt;/span&gt;
    &lt;span class="n"&gt;output_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Using best compression level&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compress2&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uLongf&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Bytef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Z_BEST_COMPRESSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Z_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Best compression success. Compressed size: %zu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Best compression failed.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3. State Pattern
&lt;/h3&gt;

&lt;p&gt;The State Pattern is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. The object will appear to change its class. This pattern is particularly useful when an object must change its behavior at runtime depending on its state.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.3.1. Key Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: The object whose behavior varies based on its state. It maintains a reference to an instance of a state subclass that defines the current state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Interface&lt;/strong&gt;: Declares methods that concrete states must implement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concrete States&lt;/strong&gt;: Implement the behavior associated with a state of the Context.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4.3.2. Example Code
&lt;/h4&gt;

&lt;p&gt;"Hunt the Wumpus" is a classic text-based adventure game where the player navigates through a network of interconnected rooms in a cave system to hunt a creature called the Wumpus. The player can move through rooms, shoot arrows to kill the Wumpus, and must avoid various hazards such as bottomless pits and super bats. The game provides sensory hints, like smells and sounds, to help the player deduce the locations of the Wumpus and hazards. The player wins by successfully shooting the Wumpus with an arrow, and loses if they enter a room with the Wumpus, fall into a pit, or get carried away by bats. Here's an example in C that implements a simplified Wumpus game and saves state using the State pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Game constants&lt;/span&gt;
&lt;span class="cp"&gt;#define ROOMS 5
&lt;/span&gt;
&lt;span class="c1"&gt;// Forward declaration of Context&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// State interface&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Context&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PlayerState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;current_room&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Function to set the state&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;set_player_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to create a Player&lt;/span&gt;
&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;create_player&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current_room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set_player_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Forward declarations of state structs&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;alive_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;dead_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;won_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete State: Alive&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;alive_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;alive_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;alive_move&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;alive_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;current_room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player moves to room %d.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// For simplicity, let's assume:&lt;/span&gt;
    &lt;span class="c1"&gt;// Room 2 has the Wumpus, Room 4 has the gold.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player encountered the Wumpus and died!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dead_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player found the gold and won!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;won_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete State: Dead&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dead_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;dead_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;dead_move&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dead_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player is dead and cannot move.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete State: Won&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;won_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;PlayerState&lt;/span&gt; &lt;span class="n"&gt;won_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;won_move&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;won_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player has already won and cannot move.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Client code&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a player&lt;/span&gt;
    &lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_player&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Initial state: Alive&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alive_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Move the player to different rooms&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Move to room 1&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Encounter the Wumpus and die&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Cannot move because player is dead&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset player to alive state for the next test&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alive_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Move to room 3&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Find the gold and win&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Cannot move because player has won&lt;/span&gt;

    &lt;span class="c1"&gt;// Clean up&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.3.3. Known Uses
&lt;/h4&gt;

&lt;p&gt;In GStreamer, the State pattern is used to handle the state transitions of a media pipeline. The states control the flow of media data through the pipeline, ensuring that elements are properly initialized, negotiated, and ready to process media data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;gst/gst.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Function to change the state of the pipeline and print the new state&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;change_pipeline_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GstElement&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GstState&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GstStateChangeReturn&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gst_element_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_CHANGE_FAILURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;g_printerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to set the pipeline to the desired state.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;GstState&lt;/span&gt; &lt;span class="n"&gt;current_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;gst_element_get_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;current_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_CLOCK_TIME_NONE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;g_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pipeline state changed to %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gst_element_state_get_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_state&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gst_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create the pipeline&lt;/span&gt;
    &lt;span class="n"&gt;GstElement&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gst_pipeline_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example-pipeline"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Set the pipeline to the NULL state&lt;/span&gt;
    &lt;span class="n"&gt;change_pipeline_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Set the pipeline to the READY state&lt;/span&gt;
    &lt;span class="n"&gt;change_pipeline_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_READY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Set the pipeline to the PAUSED state&lt;/span&gt;
    &lt;span class="n"&gt;change_pipeline_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_PAUSED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Set the pipeline to the PLAYING state&lt;/span&gt;
    &lt;span class="n"&gt;change_pipeline_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GST_STATE_PLAYING&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Clean up&lt;/span&gt;
    &lt;span class="n"&gt;gst_object_unref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;gst_deinit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Websites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.gtk.org/glib" rel="noopener noreferrer"&gt;GLib&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gtk.org" rel="noopener noreferrer"&gt;GTK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns" rel="noopener noreferrer"&gt;Design patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gstreamer.freedesktop.org/documentation" rel="noopener noreferrer"&gt;Gstreamer Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.st.com/en/embedded-software/stm32cubef4.html" rel="noopener noreferrer"&gt;STM32 HAL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://zlib.net/" rel="noopener noreferrer"&gt;zlib&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://curl.se/libcurl/" rel="noopener noreferrer"&gt;libcurl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Books
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;E. Gamma, R. Helm, R. Johnson, and J. Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fz1vmhlxdfxjknjm3inj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fz1vmhlxdfxjknjm3inj4.png" alt="Design Patterns: Elements of Reusable Object-Oriented Software" width="274" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Douglas, B. (2010). Design Patterns for Embedded Systems in C.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv4ko9rmnrc7mhkpneex4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv4ko9rmnrc7mhkpneex4.png" alt="Design Patterns for Embedded Systems in C" width="700" height="862"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>cleancode</category>
      <category>bestpractice</category>
      <category>c</category>
    </item>
    <item>
      <title>Yocto: roll your own embedded Linux distribution</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Mon, 08 Apr 2024 09:09:58 +0000</pubDate>
      <link>https://dev.to/khozaei/yocto-roll-your-own-embedded-linux-distribution-5h5k</link>
      <guid>https://dev.to/khozaei/yocto-roll-your-own-embedded-linux-distribution-5h5k</guid>
      <description>&lt;h2&gt;
  
  
  What is Linux?
&lt;/h2&gt;

&lt;p&gt;Linux is an impressive operating system that can run on a wide range of devices, from supercomputers to cell phones, manufacturing devices, network switches, and even cow milking machines. What's even more amazing is that this software is maintained by thousands of skilled software engineers and is available for free.&lt;/p&gt;

&lt;p&gt;Initially, Linux was not developed as an embedded operating system. Instead, it was created by Linus Torvalds, a Finnish university student, who made his work available to everyone, accepted feedback from others, and delegated tasks to other skilled engineers. As the project grew, it attracted more talented engineers who contributed to Linux, increasing its value and visibility and thus creating a virtuous cycle that continues to this day.&lt;/p&gt;

&lt;p&gt;Linux was first designed to run on the Intel IA-32 architecture and later ported to a Motorola processor. The porting process was difficult, so Linus Torvalds decided to redesign the architecture so that it could be easily ported, creating a clean interface between the processor-dependent parts of the software and those that are architecture independent. This decision paved the way for Linux to be ported to other processors.&lt;/p&gt;

&lt;p&gt;Linux is a kernel that manages communication between software and hardware, but it is not very useful on its own. Linux distributions combine software from various projects to create a complete operating system. Popular distributions include Debian, Ubuntu, Fedora, Red Hat, and CentOS, which cater to different use cases such as desktops, servers, and embedded devices. Although these distributions share the same major Linux kernel version, each one curates a specific set of system software, libraries, and functionalities to meet different user needs and hardware architectures. The portability of Linux software, such as the GNU toolchain, has contributed to its success in embedded systems. Much of this software was designed to be adaptable across platforms, making it a perfect fit for resource-constrained embedded devices. This has extended the reach of Linux far beyond traditional desktops.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fape9hu2zra9kg2pwpmda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fape9hu2zra9kg2pwpmda.png" alt="Embedded Circuit Board" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Embedded Linux?
&lt;/h2&gt;

&lt;p&gt;Embedded Linux is similar to the Linux distributions that run on millions of desktops and servers worldwide, but it is tailored to a specific use case. Unlike desktop and server machines, embedded devices have limited resources such as memory, processor cycles, power consumption, and storage space. These resources matter a lot in the embedded field because they determine the unit cost of a device that may be produced in the millions. For instance, even a few extra MB or GB of storage can significantly impact the cost of a device. Similarly, extra memory may require additional batteries, which can add weight to the device. Moreover, a processor with a high clock speed produces heat, and some environments have very tight heat budgets, which means only limited cooling is available. Therefore, in embedded programming, if you're using Linux or some other operating system, most of the efforts focus on optimizing limited resources to make the most out of them.&lt;/p&gt;

&lt;p&gt;When it comes to embedded operating systems, Linux is not the most lightweight option available, as compared to others like VxWorks, Integrity, and Symbian. Some embedded applications make use of frameworks like ThreadX for application support, which runs directly on the hardware, without the need for an operating system. Another option is to skip the framework and write code that runs directly on the device's processor. &lt;/p&gt;

&lt;p&gt;The main difference between using a traditional embedded operating system and Linux is the separation between the kernel and the applications. In Linux, applications run in an execution context that is entirely separate from the kernel. This means that the application cannot access memory or resources other than what the kernel allocates. This high level of process protection ensures that if a program is defective, it is isolated from the kernel and other programs, resulting in a more secure and robust system. However, this protection comes at a cost.&lt;/p&gt;

&lt;p&gt;The adoption of Linux is on an increasing trend despite its high resource overhead when compared to other options. This suggests that engineers working on projects find the added cost of Linux to be worth it. Although the cost and power demands of system-on-chip (SOC) processors have decreased in recent years, to the extent that they are no more expensive than a low-power 8-bit microcontroller from the past, more sophisticated processors can still be used where necessary. Many design solutions utilize off-the-shelf SOC processors and don't run the leads from the chip for the Ethernet, video, or other unused components.&lt;/p&gt;

&lt;p&gt;Linux has become popular due to its ability to provide unique capabilities and features that aren't available in other embedded solutions. These capabilities are crucial to implementing sophisticated designs that distinguish devices in today's market. The open-source nature of Linux allows embedded engineers to take advantage of the continuous development happening in the open-source environment. This development occurs at a pace that no single software vendor can match.&lt;/p&gt;

&lt;p&gt;Here's where Embedded Linux shines, offering a compelling combination of technical advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modular Kernel and Open-Source Power&lt;/strong&gt;: The core strength of Embedded Linux lies in the modularity of the Linux kernel. This allows developers to include only the necessary components, minimizing resource usage and optimizing performance for the specific hardware. Additionally, the open-source nature of Linux grants access to a vast developer community and a wealth of existing code, accelerating development and reducing costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust Network Stack&lt;/strong&gt;: Embedded Linux boasts a mature and reliable network stack, a crucial element for devices that need to communicate with other systems. This stack provides functionalities like TCP/IP (Transmission Control Protocol/Internet Protocol), enabling functionalities like file transfer, remote access, and internet connectivity. Protocols like Wi-Fi, Bluetooth, and cellular networking can also be integrated, allowing embedded devices to seamlessly connect to various networks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH (Secure Shell) for Secure Remote Access&lt;/strong&gt;: Embedded Linux often includes SSH, a secure communication protocol that allows developers and administrators to remotely access and manage devices. This eliminates the need for physical interaction with potentially hard-to-reach devices, streamlining maintenance and troubleshooting processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Server Capabilities&lt;/strong&gt;: For embedded devices that need to serve web content, lightweight web servers like Lighttpd or uhttpd can be incorporated within the Embedded Linux system. These servers are ideal for situations where a full-fledged web server might be overkill, offering a resource-efficient way to provide a web interface for configuration or data visualization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C Library ( libc )&lt;/strong&gt;: The C library, or libc, is a fundamental component of Embedded Linux. It provides a collection of essential functions for C programming, simplifying common tasks like memory management, input/output operations, and string manipulation. This rich library empowers developers to create efficient and portable C applications for embedded systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdagt12b2y5cgjmplvf5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdagt12b2y5cgjmplvf5v.png" alt="Yocto" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Yocto?
&lt;/h2&gt;

&lt;p&gt;The Yocto Project is an open-source collaboration project that provides templates, tools, and methods to help us create customized Linux-based systems for embedded products, regardless of the hardware architecture. It can generate tailored Linux distributions based on the glibc and musl C standard libraries, as well as Real-Time Operating System (RTOS) toolchains for bare-metal development.&lt;br&gt;
The Yocto Project aggregates several companies, communities, projects, and tools with the same purpose – to build Linux-based embedded products. These stakeholders are in the same boat, driven by their community needs to work together.&lt;br&gt;
The Yocto Project provides various tools that prepare its build environment, utilities, and toolchains, which minimize the host software dependency. These tools are independent of the host Linux distribution, which reduces the number of host utilities required to produce the same result. This has an essential benefit of considerably increasing determinism, reducing build host dependencies, and increasing first-time builds.&lt;/p&gt;
&lt;h3&gt;
  
  
  Background
&lt;/h3&gt;

&lt;p&gt;The OpenEmbedded project was initiated in January 2003 by core developers from the OpenZaurus project. They began working with a new build system, which led to the development of the OpenEmbedded build system. This build system is inspired and based on the Gentoo Portage package system called BitBake. As a result, the project has grown its software collection and the list of supported machines has expanded rapidly.&lt;br&gt;
Due to the chaotic and uncoordinated development of OpenEmbedded, it was quite challenging to use it in products that require a more stable and polished code base. This led to the birth of the Poky distribution, which started as a subset of the OpenEmbedded build system. Poky had a more polished and stable code base across a limited set of architectures. Moreover, its reduced size allowed Poky to develop highlighting technologies, such as IDE plugins and Quick Emulator (QEMU) integration, which are still in use today.&lt;br&gt;
In an effort to streamline their work, the Yocto Project and OpenEmbedded project joined forces to create a core build system known as OpenEmbedded Core. This system combines the best elements of both Poky and OpenEmbedded, with a focus on incorporating additional components, metadata, and subsets. In November of 2010, the Linux Foundation announced that the Yocto Project would take over this work as a sponsored project.&lt;/p&gt;
&lt;h3&gt;
  
  
  Poky
&lt;/h3&gt;

&lt;p&gt;Poky is a reference distribution of the Yocto Project that utilizes the OpenEmbedded build system technology. It consists of a set of tools, configuration files, and recipe data (called metadata), that is platform-agnostic and supports cross-compiling through the BitBake tool, OpenEmbedded Core, and a default set of metadata. Additionally, it offers the capability to merge and build numerous distributed open-source projects to create a fully customizable, comprehensive, and coherent Linux software stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv08sppfx7129pbce51u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv08sppfx7129pbce51u1.png" alt="Poky main components" width="533" height="331"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  BitBake
&lt;/h3&gt;

&lt;p&gt;BitBake is a powerful task scheduling and execution system that can parse Python and Shell Script code. The code parsed by BitBake generates and runs tasks, which are a set of steps ordered as per the code's dependencies. &lt;/p&gt;

&lt;p&gt;With BitBake, you can evaluate all available metadata, manage dynamic variable expansion, dependencies, and code generation. It also keeps track of all tasks to ensure their completion, maximizing the use of processing resources to reduce build time and improve predictability.&lt;/p&gt;
&lt;h3&gt;
  
  
  OpenEmbedded Core
&lt;/h3&gt;

&lt;p&gt;The OpenEmbedded Core metadata collection provides the engine of the Poky build system. It provides the core features and aims to be generic and as lean as possible. It supports seven different processor architectures (ARM, ARM64, x86, x86-64, PowerPC, PowerPC 64, MIPS, MIPS64, RISC-V32, and RISC-V 64), only supporting platforms to be emulated by QEMU.&lt;/p&gt;
&lt;h3&gt;
  
  
  Metadata
&lt;/h3&gt;

&lt;p&gt;The metadata comprises both recipes and configuration files, which are composed of a combination of Python and Shell Script text files, making it an incredibly flexible tool. Poky utilizes this metadata to expand OpenEmbedded Core and includes two different layers, each of which is a subset of metadata. These layers are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;meta-poky: This layer provides the default and supported distribution policies, visual branding, and metadata tracking information such as maintainers, upstream status, etc. This layer is designed to act as a curated template that could be utilized by distribution builders to create their own custom distribution.&lt;/li&gt;
&lt;li&gt;meta-yocto-bsp: This layer provides the Board Support Package (BSP) used as the reference hardware for the Yocto Project development and Quality Assurance (QA) process.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Yocto Project releases
&lt;/h2&gt;

&lt;p&gt;The Yocto Project has a biannual release cycle in April and October. This ensures continuous development while focusing on stability and providing points of increased testing. A release is considered Stable or Long-Term Support (LTS) depending on its readiness. &lt;/p&gt;

&lt;p&gt;The support period for each release differs significantly. The stable release is supported for 7 months, with 1 month of overlapped support for every stable release. The LTS release, on the other hand, has a minimum support period of 2 years, which can be optionally extended. &lt;/p&gt;

&lt;p&gt;After the official support period ends, a release moves to Community support and eventually reaches End of Life (EOL). A release becomes Community supported if a community member becomes the community maintainer. If there is no change in the source code for 2 months or the community maintainer is no longer active, the release reaches EOL.&lt;/p&gt;

&lt;p&gt;You can access the release information of the Yocto Project by using &lt;a href="https://wiki.yoctoproject.org/wiki/Releases" rel="noopener noreferrer"&gt;the release page&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preparing Build System
&lt;/h2&gt;

&lt;p&gt;The process needed to set up our host system depends on the Linux distribution we use. Poky has a set of supported Linux distributions. Let’s suppose we are new to embedded Linux development. In that case, it is advisable to use one of the supported Linux distributions to avoid wasting time debugging issues related to the host system support.&lt;br&gt;
If you use the current release of one of the following distributions, you should be good to start using the Yocto Project on your machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu&lt;/li&gt;
&lt;li&gt;Fedora&lt;/li&gt;
&lt;li&gt;CentOS&lt;/li&gt;
&lt;li&gt;AlmaLinux&lt;/li&gt;
&lt;li&gt;Debian&lt;/li&gt;
&lt;li&gt;OpenSUSE Leap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your preferred distribution is not in the preceding list, it doesn’t mean it is not possible to use Poky on it. Your host development system must meet some specific versions for Git, tar, Python, and GCC. Your Linux distributions should provide compatible versions of those base tools.&lt;/p&gt;
&lt;h3&gt;
  
  
  Debian-based distribution
&lt;/h3&gt;

&lt;p&gt;To install the necessary packages for a headless host system, run the following command:&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;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;gawk wget git diffstat unzip texinfo gcc
build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev zstd liblz4-tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have Ubuntu, your default shell is dash. Some scripts might have a problem with it, so you should change dash to bash with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dpkg-reconfigure dash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and select "NO" on the prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fedora
&lt;/h3&gt;

&lt;p&gt;To install the needed packages for a headless host system, run the following command:&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;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;gawk make wget &lt;span class="nb"&gt;tar &lt;/span&gt;bzip2 &lt;span class="nb"&gt;gzip &lt;/span&gt;python3 unzip perl patch diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue perl-bignum socat python3-pexpect findutils which file cpio python python3-pip xz python3-GitPython python3-jinja2 SDL-devel xterm rpcgen mesa-libGL-devel perl-FindBin perl-File-Compare perl-File-Copy perl-locale zstd lz4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Downloading the Poky source code
&lt;/h3&gt;

&lt;p&gt;After we have installed the required packages on our development host system, we can download the current LTS version (at the time of writing) of Poky source code using Git, with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://git.yoctoproject.org/poky &lt;span class="nt"&gt;-b&lt;/span&gt; Scarthgap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Preparing the build environment
&lt;/h3&gt;

&lt;p&gt;Inside the poky directory exists a script named &lt;code&gt;oe-init-build-env&lt;/code&gt;, which sets up the building environment. But first, the script must be run-sourced (not executed) as follows:&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;source &lt;/span&gt;oe-init-build-env &lt;span class="o"&gt;[&lt;/span&gt;build-directory]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, [build-directory] is an optional parameter for the name of the directory where the environment is configured. If it is empty, it defaults to build. The [build-directory] parameter is the place where we perform the builds.&lt;br&gt;
The output from source &lt;code&gt;oe-init-build-env&lt;/code&gt; build displays some important configurations such as the file location, some project URLs, and some common targets, such as available images. &lt;/p&gt;
&lt;h3&gt;
  
  
  Knowing the local.conf file
&lt;/h3&gt;

&lt;p&gt;When we initialize a build environment, it creates a file called &lt;code&gt;build/conf/local.conf&lt;/code&gt;. This config file is powerful, since it can configure almost every aspect of the build process. We can set the target machine and the toolchain host architecture to be used for a custom cross-toolchain, optimize options for maximum build time reduction, and so on. The comments inside the &lt;code&gt;build/conf/local.conf&lt;/code&gt; file are excellent documentation and a reference of the possible variables and their defaults. The minimal set of variables that we probably want to change from the default is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;MACHINE ??&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"qemux86-64"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;MACHINE&lt;/code&gt; variable is where we determine the target machine we wish to build. At the time of writing, Poky supports the following machines in its reference BSP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;beaglebone-yocto&lt;/strong&gt;: This is BeagleBone, which is the reference platform for 32-bit ARM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;genericx86&lt;/strong&gt;: This is generic support for 32-bit x86-based machines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;genericx86-64&lt;/strong&gt;: This is generic support for 64-bit x86-based machines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;edgerouter&lt;/strong&gt;: This is EdgeRouter Lite, which is the reference platform for 64-bit MIPS
The machines are made available by a layer called &lt;code&gt;meta-yocto-bsp&lt;/code&gt;. Besides these machines, OpenEmbedded Core, inside the meta directory, also provides support for the following Quick
Emulation (QEMU) machines:&lt;/li&gt;
&lt;li&gt;qemuarm: This is the QEMU ARMv7 emulation&lt;/li&gt;
&lt;li&gt;qemuarmv5: This is the QEMU ARMv5 emulation&lt;/li&gt;
&lt;li&gt;qemuarm64: This is the QEMU ARMv8 emulation&lt;/li&gt;
&lt;li&gt;qemumips: This is the QEMU MIPS emulation&lt;/li&gt;
&lt;li&gt;qemumips64: This is the QEMU MIPS64 emulation&lt;/li&gt;
&lt;li&gt;qemuppc: This is the QEMU PowerPC emulation&lt;/li&gt;
&lt;li&gt;qemuppc64: This is the QEMU PowerPC 64 emulation&lt;/li&gt;
&lt;li&gt;qemux86-64: This is the QEMU x86-64 emulation&lt;/li&gt;
&lt;li&gt;qemux86: This is the QEMU x86 emulation&lt;/li&gt;
&lt;li&gt;qemuriscv32: This is the QEMU RISC-V 32 emulation&lt;/li&gt;
&lt;li&gt;qemuriscv64: This is the QEMU RISC-V 64 emulation
Extra BSP layers available from several vendors provide support for other machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Building a target image
&lt;/h3&gt;

&lt;p&gt;Poky provides several predesigned image recipes we can use to build our binary image. We can check the list of available images by running the following command from the poky directory:&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;ls &lt;/span&gt;meta&lt;span class="k"&gt;*&lt;/span&gt;/recipes&lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;images/&lt;span class="k"&gt;*&lt;/span&gt;.bb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the recipes provide images that are a set of unpacked and configured packages, generating a filesystem that we can use with hardware or one of the supported QEMU machines.&lt;br&gt;
Next, we can see the list of most commonly used images:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;core-image-minimal&lt;/strong&gt;: This is a small image allowing a device to boot. It is handy for kernel and bootloader tests and development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;core-image-base&lt;/strong&gt;: This console-only image provides basic hardware support for the target device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;core-image-weston&lt;/strong&gt;: This image provides the Wayland protocol libraries and the reference Weston compositor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;core-image-x11&lt;/strong&gt;: This is a basic X11 image with a terminal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;core-image-sato&lt;/strong&gt;: This is an image with Sato support and a mobile environment for mobile devices that use X11. It provides applications such as a terminal, editor, file manager, media player, and so on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;core-image-full-cmdline&lt;/strong&gt;: A console-only image with more full-featured Linux system functionality installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, to build core-image-full-cmdline, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bitbake core-image-full-cmdline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running images in QEMU
&lt;/h3&gt;

&lt;p&gt;We can use hardware emulation to speed up the development process, as it enables a test run without involving any actual hardware. Fortunately, most projects have only a tiny portion that is hardware-dependent.&lt;br&gt;
QEMU is a free, open source software package that performs hardware virtualization. QEMU-based machines allow testing and development without real hardware. ARMv5, ARMv7, ARMv8, MIPS, MIPS64, PowerPC, PowerPC 64, RISC-V 32, RISC-V 64, x86, and x86-64 emulations are currently supported. We will go into more detail about QEMU usage in sw, Speeding Up Product Development through Emulation – QEMU.&lt;br&gt;
OpenEmbedded Core provides the runqemu script tool, which is a wrapper to make use of QEMU easier. The way to run the script tool is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;runqemu &lt;span class="o"&gt;[&lt;/span&gt;machine] &lt;span class="o"&gt;[&lt;/span&gt;zimage] &lt;span class="o"&gt;[&lt;/span&gt;filesystem]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, [machine] is the machine/architecture to be used as qemux86-64, or any other supported machine. Also, [zimage] is the path to a kernel (for example, bzImage-qemux86-64.bin).&lt;br&gt;
Finally, [filesystem] is the path to an ext4 image (for example, filesystem-qemux86-64.ext4) or an NFS directory. All parameters in the preceding call to runqemu [zimage] and [filesystem] are optional. Just running runqemu is sufficient to launch the image in the shell where the build environment is set, as it will automatically pick up the default settings from building the environment. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;runqemu qemux86-64 core-image-full-cmdline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Salvador, O., &amp;amp; Angolini, D. (2017). Embedded Linux Development using Yocto Projects: Learn to leverage the power of Yocto Project to build efficient Linux-based products. Packt Publishing Ltd.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgqxpxcckc0o2e1ayfdsu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgqxpxcckc0o2e1ayfdsu.png" alt="Embedded Linux Development using Yocto Projects" width="364" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simmonds, C. (2017). Mastering Embedded Linux Programming. Packt Publishing Ltd.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnbt1yypaun4xeobmjwvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnbt1yypaun4xeobmjwvx.png" alt="Mastering Embedded Linux Programming" width="364" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sally, G. (2010). Pro Linux embedded systems. Apress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffgo9esbwv2r8k2bcpbpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffgo9esbwv2r8k2bcpbpn.png" alt="Pro Linux embedded systems" width="357" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>linux</category>
      <category>yocto</category>
      <category>openembedded</category>
    </item>
    <item>
      <title>MISRA C Standard</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Sun, 24 Mar 2024 14:09:58 +0000</pubDate>
      <link>https://dev.to/khozaei/misra-c-standard-34ph</link>
      <guid>https://dev.to/khozaei/misra-c-standard-34ph</guid>
      <description>&lt;h3&gt;
  
  
  C Programming Language
&lt;/h3&gt;

&lt;p&gt;Over half a century ago, in the year 1969, the C programming language was created at Bell Labs. The primary goal was to use this language for developing the Unix operating system, which turned out to be a highly successful venture. Despite receiving frequent criticism, C is still one of the most widely used programming languages globally, and it is the most popular one for developing embedded systems. &lt;/p&gt;

&lt;p&gt;The reasons behind C's popularity and success are many and varied. First, C compilers are available for nearly every processor, ranging from tiny DSPs used in hearing aids to supercomputers. This versatility makes it possible to use C for a wide range of applications.&lt;/p&gt;

&lt;p&gt;Furthermore, C compiled code can be highly efficient without hidden costs. Programmers can predict running times to some extent even before testing, without using tools for the worst-case execution time approximation. This saves a lot of time and effort and helps to streamline the development process.&lt;/p&gt;

&lt;p&gt;Additionally, C allows writing compact code thanks to limited verbosity and the availability of many built-in operators. This feature makes it easier to write and debug code, which can result in faster development times.&lt;/p&gt;

&lt;p&gt;It is worth noting that C is defined by international standards. It was first standardized in 1989 by the American National Standards Institute (referred to as ANSI C), and then by the International Organization for Standardization (ISO). This ensures that C is a highly reliable and stable programming language.&lt;/p&gt;

&lt;p&gt;Moreover, C, possibly with extensions, allows easy access to the hardware, a crucial aspect for developing embedded software. This feature provides developers with greater control over the hardware, making it easier to optimize performance and functionality.&lt;/p&gt;

&lt;p&gt;C has a long history of usage in all kinds of systems, including safety, security, mission, and business-critical systems. This makes it a highly versatile programming language that can be used in a wide range of applications.&lt;/p&gt;

&lt;p&gt;Lastly, C is widely supported by all sorts of tools, making it easier to develop and maintain software written in C. This includes compilers, debuggers, and other software development tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs6dd1o3mquq4xpm4muc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs6dd1o3mquq4xpm4muc8.png" alt="C programming language" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  C Is Not Fully Defined
&lt;/h4&gt;

&lt;p&gt;There are claims that C++ will eventually replace C, but this is unlikely in the embedded software industry. C++ is a very complex language that is constantly evolving, which contrasts with industrial best practices. C, on the other hand, is a stable and compact language. However, C is subject to criticism regarding its behavior and the as-if rule. This rule allows the compiler to optimize the code while maintaining the observable behavior. C is not fully defined in this respect, and there are four classes of non-definite behaviors.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implementation-defined behavior&lt;/strong&gt;: unspecified behavior where each implementation documents how the choice is made; e.g., the sizes and precise representations of the standard integer types;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locale-specific behavior&lt;/strong&gt;: behavior that depends on local conventions of nationality, culture, and language that each implementation documents; e.g., character sets and how characters are displayed;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undefined behavior&lt;/strong&gt;: behavior, upon use of a non-portable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements; e.g., attempting to write a string literal constant or shifting an expression by a negative number or by an amount greater than or equal to the width of the promoted expression;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unspecified behavior&lt;/strong&gt;: use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance;e.g., the order in which sub-expressions are evaluated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Non-definite behavior in programming languages is a result of two factors. Firstly, efficient compilers can be written for almost any hardware architecture. Secondly, there are many compilers available from different vendors, and the language is standardized.&lt;/p&gt;

&lt;p&gt;Regarding the second point, it's important to note that ISO typically standardizes existing practices while considering input from participating vendors. They also prioritize backward compatibility. Therefore, when there are divergent implementations, non-definite behavior may be the only feasible solution.&lt;/p&gt;

&lt;p&gt;In C, the main objective is to obtain efficient code with no hidden costs. This is the reason why there is no run-time error checking. However, easy access to hardware can make it simple to corrupt the program state.&lt;/p&gt;

&lt;p&gt;One of the drawbacks of code compactness is that the language can be easily misunderstood and misused.&lt;/p&gt;

&lt;p&gt;The C language is expected to remain true to its original purpose and will continue to be used in the development of embedded systems. However, it is worth noting that certain features of C may conflict with safety and security requirements. Therefore, it is essential to subset the language for critical applications. This has been recognized early and is now mandated or recommended by various safety and security-related industrial standards, such as IEC 61508 for industrial applications, ISO 26262 for automotive, CENELEC EN 50128 for railways, RTCA DO-178B/C for aerospace, and FDA's General Principles of Software Validation.&lt;/p&gt;

&lt;h4&gt;
  
  
  C Can Be Difficult To Read
&lt;/h4&gt;

&lt;p&gt;It is important to use C language features correctly, as improper usage can adversely affect the readability and understandability of the program. Some of the features that can cause issues are: &lt;br&gt;
  • The preprocessing phase &lt;br&gt;
  • A large number of operators with complex precedence and associativity rules &lt;br&gt;
  • Numerous control-flow mechanisms, some with complex semantics (such as goto, switch, for, break, continue, setjmp/longjmp, etc.) &lt;br&gt;
  • Implicit conversions that follow intricate rules &lt;br&gt;
  • Two types of comment markers that interact in a tricky way with line splicing (i.e., splitting logical lines into multiple physical lines using trailing backslashes as line-continuation markers). &lt;br&gt;
The International Obfuscated C Code Contest, which has been running since 1984, awards a prize to the most obscure/obfuscated C programs that follow specific rules. As already mentioned, ensuring code readability and understandability is crucial for the effectiveness of code reviews and has an obvious impact on other program properties such as maintainability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7mxaxjxeh13wbyer957a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7mxaxjxeh13wbyer957a.jpg" alt="C standard" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  MISRA C
&lt;/h3&gt;

&lt;p&gt;The MISRA,The Motor Industry Software Reliability Association, project was initiated in 1990 with the aim of providing best practice guidelines for the safe and secure development of both embedded control systems and standalone software. Originally, the project was part of the UK Government's "SafeIT" program but later it became self-supporting with MIRA Ltd, now HORIBA MIRA Ltd, providing the project management support. The core activities of MISRA include developing guidance in specific technical areas such as programming languages, model-based development, automatic code generation, software readiness for production, safety analysis, safety cases, and more. In November 1994, MISRA published its "Development guidelines for vehicle-based software," also known as "The MISRA Guidelines." This was the first automotive publication concerning functional safety, more than 10 years before work began on ISO 26262.&lt;/p&gt;

&lt;p&gt;The MISRA guidelines prescribe the use of a restricted subset of a standardized structured language. As a response to this, the MISRA consortium started developing the MISRA C guidelines. At the time, Ford and Land Rover were each developing their own in-house rules for vehicle-based C software. It was recognized that creating a common set of guidelines would be more beneficial to the industry. The first version of the MISRA C guidelines was published in 1998 and it gained significant industrial attention.&lt;/p&gt;

&lt;p&gt;In 2004, MISRA received numerous comments from its users, many of which were from non-automotive industries, surpassing their expectations. As a result, MISRA published an enhanced version of the C guidelines, specifically targeting all industries that develop C software for high-integrity and critical systems. The success of MISRA C prompted MISRA to release a set of MISRA C++ guidelines in 2008, as C++ is also used in critical contexts.&lt;/p&gt;

&lt;p&gt;MISRA C:1998 and MISRA C:2004 are both guidelines that target the 1990 version of the C Standard. A revised set of guidelines called MISRA C:2012 was published in 2013, which supports both C99 and C90 (sometimes referred to as C95 in their amended and corrected form). Compared to the previous versions, MISRA C:2012 covers more language issues and provides a more precise specification of the guidelines with improved rationales and examples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuhliyurqsm0xwvczfzzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuhliyurqsm0xwvczfzzl.png" alt="Origin and history of MISRA C" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "JSF Air Vehicle C++ Coding Standards for the System Development and Demonstration Program" had a significant impact on the development of coding standards for C++. This, in turn, led to the creation of MISRA C++:2008, which influenced the development of MISRA C:2012. The UK Ministry of Defence supported the development of the vulnerabilities document, which helped in identifying various behaviors in ISO C++. This document is similar to Annex J in ISO C, which is currently missing. Its absence makes it difficult to ensure that the guidelines are comprehensive. Additionally, MISRA C played a vital role in shaping NASA's "JPL Institutional Coding Standard for the C Programming Language" and other coding standards.&lt;/p&gt;

&lt;p&gt;The MISRA C guidelines aim to enhance the safety and security of embedded or standalone systems. The guidelines define a subset of the C language that eliminates or minimizes the possibility of errors. They prohibit critical non-definite behavior and restrict the use of implementation-defined behavior and compiler extensions. Additionally, they control the use of language features that can be easily misused or misunderstood. Overall, the guidelines are designed to improve the reliability, readability, portability, and maintainability of the systems.&lt;/p&gt;

&lt;p&gt;There are two kinds of MISRA C guidelines.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Directive&lt;/strong&gt;: a guideline where the information concerning compliance is generally not fully contained in the source code: requirements, specifications, design, and etc. all may have to be taken into account. Static analysis tools may assist in checking compliance with respect to directives if provided with extra information not derivable from the
source code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule&lt;/strong&gt;: a guideline where information concerning compliance is fully contained in the source code. Discounting undecidability, static analysis tools should, in principle, be capable of checking compliance with respect to the rule.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MISRA C coding standard is intended to be used in conjunction with a documented development process, where any deviations from the standard that can be justified will be authorized and recorded. To make this process easier, each guideline in the MISRA C standard has been assigned a category.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mandatory&lt;/strong&gt;: C code that complies to MISRA C must comply with every mandatory guideline; deviation is not permitted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Required&lt;/strong&gt;: C code that complies to MISRA C shall comply with every required guideline; a formal deviation is required where this is not the case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advisory&lt;/strong&gt;: these are recommendations that should be followed as far as is reasonably practical; formal deviation is not required, but non-compliances should be documented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Organizations or projects have the option to treat required guidelines as mandatory and advisory guidelines as required or mandatory. Adopting MISRA Compliance:2016 allows advisory guidelines to be disregarded and marked as "Disapplied" when they are deemed to have no value, such as when adopted code has not been developed to comply with the MISRA C guidelines. However, the decision to disapply a guideline should not be taken lightly. It is important to create a guideline recategorization plan that includes the rationale for any decision to disapply a guideline.&lt;/p&gt;

&lt;p&gt;MISRA C rules are categorized based on the amount of code that needs to be analyzed to detect all violations. Single Translation Unit refers to checking each translation unit independently. System requires checking more than the translation unit in question, if not all the source code that constitutes the system.&lt;/p&gt;

&lt;p&gt;MISRA C:2012 Amendment 1 was published in 2016 to extend the applicability of MISRA C:2012 to industries and applications that prioritize data-security. It includes 14 new guidelines (1 directive and 13 rules) to complete the coverage of ISO/IEC TS 17961:2013, which is a set of rules for secure coding in C. &lt;/p&gt;

&lt;p&gt;The coverage of the CERT C Coding Standard is almost complete with Amendment 1. As a result, MISRA C is the preferred language subset for all industries developing embedded systems in C that are safety- and/or security-critical. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm6fz95govs2zl89jln58.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm6fz95govs2zl89jln58.jpg" alt="Keep C in your hands" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Important Rules
&lt;/h3&gt;

&lt;p&gt;MISRA established standards to ensure safe and reliable automotive software. Strict rules minimize risks and prevent vulnerabilities. We'll discuss critical rules for code clarity and safety adherence. Understanding them helps developers navigate the intricacies of software development.&lt;/p&gt;
&lt;h4&gt;
  
  
  Rule D.4.1 (required): Run-time failures shall be minimized
&lt;/h4&gt;

&lt;p&gt;It is important to ensure that there are measures in place to detect and handle run-time errors. This is particularly crucial for safety-critical systems, as C language does not have built-in mechanisms to handle dynamic errors. Therefore, special attention is required to ensure the safety and reliability of such systems.&lt;br&gt;
As a developer, it is important to keep a watchful eye on the occurrence of run-time errors while coding. To prevent such errors, checks should be introduced in the code wherever necessary, while also considering performance and code-size constraints. Below are some areas that should be taken into consideration, as they are prone to run-time errors.&lt;/p&gt;
&lt;h5&gt;
  
  
  Arithmetic Errors
&lt;/h5&gt;

&lt;p&gt;These occur as the resultant of the evaluation of expressions giving rise to divide by zero error, overflow, or underflow scenarios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
num1 = 10;
for(i=0;i&amp;lt;10;i++)
{
result = num1/i; // Noncompliant
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, the literal &lt;em&gt;i&lt;/em&gt; is initially initialized to zero; hence on dividing &lt;em&gt;num1&lt;/em&gt; by &lt;em&gt;i&lt;/em&gt;, the zero division error is encountered with.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pointer Arithmetic
&lt;/h5&gt;

&lt;p&gt;This deals with the calculation of addresses where care must be taken to ensure that the addresses computed should be reasonable and point to places meaningful.&lt;/p&gt;

&lt;h5&gt;
  
  
  Left Shifts
&lt;/h5&gt;

&lt;p&gt;Care must be taken while performing left shifts, as the Most Significant Bit is lost resulting in the overflow.&lt;/p&gt;

&lt;h5&gt;
  
  
  Array Bound Errors
&lt;/h5&gt;

&lt;p&gt;The array indices while being used for indexing the array should be ensured that they are within the bounds specified.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.1.3 (required): There shall be no occurrence of undefined or critical unspecified behavior
&lt;/h4&gt;

&lt;p&gt;The ISO standard specifies a minimum set of about 91 characters that all compilers must support. This means that even if a compiler supports a larger set of characters, only these 91 characters should be used. The standard has defined a set of escape sequences including \n, \t, \v, \b, \r, \f, \a, \\, ?, \', \", \[Octal Number], and \x[Hexadecimal Number] that can be used. It is important to note that using escape sequences other than these can lead to unpredictable behavior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const char_t a[ 2 ] = "\k"; // Noncompliant
const char_t b[ 2 ] = "\b"; // Compliant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule D.4.1 (required): The character sequences /* and // shall not be used within a comment
&lt;/h4&gt;

&lt;p&gt;The nesting of comments is not something that is supported in C. The comment starts on detecting /* and ends on the first occurrence of */ irrespective of any nesting of comments being attempted. A noncompliant code example supporting the rule statement is shown as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* This is a multi-line comment statement.
/* Nesting of comments leads to unexpected behavior*/
The actual comment ends here */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example shows a multi-statement comment section which is begun with /*, but in the very next line, there is a comment line ending with */, whereas the actual comment ends in the next line. Now this might confuse the developer as which the actual ending of the comment might be, as the final line gets uncommented, due to the early detection of the */. Hence nesting of the comments is not used.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.7.1 (required): Octal constants should not be used
&lt;/h4&gt;

&lt;p&gt;Any integer constant that begins with “0” (zero) is termed as an octal constant. The usage of the octal constants is denied, because this may cause ambiguous scenarios. Following example illustrates this rule. Consider a user who wants to assign fixed length integer constants to variables. The array initialization is done as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data [0] = 500; /* set to decimal 500*/
data [1] = 071; /* set to decimal 57*/
data [2] = 520; /* set to decimal 520*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet, the user assigns the decimal value “071” to data, thinking that it would be taken in as an integer constant, but the compiler recognizes it as an octal value as it has begun with a “0” and hence assigns the decimal value of the octal constant “071” which is “57” to data. Therefore it is better not to use octal constants, yet zero is an exception as it holds the same value even in the octal representation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.8.1 (required): Types shall be explicitly specified
&lt;/h4&gt;

&lt;p&gt;Implicit typing of variables and functions though supported by some C compilers shall not be used according to the rule, as it might lead to confusions. A supporting example shows a noncompliant form of the rule along with its compliant solution in the comments is shown as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern x; // Compliant solution - extern int16_t x;
const x; // Compliant solution - const int16_t x;
static fun(void); // Compliant solution - static int16_t fun(void);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule R.9.1 (required): The value of an object with automatic storage duration shall not be read before it has been set
&lt;/h4&gt;

&lt;p&gt;Normally when the integer variable is declared without any storage specifier, the default specifier it takes is, the auto class. These integer variables shall not be used before getting initialized, to avoid any unexpected behavior due to garbage values. In the example below the variable data returned by the function would hold garbage value, due to the conditional construct, as it is not initialized before being used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
int data, value;
value=0;
if (value==1)
{
data = 45;
}
return data;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intention of this rule is that all the variables have to be initialized before being used. The initialization need not necessarily be done at the time of the declaration but at some other part of the code but before the variable is put into use.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.10.1 (required): Operands shall not be of an inappropriate essential type
&lt;/h4&gt;

&lt;p&gt;There are rules that are to be followed on using the operators over the operands. One such is the rule that talks about the usage of the Bitwise operator over its operands. The built-in Bitwise operators (~, &amp;gt;&amp;gt;, &amp;gt;&amp;gt;=, &amp;amp;, &amp;amp;=, ^, ^=, |, and |=), if used on the signed integer constants, yield implementation-dependent results. The most significant of them is the left shift which, if performed on the signed integers, may cause the signed bit, which is the Most Significant Bit, to be lost in the process, which leads to erroneous results. Hence, the bitwise operators are not used against the signed integers. A supporting illustration is shown as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if ((uint16_value &amp;amp; int16_data) == 0x246U)
if (~int16_data == 0x246U)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example shows a bitwise operation being performed between an unsigned and a signed integer and another bitwise operation being performed on a signed integer. Both of these operations might yield results far from the unexpected one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.11.3 (required): A cast shall not be performed between a pointer to object type and a pointer to a different object type
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Rule R.11.3 (required): A conversion should not be performed between a pointer to object and an integer type
&lt;/h4&gt;

&lt;p&gt;These rules are extracted from a set of rules that talk about conversions from one type to another. These rules in particular talk about things that have to be kept in mind while dealing with pointers and conversions. Pointer types shall neither be made to cast into other types nor other types be cast into pointers. It is because if an address value being held by a pointer variable is assigned to an integer variable, it not be able to hold the complete value of the address due to its size. In this case, there occurs data loss, and further computations involving these variables will not yield the expected results. An example supporting this rule is shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int* data;
int addr_value = (int) &amp;amp;data;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example shows a pointer data variable being type cast into an integer and its value being assigned to an integer value. Data loss may occur if the addr_value is not large enough to accommodate the address value being assigned to it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.12.1 (advisory): The precedence of operators within expressions should be made explicit
&lt;/h4&gt;

&lt;p&gt;This rule is from the set of rules that are designed to be followed for evaluating or forming an expression for evaluation. Precedence is normally followed for the evaluation of an expression to arrive at the intended result. But the rules of precedence can be confusing at times. Hence in order to avoid this confusion which may cause unpredictable results later, it is advisable to have a limited dependency on the rules of precedence. The expression can be evaluated according to the precedence by making use of parentheses, in case of complex statements. However, there should not be overusing of the parentheses. A noncompliant code example is shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = a == b ? a : a - b; // Noncompliant; Compliant Usage -&amp;gt; x = ( a == b ) ? a : ( a - b );
x = a + b - c + d; // Noncompliant; Compliant Usage -&amp;gt; x = ( a + b ) - ( c + d );
x = a * 3 + c + d; // Noncompliant; Compliant Usage -&amp;gt; x = ( a * 3 ) + c + d;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule R.16.3 (required): An unconditional break statement shall terminate every switch clause
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Rule R.16.4 (required): Every switch statement shall have a default label
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Rule R.16.5 (required): A default label shall appear as either the first or the last switch label of a switch statement
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Rule R.16.6 (required): Every switch statement shall have at least two switch clauses
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Rule R.16.7 (required): A switch expression shall not have essentially Boolean type
&lt;/h4&gt;

&lt;p&gt;These are few rules to be followed while writing a switch statement. The switch cases inclusive of the default case mark their end when an unconditional break statement is introduced. The usage of the break statement is permitted only in the&lt;br&gt;
case of a switch statement, and an exception exists in case of an empty case clause. The switch statement should have a default label which can be present either at the end or at the top under a switch statement. The switch expression is prohibited in using a Boolean type, as the result of a Boolean computation is either true (1) or false (0), in which case a simple if…else construct would suffice as there would be only two choices to decide upon. Hence switch statements are expected to have at least two cases to prove their usage. These are illustrated in example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (value) /* value is not of type Boolean*/
{
  case 0:
    statement 1;
    break; /* break statement is required after the case statements*/
  case 1: /* empty case clause, no break is required*/
  case 2:
    statement 1;
    break;
  default:
    err_flag_count = 1;
    break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule R.17.2 (required): Functions shall not call themselves, either directly or indirectly.
&lt;/h4&gt;

&lt;p&gt;Recursive functions are not considered to be used in case of safety-critical systems. This is because the usage of the recursive functions consumes the stack space and causes the danger of depleting the same. The recursive function requires high control, else it would not be possible to determine the worst-case stack usage. A supporting noncompliant code example is shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void func()
{
  printf("This is a recursive function");
  func(); //Noncompliant
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule R.9.5 (required): Where designated initializers are used to initialize an array object, the size of the array shall be specified explicitly
&lt;/h4&gt;

&lt;p&gt;The declaration of an array without specifying the size of the array is possible. But it is not allowed according to the rules, as that might be unclear. An illustration on this is shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int arr1 [ ];
int arr2 [ ] = { [0] = 1, [12] = 36, [4] = 93 };
int pirate [ ] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, all the lines of array declaration are noncompliant as the size of the array is not specified explicitly. In the second line of declaration, the highest size defines the size implicitly, and in the third line, the total number of items defines the size, but these implicit declarations of size might be unclear, hence not used according to the rule.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rule R.19.2 (advisory): The union keyword should not be used
&lt;/h4&gt;

&lt;p&gt;The usage of union in order to access an object in different ways may cause mis-interpretation of the data. Hence this rule was designed to prevent the usage of unions in any circumstances. An example of a noncompliant code is shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;union U1 // Noncompliant
{ 
  float j;
  int i;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule R.20.4 (required): A macro shall not be defined with the same name as a keyword
&lt;/h4&gt;

&lt;p&gt;The reserved identifiers, function, and macros that come under the standard library should not be defined or undefined or redefined. The names of the standard library macros, functions, and objects are prohibited to be reused. An example illustration is discussed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define sqrt cathy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, the library function sqrt is being redefined, such that wherever the keyword sqrt occurs in the code, the pre-processor is instructed to just replace the same with the value “cathy,” where in a real case, the library function sqrt comes under the “math library” and is used to compute the square root of a given number.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools and Checkers
&lt;/h3&gt;

&lt;p&gt;Static analysis is an essential part of the software development process that involves the automatic examination of source code without executing the application. It is an effective technique that can help to identify potential errors, security vulnerabilities, and other defects in the code, thus improving the quality and reliability of embedded software. For embedded software, there are various types of static analysis techniques that can be employed to detect different types of issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Control flow analysis&lt;/strong&gt;: This type of analysis checks the control flow of the code to identify potential errors, such as unreachable code and infinite loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data flow analysis&lt;/strong&gt;: This type of analysis checks the flow of data through the code to identify potential errors, such as data races and memory leaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pointer analysis&lt;/strong&gt;: This type of analysis checks the use of pointers in the code to identify potential errors, such as dangling pointers and buffer overflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security analysis&lt;/strong&gt;: This type of analysis checks the code for potential security vulnerabilities, such as buffer overflows and SQL injection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance analysis&lt;/strong&gt;: This type of analysis checks the code for compliance with a specific standard, such as MISRA C or DO-178B.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automated tools can scan C codebase for MISRA C violations, generating detailed reports on potential issues and their locations.&lt;/p&gt;

&lt;h4&gt;
  
  
  LDRA Tool Suite (proprietary)
&lt;/h4&gt;

&lt;p&gt;The LDRA Tool Suite is a software analysis tool from LDRA that provides automated testing, static analysis, and dynamic testing capabilities. It includes MISRA C compliance checking and helps ensure the safety and reliability of embedded systems software.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parasoft C/C++test (proprietary)
&lt;/h4&gt;

&lt;p&gt;This tool offers robust MISRA C support, including rule checking, automated reporting, and integration with development environments. It can identify coding practices that might not strictly violate the standard but could introduce maintainability or safety concerns.&lt;/p&gt;

&lt;h4&gt;
  
  
  PC-lint Plus (proprietary)
&lt;/h4&gt;

&lt;p&gt;PC-lint Plus comes with a comprehensive rule set covering widely recognized coding standards such as MISRA, CERT-C and AUTOSAR. With an unparalleled focus on seamless integration and automation, PC-lint Plus stands out as the definitive solution for consistent, reliable, and superior quality C and C++ source code analysis.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cppcheck (free software/open source)
&lt;/h4&gt;

&lt;p&gt;It provides unique code analysis to detect bugs and focuses on detecting undefined behaviour and dangerous coding constructs. The goal is to have very few false positives. Cppcheck covers almost all the MISRA C 2012 rules. Including the amendments. Together with a C compiler you get full coverage.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;van der Linden, P. (1994). Expert C Programming. Prentice Hall.&lt;/li&gt;
&lt;li&gt;Bagnara, R., Bagnara, A., &amp;amp; Hill, P. M. (2019). The MISRA C coding standard: A key enabler for the development of safety-and security-critical embedded software. In embedded world Conference 2019—Proceedings (pp. 543-553).&lt;/li&gt;
&lt;li&gt;MISRA, MISRA C:2012 Addendum 2 (2018)— Coverage of MISRA C:2012
(including Amendment 1) against ISO/IEC TS 17961:2013 “C Secure”,
2nd ed. Nuneaton, Warwickshire CV10 0TU, UK: HORIBA MIRA
Ltd.&lt;/li&gt;
&lt;li&gt;Yamili, Y. C., &amp;amp; Kathiresh, M. (2021). Autosar and misra coding standards. In Automotive Embedded Systems: Key Technologies, Innovations, and Applications (pp. 37-70). Cham: Springer International Publishing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>c</category>
      <category>standard</category>
      <category>embedded</category>
      <category>misra</category>
    </item>
    <item>
      <title>Immutable Linux</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Thu, 07 Mar 2024 17:52:55 +0000</pubDate>
      <link>https://dev.to/khozaei/immutable-linux-4a4a</link>
      <guid>https://dev.to/khozaei/immutable-linux-4a4a</guid>
      <description>&lt;h3&gt;
  
  
  Embracing Immutable Architecture
&lt;/h3&gt;

&lt;p&gt;In the constantly evolving world of software engineering, traditional mutable systems have long faced challenges that hindered their stability, security, and scalability. These challenges have paved the way for a groundbreaking approach: immutable architecture. This paradigm shift offers a robust solution to age-old problems, revolutionizing how we design and manage complex systems, particularly in the realm of Linux distributions and containerized environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges of Mutable Systems
&lt;/h3&gt;

&lt;p&gt;Mutable systems, characterized by their ability to modify the core system, have historically faced several hurdles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unproducible Environments&lt;/strong&gt;: In mutable systems, manual configurations often varied across environments, leading to inconsistencies that could result in bugs and errors during development, testing, or deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration Drift&lt;/strong&gt;: Over time, configurations on mutable systems could deviate from their intended state due to multiple users and administrators making changes. This drift introduced inconsistencies and vulnerabilities, challenging system stability and security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security Vulnerabilities&lt;/strong&gt;: Providing write access to system files in mutable systems exposed them to exploitation by malware or human error. Even accidental modifications could compromise system integrity and introduce instability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficulty in Rollback&lt;/strong&gt;: Recovering from a faulty configuration or update in mutable systems proved complex, as changes were incremental and intertwined. Rolling back to a known good state often required manual intervention, carrying the risk of further unintended modifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Immutable Solution
&lt;/h3&gt;

&lt;p&gt;In response to these challenges, immutable architectures emerged, offering a paradigm shift in system design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintaining a Read-Only Core System&lt;/strong&gt;: Immutable architectures ensure system stability and security by maintaining a read-only core system. This prevents accidental or malicious modifications, enhancing overall system integrity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Atomic Updates&lt;/strong&gt;: Updates are applied atomically, deploying new versions of the system as complete, self-contained images. This ensures consistency and avoids partial updates that could lead to issues or vulnerabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Leveraging Containerization&lt;/strong&gt;: Immutable architectures often leverage containerization, where applications run in isolated containers. This further enhances security and prevents conflicts or dependencies on the core system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits of Immutable Architecture
&lt;/h3&gt;

&lt;p&gt;Immutable architecture brings a plethora of benefits to the table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security and Stability&lt;/strong&gt;: By eliminating direct modifications and enforcing a read-only core system, immutable architectures enhance security and stability, minimizing the attack surface and reducing the risk of configuration drifts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Predictable Environments&lt;/strong&gt;: With immutable architectures, environments are reproducible and consistent, making it easier to predict system behavior and reason about the impact of changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplified Rollback and Recovery&lt;/strong&gt;: Recovering from issues or failures becomes simpler with immutable architectures, as deploying a known good version involves swapping to a previous, verified state, reducing downtime and minimizing operational overhead.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Applications and Considerations
&lt;/h3&gt;

&lt;p&gt;Immutable architectures find application across various domains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Linux Distributions&lt;/strong&gt;: Many modern Linux distributions have embraced immutable architectures for their base systems, deploying new images instead of modifying existing ones to enhance security and consistency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containerized Applications&lt;/strong&gt;: Containerized applications, prevalent in platforms like Docker and Kubernetes, inherently follow immutable principles, promoting faster deployments and simplified management.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Immutable Linux Distributions
&lt;/h3&gt;

&lt;p&gt;An immutable Linux distribution is a type of operating system that adheres to the principle of immutability, where the core components of the system, including the root file system, are designed to be read-only and cannot be modified after the system has been deployed. Immutable Linux distributions offer a unique approach to system design and management, emphasizing security, reliability, and consistency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Feed12vclzctntuwekogg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Feed12vclzctntuwekogg.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Read-Only Root File System
&lt;/h4&gt;

&lt;p&gt;Traditional Linux distributions follow a mutable approach in which the core system, residing in the root filesystem, is writable. This approach allows for modifications, installations, and configurations, but it comes with inherent risks and complexities. Immutable distributions challenge this paradigm by adopting a read-only root filesystem, offering several key advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: By preventing direct modifications to critical system files, the attack surface for malware and human error shrinks significantly. This significantly reduces the risk of vulnerabilities and breaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved System Stability&lt;/strong&gt;: The read-only nature ensures the core system remains in a known good state, eliminating the possibility of accidental modifications or configuration drift that can destabilize the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Faster Rollbacks&lt;/strong&gt;: If an update introduces issues, reverting to the previous version is much simpler. The old system remains untouched, allowing a quick switch back to minimize downtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Greater Consistency&lt;/strong&gt;: All systems deployed from the same image share an identical root filesystem, ensuring consistency and predictability across environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the core system in an immutable Linux distribution resides in a read-only root filesystem, there are often exceptions made for specific directories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;/etc&lt;/strong&gt;: This directory typically houses configuration files for various applications and services. While immutability aims to minimize configuration drift, allowing modifications to /etc enables customization within a controlled environment. Some distributions utilize a writable overlay layer specifically for /etc, allowing changes to persist across reboots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/var&lt;/strong&gt;: This directory stores variable data, such as logs, temporary files, and caches. Since this data is constantly changing, it necessitates a writable location. However, some distributions might employ techniques like layering or dedicated writable partitions to manage /var within the context of immutability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/home&lt;/strong&gt;: This directory stores user data like documents, configurations, and application settings. Maintaining user data across updates is crucial, and /home needs to be writable for users to access and modify their files. Some distributions might place /home on a separate writable partition or utilize a dedicated writable overlay layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3jrxt3757gfa9aifjt5l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3jrxt3757gfa9aifjt5l.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Atomic Updates and Rollbacks: The Power of Reverting in Immutable Linux
&lt;/h4&gt;

&lt;p&gt;Immutable Linux distributions, with their read-only root filesystems, prioritize security and stability. Updates, however, can introduce unforeseen issues. Here's where atomic updates and rollbacks shine. These features ensure seamless transitions during updates and provide a safety net for quick recovery if needed.&lt;/p&gt;

&lt;h5&gt;
  
  
  The Power of Atomicity: All or Nothing
&lt;/h5&gt;

&lt;p&gt;Imagine a complex system update like a delicate surgery. One wrong move during the operation can have disastrous consequences. Similarly, traditional updates can leave the system in an inconsistent state if something goes wrong midway. Atomic updates address this by guaranteeing the entire update process happens as a single, indivisible unit. In the context of immutable systems, atomicity ensures either the entire update succeeds or the system remains unchanged.&lt;br&gt;
Here's a breakdown of atomic updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New Image Creation&lt;/strong&gt;: A complete system image, containing the updated files and configurations, is built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: The new image is deployed alongside the existing system. This doesn't affect the running system yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing and Validation&lt;/strong&gt;: Rigorous testing verifies the new system functions correctly before switching over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atomic Switch&lt;/strong&gt;: If all goes well, a swift transition occurs, completely replacing the running system with the new image. This switch is atomic, meaning either the entire update succeeds, or the system remains unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Undoing Mistakes: The Rollback Magic
&lt;/h5&gt;

&lt;p&gt;One of the main advantages of immutability is that it allows for easy rollback in case updates go wrong. If an update fails, the system can be quickly restored to a previous working state. Rollbacks function in the following way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Switching Back&lt;/strong&gt;: Since the previous system image remains untouched, simply switching back to it effectively rolls back the update. This is analogous to reverting a database transaction that encountered an error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal Downtime&lt;/strong&gt;: Rollbacks are typically fast, minimizing downtime and ensuring service continuity. This is crucial for production environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Approaches to Achieve Atomicity and Rollbacks
&lt;/h5&gt;

&lt;p&gt;Several techniques exist for implementing atomic updates and rollbacks in immutable distributions. Here's a look at three common approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;libostree&lt;/strong&gt;: This library, used by Fedora CoreOS and Silverblue, leverages a layered filesystem approach. It manages updates by creating new, read-only layers on top of the existing ones. Updates are atomic because either the entire new layer is successfully applied, or the previous state remains untouched. Rollbacks involve simply switching back to the previous layer, similar to undoing a database transaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A/B Partitioning&lt;/strong&gt;: This approach, used by RancherOS, utilizes two separate partitions for the root filesystem. One partition is active, while the other remains inactive. During an update, the new system image is written to the inactive partition. Once testing is complete, a quick switch activates the updated partition, effectively rolling out the update. In case of issues, the system can simply boot from the original, known good partition. This method mirrors a database transaction by preparing changes in a separate space before applying them to the main system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot-based Systems&lt;/strong&gt;: Some distributions like SUSE MicroOS use tools like Btrfs snapshots to create a point-in-time copy of the system before applying updates. This snapshot acts as a rollback point. If the update fails, the system can revert to the previous snapshot. Snapshotting offers a more lightweight alternative to full image-based approaches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl6rp9ocd06oygx2cnwdg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl6rp9ocd06oygx2cnwdg.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Automated Updates
&lt;/h4&gt;

&lt;p&gt;Immutable Linux distributions, with their read-only root filesystems, prioritize security and stability. However, manually managing updates on numerous systems can be time-consuming and prone to errors. Here's where unattended updates and scheduled updates come in, offering automation to keep your systems up-to-date and secure.&lt;/p&gt;

&lt;h5&gt;
  
  
  Unattended Updates
&lt;/h5&gt;

&lt;p&gt;Unattended updates allow you to configure your immutable system to automatically download and install new system images containing the latest updates. This eliminates the need for manual intervention and ensures your systems are always running the most recent and secure versions. Here are some key points about unattended updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Options&lt;/strong&gt;: Most distributions provide configuration options to define update behavior, such as specifying update frequency (daily, weekly, etc.) and defining a window for applying updates (outside peak usage hours for minimal disruption).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Management&lt;/strong&gt;: Update systems in immutable distributions typically handle dependency management automatically. Since new images are complete units, any dependencies required by the updates are already included.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing and Validation&lt;/strong&gt;: While updates happen automatically, some distributions might offer pre-testing options. You can test a new image in a controlled environment before deploying it to production systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Scheduled Updates
&lt;/h5&gt;

&lt;p&gt;Scheduled updates further enhance the automation capabilities. You can define specific times for updates to occur, ensuring they happen at your convenience and minimize disruption to critical workloads. Here's what you need to know about scheduled updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Schedule updates to occur during off-peak hours or maintenance windows to minimize impact on running applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictability&lt;/strong&gt;: Scheduled updates provide predictability in your update cycle, allowing you to plan system downtime and maintenance activities accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration with Management Tools&lt;/strong&gt;: Many distributions offer integration with system management tools like Ansible or Puppet. These tools can be used to automate the entire update process, including scheduling and triggering rollbacks if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Reverting to Stability
&lt;/h5&gt;

&lt;p&gt;Even with automated updates, unforeseen issues can arise. The beauty of immutable systems lies in their ability to easily rollback to a previous state. Here's how rollbacks work in the context of unattended and scheduled updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rollback Options&lt;/strong&gt;: Most distributions provide tools or configuration options to trigger a rollback if an update introduces problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutable History&lt;/strong&gt;: Since previous system images remain untouched, a rollback simply involves switching back to the previously deployed image. This ensures a quick and efficient recovery process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal Downtime&lt;/strong&gt;: Rollbacks are typically fast, minimizing downtime and ensuring service continuity for your applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fusa8fd7tkluflstzohh3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fusa8fd7tkluflstzohh3.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Declarative Configuration
&lt;/h4&gt;

&lt;p&gt;Traditional configuration management often involves editing text files directly on the system. This can be error-prone and time-consuming, especially for complex configurations. In contrast, declarative configuration focuses on what the desired state is, rather than how to achieve it.&lt;/p&gt;

&lt;p&gt;Here's a breakdown of the key differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Imperative (Traditional)&lt;/strong&gt;: Focuses on the specific steps or commands needed to achieve the desired configuration. This approach can be complex and error-prone, especially for intricate configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative&lt;/strong&gt;: Describes the desired state of the system in a human-readable format. The configuration tool then takes care of interpreting the desired state and making the necessary changes to achieve it. This approach is more concise and less error-prone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Declarative configuration offers several advantages in the context of immutable systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repeatability and Consistency&lt;/strong&gt;: Configurations are defined in reusable files, ensuring consistent system state across multiple deployments. This is crucial for maintaining identical environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human-Readable&lt;/strong&gt;: Configuration files are easier to understand and maintain compared to editing raw system files directly. This simplifies collaboration and troubleshooting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotence&lt;/strong&gt;: A key principle of declarative configuration is idempotence. This means that running the configuration multiple times will result in the same desired state, even if the system state has already been achieved. This prevents accidental configuration drift and ensures consistency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: Configuration files can be version controlled, allowing you to track changes and revert to previous configurations if needed. This enhances rollback capabilities and facilitates auditing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Several tools are commonly used for declarative configuration management in immutable Linux distributions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ansible&lt;/strong&gt;: A powerful tool offering a YAML-based language to define configurations. It can manage configurations across multiple systems and platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaltStack&lt;/strong&gt;: Another popular option with a declarative language and a focus on automation and orchestration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chef&lt;/strong&gt;: A mature tool with a Ruby-based language for configuration management. While not as widely used in immutable deployments, it's still a viable option in some cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While declarative configuration management tools play a significant role in managing immutable Linux distributions, some distributions also offer APIs as an alternative or complementary approach.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;While immutable architecture offers significant advantages, it's essential to consider potential trade-offs, such as reduced flexibility and increased operational overhead, particularly in comparison to mutable systems. However, for environments where security, reliability, and ease of rollback are paramount, immutable architecture emerges as a powerful tool for building resilient and scalable systems.&lt;/p&gt;

&lt;p&gt;As the tech landscape continues to evolve, understanding and embracing immutable architecture can be a transformative step in navigating the complexities of modern software development and deployment. By building on a foundation of immutability, organizations can pave the way for more resilient, secure, and efficient systems, poised to thrive in an ever-changing digital landscape.&lt;/p&gt;

&lt;h5&gt;
  
  
  References
&lt;/h5&gt;

&lt;p&gt;Perry, M. L. (2020). The Art of Immutable Architecture. Apress.&lt;/p&gt;

</description>
      <category>immutable</category>
      <category>linux</category>
      <category>embedded</category>
      <category>container</category>
    </item>
    <item>
      <title>What is Xenomai?</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Wed, 28 Feb 2024 15:45:06 +0000</pubDate>
      <link>https://dev.to/khozaei/what-is-xenomai-4db</link>
      <guid>https://dev.to/khozaei/what-is-xenomai-4db</guid>
      <description>&lt;h3&gt;
  
  
  Understanding Hard, Firm, and Soft Real-Time Systems
&lt;/h3&gt;

&lt;p&gt;Real-time systems are often classified based on the strictness of their timing requirements. Here are the three main classifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Hard Real-Time Systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard real-time systems have strict timing constraints where missing a deadline is considered catastrophic and unacceptable.&lt;/li&gt;
&lt;li&gt;In hard real-time systems, the correctness of the system's behavior depends not only on the logical result of computations but also on the time at which the results are produced.&lt;/li&gt;
&lt;li&gt;Examples of hard real-time systems include &lt;strong&gt;flight control systems&lt;/strong&gt;, &lt;strong&gt;medical devices such as pacemakers&lt;/strong&gt;, and automotive safety systems like &lt;strong&gt;anti-lock brakes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Firm Real-Time Systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firm real-time systems also have strict timing requirements, but occasional deadline misses can be tolerated as long as they happen infrequently and the system can still maintain its overall usefulness.&lt;/li&gt;
&lt;li&gt;In firm real-time systems, missing deadlines might result in a degradation of system performance but not catastrophic failure.&lt;/li&gt;
&lt;li&gt;Examples of firm real-time systems include &lt;strong&gt;multimedia streaming&lt;/strong&gt; applications where occasional frame drops or delays are tolerable but should be minimized to maintain user experience.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Soft Real-Time Systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Soft real-time systems have timing constraints, but missing deadlines does not necessarily lead to system failure or significant degradation in system performance.&lt;/li&gt;
&lt;li&gt;In soft real-time systems, meeting deadlines is desirable but not mandatory. The system can still provide useful results even if deadlines are occasionally missed.&lt;/li&gt;
&lt;li&gt;Examples of soft real-time systems include &lt;strong&gt;online video conferencing&lt;/strong&gt; applications, where a slight delay in transmitting audio or video data may be acceptable as long as the overall communication remains effective.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Real time is the time it takes for an action to have a noticeable effect. (Paul Graham)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Predictable System Challenges
&lt;/h3&gt;

&lt;p&gt;The focus on computer system architecture design is often to improve the performance for general-purpose use, which does not include a strict requirement of timing.&lt;/p&gt;

&lt;p&gt;Predictable system challenges such as CPU pipeline, cache, multi-threading, and multi-core play crucial roles in determining the predictability and performance of real-time systems. Here's a brief description of each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CPU Pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CPU pipeline is a fundamental component of modern processors that allows them to execute multiple instructions concurrently by breaking down instruction execution into multiple stages.&lt;/li&gt;
&lt;li&gt;While pipeline architectures improve instruction throughput and overall performance, they can introduce challenges for real-time systems due to potential pipeline stalls, dependencies, and branch prediction errors that can lead to unpredictable execution times.&lt;/li&gt;
&lt;li&gt;Real-time systems need to carefully manage pipeline hazards to ensure predictable behavior and meet timing constraints.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caches are small, high-speed memory units located on or near the CPU that store frequently accessed data and instructions to reduce access latency and improve performance.&lt;/li&gt;
&lt;li&gt;While caches significantly enhance system performance for non-real-time applications by reducing memory access times, they can introduce unpredictability in real-time systems due to cache misses, cache coherence issues, and the non-deterministic nature of cache replacement policies.&lt;/li&gt;
&lt;li&gt;Real-time systems must employ cache management techniques such as cache partitioning, cache locking, and cache-aware scheduling to control cache behavior and maintain predictability.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Multi-threading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-threading enables concurrent execution of multiple threads within a single process, allowing programs to utilize CPU resources more efficiently and improve responsiveness.&lt;/li&gt;
&lt;li&gt;However, multi-threading introduces challenges for real-time systems, including thread scheduling overhead, priority inversion, and contention for shared resources such as CPU cores, memory, and I/O devices.&lt;/li&gt;
&lt;li&gt;Real-time systems need to implement thread scheduling policies that prioritize critical tasks, minimize thread interference, and prevent priority inversion to ensure timely execution of tasks and meet deadlines.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Multi-Core:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-core processors integrate multiple CPU cores on a single chip, enabling parallel execution of tasks and higher overall system throughput.&lt;/li&gt;
&lt;li&gt;While multi-core architectures offer increased computational power and scalability, they pose challenges for real-time systems in terms of task allocation, load balancing, and inter-core communication.&lt;/li&gt;
&lt;li&gt;Real-time systems must employ efficient task scheduling and synchronization mechanisms to leverage the benefits of multi-core processors while maintaining predictability and meeting timing constraints.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-Time Operating System
&lt;/h3&gt;

&lt;p&gt;A real-time operating system (RTOS) serves as a critical intermediary layer between application software and hardware components in embedded systems and other time-critical environments. One of the primary functions of an RTOS is to abstract and manage hardware resources efficiently, shielding application developers from the intricacies of low-level hardware interaction. This abstraction allows developers to focus on implementing the desired functionality of their applications without needing to delve deeply into the specifics of the underlying hardware platform.&lt;/p&gt;

&lt;p&gt;RTOSs achieve this abstraction by providing a set of standardized interfaces and services for accessing hardware resources such as CPU processing time, memory, I/O devices, and communication interfaces. These interfaces typically include system calls, device drivers, and middleware components that enable developers to interact with hardware resources in a platform-independent and programmer-friendly manner.&lt;/p&gt;

&lt;p&gt;By encapsulating hardware details and providing a unified programming interface, RTOSs enable application developers to write portable and scalable code that can be easily adapted to different hardware platforms with minimal effort. This abstraction also promotes code reusability and maintainability, as developers can focus on writing application logic without being tied to specific hardware implementations.&lt;/p&gt;

&lt;p&gt;Additionally, RTOSs are designed to minimize overhead and maximize system efficiency to meet the stringent timing requirements of real-time applications. Unlike general-purpose operating systems (GPOS), which may prioritize features such as multitasking, multi-user support, and graphical user interfaces, RTOSs are optimized for low-latency, deterministic operation.&lt;/p&gt;

&lt;p&gt;RTOSs achieve low overhead by employing lightweight task scheduling algorithms, efficient memory management strategies, and streamlined kernel designs. These optimizations reduce context switching times, minimize memory footprint, and ensure rapid response to system events, enabling real-time applications to meet their timing constraints reliably.&lt;/p&gt;

&lt;p&gt;Moreover, the reduced overhead of RTOSs translates into lower system costs and improved predictability for embedded systems and other resource-constrained environments. By minimizing unnecessary computational overhead and resource contention, RTOSs enable developers to achieve higher performance and tighter control over system behavior, leading to more efficient utilization of hardware resources and reduced development costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux
&lt;/h3&gt;

&lt;p&gt;Linux is one of the most widely used general-purpose operating systems (GPOS) in the world. Originally developed as a hobby project by Linus Torvalds in the early 1990s, Linux has since evolved into a powerful and versatile operating system that powers a vast array of computing devices, from personal computers and servers to embedded systems and supercomputers.&lt;/p&gt;

&lt;p&gt;As a general-purpose operating system, Linux is designed to provide a rich set of features and functionalities to support a wide range of computing tasks and applications. However, while Linux excels as a general-purpose operating system, it is not typically used in scenarios requiring real-time capabilities. Real-time operating systems (RTOS) like VxWorks, FreeRTOS, or QNX are specifically designed to provide deterministic behavior and meet strict timing constraints, which are essential for real-time applications such as industrial control systems, automotive electronics, and medical devices.&lt;/p&gt;

&lt;p&gt;Linux, in contrast, is optimized for general-purpose computing tasks where determinism and timing guarantees are not critical. While efforts have been made to improve Linux's real-time capabilities through technologies like the PREEMPT-RT patch, it may still not be suitable for applications with ultra-low-latency or hard real-time requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7o42m9qrqtt67dyjvmaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7o42m9qrqtt67dyjvmaa.png" alt="Linux Kernel Architecture" width="775" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-Time Linux
&lt;/h3&gt;

&lt;p&gt;In the realm of real-time computing, achieving precise timing guarantees and deterministic behavior is paramount for applications operating in time-critical environments. Linux, a versatile and widely used general-purpose operating system, has garnered attention as a platform for real-time applications despite its non-deterministic nature. Two prominent approaches have emerged to augment Linux with real-time capabilities: the single kernel approach with the PREEMPT-RT patch and the dual kernel approach with Xenomai. Each approach offers distinct methodologies for providing real-time responsiveness within the Linux ecosystem, catering to a diverse range of real-time application requirements. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftgbb0nexvt3f0p8qrbb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftgbb0nexvt3f0p8qrbb9.png" alt="Real-Time Linux Approaches" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Single Kernel Approach with PREEMPT-RT
&lt;/h4&gt;

&lt;p&gt;In the single kernel approach, real-time capabilities are added to the Linux kernel through the PREEMPT-RT patch. This patch modifies the Linux kernel to reduce latency and improve responsiveness, making it more suitable for real-time applications. Some key features and characteristics of the PREEMPT-RT approach include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Preemption: The PREEMPT-RT patch enables full preemption of the Linux kernel, allowing higher-priority tasks to preempt lower-priority tasks even during critical sections of code execution. This reduces latency and improves the responsiveness of real-time tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interrupt Handling: Interrupt handling in the Linux kernel is optimized to minimize interrupt latency, ensuring timely response to external events. This is crucial for real-time applications that rely on rapid event handling and precise timing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduler Enhancements: The Linux scheduler is modified to support priority-based scheduling algorithms that prioritize real-time tasks over non-real-time tasks. This ensures that critical tasks are executed in a timely manner and meet their deadlines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determinism: While the PREEMPT-RT patch improves the real-time capabilities of the Linux kernel, it may not provide the strict determinism required for certain real-time applications with ultra-low-latency or hard real-time requirements. However, it offers significantly improved real-time performance compared to the vanilla Linux kernel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single Kernel: In the single kernel approach, real-time tasks and non-real-time tasks share the same Linux kernel, providing a unified execution environment for both types of applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Dual Kernel Approach with Xenomai
&lt;/h4&gt;

&lt;p&gt;In the dual kernel approach, real-time capabilities are provided by a separate real-time microkernel running alongside the Linux kernel. Xenomai is one such real-time microkernel that operates in parallel with Linux, providing deterministic behavior and strict timing guarantees for real-time tasks. Here are some key aspects of the Xenomai approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Separation of Concerns: Xenomai operates as a separate real-time executive (Xenomai nucleus) running alongside the Linux kernel. Real-time tasks are executed within the Xenomai environment, while non-real-time tasks continue to run within the Linux environment. This separation ensures that real-time tasks are shielded from non-real-time activities and can meet their timing requirements reliably.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determinism: Xenomai provides strict determinism and precise timing guarantees for real-time tasks by implementing priority-based scheduling algorithms, minimal interrupt latency, and efficient inter-task communication mechanisms. This makes it suitable for applications with hard real-time requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interrupt Handling: Interrupts are efficiently managed within the Xenomai environment to minimize interrupt latency and ensure timely response to external events. Xenomai provides mechanisms for prioritizing interrupt handling and preempting lower-priority tasks when necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux Compatibility: Xenomai is designed to be compatible with the Linux ecosystem, allowing real-time tasks to interact with Linux services and device drivers seamlessly. This enables developers to leverage existing Linux infrastructure and libraries while developing real-time applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dual Kernel Architecture: In the dual kernel approach, the Linux kernel and Xenomai nucleus operate as separate entities, each managing its own set of resources and tasks. This architecture provides a clear separation of concerns between real-time and non-real-time activities, ensuring that real-time tasks can execute predictably without being affected by non-real-time activities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Xenomai
&lt;/h3&gt;

&lt;p&gt;Xenomai is a real-time development framework designed for Linux-based systems, enabling the creation of applications with strict timing requirements. It employs a dual kernel architecture, comprising a small real-time microkernel called the Xenomai nucleus, which runs alongside the Linux kernel. This separation ensures that real-time tasks can execute independently of non-real-time tasks, providing deterministic behavior and precise timing guarantees.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9yxk2bxiciu5rhuyh70w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9yxk2bxiciu5rhuyh70w.png" alt="Xenomai Architecture" width="755" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  I-pipe
&lt;/h4&gt;

&lt;p&gt;The Interrupt Pipeline (I-pipe) is a technology used by Xenomai to enable coexistence between the Linux kernel and the Xenomai nucleus. The I-pipe intercepts and handles interrupts before they reach the Linux kernel, allowing Xenomai to provide deterministic interrupt handling and low-latency response times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs4xw73e45j5mhp4ctizf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs4xw73e45j5mhp4ctizf.png" alt="I-pipe" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Dovetail
&lt;/h4&gt;

&lt;p&gt;Dovetail is a component of Xenomai that facilitates the integration between the Linux kernel and the Xenomai nucleus. It provides mechanisms for coordinating interrupt handling, scheduling, and resource management between the two kernels, ensuring compatibility and seamless operation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Emulated Virtualization Layer (EVL)
&lt;/h4&gt;

&lt;p&gt;A recent addition to Xenomai is the Emulated Virtualization Layer (EVL), which virtualizes real-time services within the Linux kernel context. EVL aims to provide a lightweight and efficient real-time execution environment by leveraging modern Linux kernel features and hardware capabilities. It enables real-time tasks to execute directly within the Linux kernel while maintaining strict determinism and low-latency performance.&lt;/p&gt;

&lt;p&gt;A program that implemented by Xenomai is like the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbxp2sa56tkdqdg0lf5s2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbxp2sa56tkdqdg0lf5s2.png" alt="Xenomai Program" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Liu, J. W. S. (2000). Real-Time Systems. Prentice Hall.&lt;/li&gt;
&lt;li&gt;Laplante, P. A. (2011). Real-Time Systems Design and Analysis: Tools for the Practitioner. Wiley-IEEE Press.&lt;/li&gt;
&lt;li&gt;Xenomai. (2023). Overview. Retrieved from &lt;a href="https://v4.xenomai.org/overview/" rel="noopener noreferrer"&gt;https://v4.xenomai.org/overview/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>realtime</category>
      <category>xenomai</category>
      <category>iot</category>
      <category>linux</category>
    </item>
    <item>
      <title>Conan by example for C</title>
      <dc:creator>Amin Khozaei</dc:creator>
      <pubDate>Thu, 29 Jun 2023 19:59:27 +0000</pubDate>
      <link>https://dev.to/khozaei/conan-by-example-for-c-2529</link>
      <guid>https://dev.to/khozaei/conan-by-example-for-c-2529</guid>
      <description>&lt;p&gt;As a C developer, you know that many tools exist for managing projects. Every C projects use a subset of these tools, so if you want to use a C library in your project, you should understand how these tools work. If you choose CMake as the build generator of your project, and you want to use a library that uses different build tools like Autotools, you should know how to use Autotools in your CMake file. Conan supports multiple build generators and makes suitable configs based on desired build generator. So, you could select each library that exists in Conan repositories. &lt;br&gt;
Conan can do more things like:&lt;br&gt;
It is fully decentralized. Users can host their packages on their servers, privately. Integrates with Artifactory and Bintray.&lt;br&gt;
Portable. Works across all platforms, including Linux, OSX, Windows, Solaris, FreeBSD, embedded and cross-compiling, docker, WSL&lt;br&gt;
Manage binaries. It can create, upload and download binaries for any configuration and platform, even cross-compiling, saving lots of time in development and continuous integration. The binary compatibility can be configured and customized. Manage all your artifacts in the same way on all platforms.&lt;br&gt;
Integrates with any build system, including any proprietary and custom one. Provides tested support for major build systems (CMake, MSBuild, Makefiles, Meson, etc).&lt;br&gt;
Extensible: Its Python-based recipes, together with extension points allow for great power and flexibility.&lt;br&gt;
Stable. Used in production by many companies, since 1.0 there is a commitment not to break package recipes and documented behavior.&lt;br&gt;
Read more on its &lt;a href="https://conan.io/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt; or &lt;a href="https://github.com/conan-io/conan" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to install Conan
&lt;/h2&gt;

&lt;p&gt;Python 3.6 or newer is required to install Conan tool. The following commands should run to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;conan
conan profile detect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;‍‍&lt;br&gt;
If you have installed toolchains, the output of recent command is like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;gcc&amp;gt;=5,&lt;/span&gt; &lt;span class="err"&gt;using&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;major&lt;/span&gt; &lt;span class="err"&gt;as&lt;/span&gt; &lt;span class="err"&gt;version&lt;/span&gt;
&lt;span class="err"&gt;gcc&lt;/span&gt; &lt;span class="err"&gt;C++&lt;/span&gt; &lt;span class="err"&gt;standard&lt;/span&gt; &lt;span class="err"&gt;library:&lt;/span&gt; &lt;span class="err"&gt;libstdc++11&lt;/span&gt;
&lt;span class="err"&gt;Detected&lt;/span&gt; &lt;span class="err"&gt;profile:&lt;/span&gt;
&lt;span class="nn"&gt;[settings]&lt;/span&gt;
&lt;span class="py"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;x86_64&lt;/span&gt;
&lt;span class="py"&gt;build_type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Release&lt;/span&gt;
&lt;span class="py"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gcc&lt;/span&gt;
&lt;span class="py"&gt;compiler.cppstd&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gnu17&lt;/span&gt;
&lt;span class="py"&gt;compiler.libcxx&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;libstdc++11&lt;/span&gt;
&lt;span class="py"&gt;compiler.version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;12&lt;/span&gt;
&lt;span class="py"&gt;os&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;

&lt;span class="err"&gt;WARN:&lt;/span&gt; &lt;span class="err"&gt;This&lt;/span&gt; &lt;span class="err"&gt;profile&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;guess&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;environment,&lt;/span&gt; &lt;span class="err"&gt;please&lt;/span&gt; &lt;span class="err"&gt;check&lt;/span&gt; &lt;span class="err"&gt;it.&lt;/span&gt;
&lt;span class="err"&gt;WARN:&lt;/span&gt; &lt;span class="err"&gt;The&lt;/span&gt; &lt;span class="err"&gt;output&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;this&lt;/span&gt; &lt;span class="err"&gt;command&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;not&lt;/span&gt; &lt;span class="err"&gt;guaranteed&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;be&lt;/span&gt; &lt;span class="err"&gt;stable&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;can&lt;/span&gt; &lt;span class="err"&gt;change&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;future&lt;/span&gt; &lt;span class="err"&gt;Conan&lt;/span&gt; &lt;span class="err"&gt;versions.&lt;/span&gt;
&lt;span class="err"&gt;WARN:&lt;/span&gt; &lt;span class="err"&gt;Use&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;own&lt;/span&gt; &lt;span class="err"&gt;profile&lt;/span&gt; &lt;span class="err"&gt;files&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;stability.&lt;/span&gt;
&lt;span class="err"&gt;Saving&lt;/span&gt; &lt;span class="err"&gt;detected&lt;/span&gt; &lt;span class="err"&gt;profile&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;/home/amin/.conan2/profiles/default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conan supports http and https proxies. If you want to config proxy, the following variables in GNU/Linux should be set.&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;export &lt;/span&gt;&lt;span class="nv"&gt;HTTP_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://ip:port"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HTTPS_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://ip:port"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Conan
&lt;/h2&gt;

&lt;p&gt;Libraries in the main repository could be accessed by &lt;a href="https://conan.io/" rel="noopener noreferrer"&gt;conan.io&lt;/a&gt; or by &lt;code&gt;conan search &amp;lt;libname&amp;gt;&lt;/code&gt;.  After finding the suitable version of each library, the Conan config file should be configured. Conan supports two different config styles, &lt;code&gt;conanfile.py&lt;/code&gt; which uses Python to config Conan tool, and &lt;code&gt;conanfile.txt&lt;/code&gt; which has ini style.&lt;/p&gt;

&lt;p&gt;An example is a cli software that gets some options and makes a decision on each option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[requires]&lt;/span&gt;
&lt;span class="err"&gt;glib/2.73.0&lt;/span&gt;

&lt;span class="nn"&gt;[generators]&lt;/span&gt;
&lt;span class="err"&gt;CMakeDeps&lt;/span&gt;
&lt;span class="err"&gt;CMakeToolchain&lt;/span&gt;

&lt;span class="nn"&gt;[options]&lt;/span&gt;
&lt;span class="err"&gt;glib*:&lt;/span&gt;&lt;span class="py"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The conanfile.txt has multiple sections, &lt;code&gt;requires&lt;/code&gt; section used to define imported libraries with specific version, &lt;code&gt;generator&lt;/code&gt; section used to define your project's generator like CMake, and &lt;code&gt;options&lt;/code&gt; section used to config each imported library, for example, &lt;code&gt;glib*:shared=False&lt;/code&gt; used to compile glib statically. Now it's time to create &lt;code&gt;CMakefile.txt&lt;/code&gt;. Here is the content of &lt;code&gt;CMakefile.txt&lt;/code&gt;.&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;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 3.22.6&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;net_alert C&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;find_package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;glib REQUIRED&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;include_directories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;include&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&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_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; src/main.c &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;target_link_libraries&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_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; glib::glib-2.0&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;target_link_libraries&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_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; glib::gio-2.0&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conan makes cmake presets for each library, so &lt;code&gt;find_package&lt;/code&gt; can find the library. &lt;code&gt;target_link_libraries&lt;/code&gt; should be used to link with our example. Here is the example code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;glib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;glib/gi18n.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;gio/gio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;config_s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gint&lt;/span&gt; &lt;span class="n"&gt;server_port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GString&lt;/span&gt; &lt;span class="n"&gt;server_ip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;gboolean&lt;/span&gt; &lt;span class="n"&gt;server_mode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GString&lt;/span&gt; &lt;span class="n"&gt;wav&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GString&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;GString&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gbuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GOptionEntry&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_OPTION_ARG_INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Server_port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_OPTION_ARG_STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Server ip address"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_OPTION_ARG_NONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Server mode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"wav"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'w'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_OPTION_ARG_STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wav&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"WAV alert file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;G_OPTION_ARG_STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Command to send to the server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GError&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;GOptionContext&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;wav&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_string_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alert.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2986&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;gbuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_string_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_option_context_new&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"net_alert: an application to alert on demand"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;g_option_context_add_main_entries&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;g_option_context_add_group&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//gtk_get_option_group (TRUE));&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;g_option_context_parse&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
        &lt;span class="n"&gt;g_print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"option parsing failed: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;g_string_overwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wav&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wav&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"port: %i&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;server address: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;server mode: %i&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Wav: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;command: %s&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_port&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_mode&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wav&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;server_mode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;client_mode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conan sets include paths for imported libraries, so header files could be included directly. For a complete version of the example follow the &lt;a href="https://github.com/khozaei/net_alert" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the example
&lt;/h2&gt;

&lt;p&gt;First of all, Canon must build imported libraries. Then created script &lt;code&gt;conanbuild.sh&lt;/code&gt; should be sourced by bash shell. After that, CMake can generate build of our example. The following commands needs to build the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;conan &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--output-folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build &lt;span class="nt"&gt;--build&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;missing
&lt;span class="nb"&gt;cd &lt;/span&gt;build
&lt;span class="nb"&gt;source &lt;/span&gt;conanbuild.sh
cmake .. &lt;span class="nt"&gt;-DCMAKE_TOOLCHAIN_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;conan_toolchain.cmake &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Release
cmake &lt;span class="nt"&gt;--build&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Conan makes C developers happy but, not all libraries are available in main repository of Conan. So, C developers should make their self repository or use libraries with an understanding of more than one build tools.&lt;/p&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>conan</category>
    </item>
  </channel>
</rss>
