<?xml version="1.0" encoding="UTF-8"?>

<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Parker Jones Dev Blog - mastering-c</title>
    <subtitle>Local-first, reproducible systems in Rust and Nix — and using AI as a power tool without getting credulous about it. I build the unglamorous plumbing and write up what actually happened, including what broke.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://parkerjones.dev/series/mastering-c/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://parkerjones.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-06-14T00:00:00+00:00</updated>
    <id>https://parkerjones.dev/series/mastering-c/atom.xml</id>
    <entry xml:lang="en">
        <title>Mastering C with Effective C: Introduction to Makefiles</title>
        <published>2024-06-14T00:00:00+00:00</published>
        <updated>2024-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://parkerjones.dev/posts/mastering-c-makefiles/"/>
        <id>https://parkerjones.dev/posts/mastering-c-makefiles/</id>
        <content type="html" xml:base="https://parkerjones.dev/posts/mastering-c-makefiles/">&lt;h3 id=&quot;mastering-c-with-effective-c-introduction-to-makefiles&quot;&gt;Mastering C with Effective C: Introduction to Makefiles&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h4&gt;
&lt;p&gt;Welcome to the first post in the &lt;a href=&quot;&#x2F;mastering-c&quot;&gt;&quot;Mastering C with Effective C&quot; series&lt;&#x2F;a&gt;! In this post, we&#x27;ll explore the basics of Makefiles and how they can help you manage and automate the build process of your C projects. Makefiles are an essential tool for any C programmer, simplifying the compilation process, managing dependencies, and ensuring efficient builds.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;what-is-a-makefile&quot;&gt;What is a Makefile?&lt;&#x2F;h4&gt;
&lt;p&gt;A Makefile is a special file, containing a set of directives used by the &lt;code&gt;make&lt;&#x2F;code&gt; build automation tool to compile and link a program. It defines rules on how to build different parts of your project, making it easier to manage larger projects with multiple source files.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;benefits-of-using-makefiles&quot;&gt;Benefits of Using Makefiles&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automation&lt;&#x2F;strong&gt;: Automates the compilation process, reducing the chances of human error.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Efficiency&lt;&#x2F;strong&gt;: Only rebuilds the parts of the project that have changed, saving time during development.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Organization&lt;&#x2F;strong&gt;: Keeps build instructions in a single, easy-to-read file.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Portability&lt;&#x2F;strong&gt;: Ensures that your project can be built consistently across different environments.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;basic-structure-of-a-makefile&quot;&gt;Basic Structure of a Makefile&lt;&#x2F;h4&gt;
&lt;p&gt;A Makefile typically consists of rules. Each rule defines how to build a target from its dependencies. The general structure is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;makefile&quot;&gt;target: dependencies
    command
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;target&lt;&#x2F;strong&gt;: The file to be generated (e.g., executable or object file).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;dependencies&lt;&#x2F;strong&gt;: The files that the target depends on (e.g., source files).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;command&lt;&#x2F;strong&gt;: The command to generate the target from the dependencies (e.g., compile command).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;example-a-simple-makefile&quot;&gt;Example: A Simple Makefile&lt;&#x2F;h4&gt;
&lt;p&gt;Let&#x27;s start with a simple example. Suppose we have a project with three source files: &lt;code&gt;main.c&lt;&#x2F;code&gt;, &lt;code&gt;file1.c&lt;&#x2F;code&gt;, and &lt;code&gt;file2.c&lt;&#x2F;code&gt;. Here&#x27;s a basic Makefile to compile these files into a single executable:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;makefile&quot;&gt;# the compiler to use
CC = clang

# compiler flags:
#  -g    adds debugging information to the executable file
#  -Wall turns on most, but not all, compiler warnings
CFLAGS  = -g -Wall
  
# files to link:
LFLAGS = #-lcs50
  
# the name to use for the output file:
TARGET = my_program
  
# the list of source files
SRCS = main.c file1.c file2.c
  
# the list of object files (derived from the source files)
OBJS = $(SRCS:.c=.o)
  
all: $(TARGET)
  
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LFLAGS)
  
%.o: %.c
	$(CC) $(CFLAGS) -c $&amp;lt; -o $@
  
clean:
	rm -f $(OBJS) $(TARGET)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;breaking-down-the-makefile&quot;&gt;Breaking Down the Makefile&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Compiler and Flags&lt;&#x2F;strong&gt;: We specify the compiler (&lt;code&gt;clang&lt;&#x2F;code&gt;) and the compiler flags (&lt;code&gt;CFLAGS&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Source and Object Files&lt;&#x2F;strong&gt;: &lt;code&gt;SRCS&lt;&#x2F;code&gt; lists the source files, and &lt;code&gt;OBJS&lt;&#x2F;code&gt; lists the corresponding object files.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Build Rules&lt;&#x2F;strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;all: $(TARGET)&lt;&#x2F;code&gt;: The default target, which builds the executable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;$(TARGET): $(OBJS)&lt;&#x2F;code&gt;: The rule to link the object files into the final executable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;%.o: %.c&lt;&#x2F;code&gt;: A pattern rule to compile source files into object files.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clean Rule&lt;&#x2F;strong&gt;: The &lt;code&gt;clean&lt;&#x2F;code&gt; rule removes the generated object files and the executable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;using-the-makefile&quot;&gt;Using the Makefile&lt;&#x2F;h4&gt;
&lt;p&gt;To use the Makefile, simply run the &lt;code&gt;make&lt;&#x2F;code&gt; command in the terminal within the project directory. This will compile and link the source files into the &lt;code&gt;my_program&lt;&#x2F;code&gt; executable.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;make
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To clean up the generated files, run:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;make clean
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;additional-resources&quot;&gt;Additional Resources&lt;&#x2F;h4&gt;
&lt;p&gt;For more information and deeper dives into Makefiles, check out these resources:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;make&#x2F;manual&#x2F;make.html&quot;&gt;GNU Make Manual&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Make_(software)&quot;&gt;GNU Make on Wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tutorialspoint.com&#x2F;makefile&#x2F;index.htm&quot;&gt;Makefile Tutorial - TutorialsPoint&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;makefiletutorial.com&#x2F;&quot;&gt;Makefile Tutorial by Example&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cmake.org&#x2F;documentation&#x2F;&quot;&gt;CMake Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h4&gt;
&lt;p&gt;Makefiles are a powerful tool for managing the build process of your C projects. By automating compilation and linking, they save time and reduce errors. In this post, we covered the basics of Makefiles, their benefits, and how to create a simple Makefile for a C project.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;next-up&quot;&gt;Next Up&lt;&#x2F;h4&gt;
&lt;p&gt;Stay tuned for the next post in the &quot;Mastering C with Effective C&quot; series, where we&#x27;ll dive into data types and variables in C. We will explore different data types, how to declare and use variables, and the importance of understanding data representation.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Happy coding!&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Mastering C: Building a Project with Nix Flakes</title>
        <published>2024-06-14T00:00:00+00:00</published>
        <updated>2024-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://parkerjones.dev/posts/mastering-c-nix-flake/"/>
        <id>https://parkerjones.dev/posts/mastering-c-nix-flake/</id>
        <content type="html" xml:base="https://parkerjones.dev/posts/mastering-c-nix-flake/">&lt;h1 id=&quot;upgrading-your-c-project-build-to-use-nix-flakes-a-modern-guide&quot;&gt;Upgrading Your C Project Build to Use Nix Flakes: A Modern Guide&lt;&#x2F;h1&gt;
&lt;p&gt;Hello again, fellow C enthusiasts! In our previous blog post, we explored building a C program with external library dependencies using Nix. Today, we’re taking it a step further by upgrading our Nix setup to use Nix flakes, a more structured and modern way to manage dependencies and ensure reproducibility. This post will guide you through updating your existing Nix build to a Nix flake and explain each component in detail. Let’s dive in!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-nix-flakes&quot;&gt;What Are Nix Flakes?&lt;&#x2F;h2&gt;
&lt;p&gt;Nix flakes introduce a standardized way to define Nix projects, providing better dependency management, versioning, and reproducibility. They offer:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consistency&lt;&#x2F;strong&gt;: Ensures builds are reproducible across different environments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ease of Use&lt;&#x2F;strong&gt;: Simplifies the setup and management of dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Modularity&lt;&#x2F;strong&gt;: Allows sharing and composing Nix expressions easily.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For more details, you can check out the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nixos.wiki&#x2F;wiki&#x2F;Flakes&quot;&gt;Nix Flakes documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;transitioning-from-a-classic-nix-setup-to-nix-flakes&quot;&gt;Transitioning from a Classic Nix Setup to Nix Flakes&lt;&#x2F;h2&gt;
&lt;p&gt;We’ll start with our &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt; C program, which uses the &lt;code&gt;jansson&lt;&#x2F;code&gt; library for JSON parsing. We’ll convert our existing &lt;code&gt;default.nix&lt;&#x2F;code&gt; to a &lt;code&gt;flake.nix&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;original-default-nix&quot;&gt;Original &lt;code&gt;default.nix&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Here’s a quick look at our original &lt;code&gt;default.nix&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;{ pkgs ? import &amp;lt;nixpkgs&amp;gt; {} }:

let
  jansson = pkgs.jansson;
in
pkgs.stdenv.mkDerivation {
  pname = &amp;quot;simple-parse-example&amp;quot;;
  version = &amp;quot;1.0&amp;quot;;

  src = .&#x2F;.;

  nativeBuildInputs = [ pkgs.clang ];
  buildInputs = [ jansson ];

  buildPhase = &amp;#39;&amp;#39;
    clang -g -Wall -o simple-parse-example simple-parse-example.c -ljansson
  &amp;#39;&amp;#39;;

  installPhase = &amp;#39;&amp;#39;
    mkdir -p $out&#x2F;bin
    cp simple-parse-example $out&#x2F;bin&#x2F;
  &amp;#39;&amp;#39;;

  meta = with pkgs.lib; {
    description = &amp;quot;A simple program using jansson&amp;quot;;
    license = licenses.mit;
    maintainers = [ maintainers.yourname ];
    platforms = platforms.unix;
  };
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;converting-to-flake-nix&quot;&gt;Converting to &lt;code&gt;flake.nix&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;We’ll now convert this setup to use Nix flakes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-1-creating-flake-nix&quot;&gt;Step 1: Creating &lt;code&gt;flake.nix&lt;&#x2F;code&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Create a file named &lt;code&gt;flake.nix&lt;&#x2F;code&gt; in your project directory with the following content:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;{
  description = &amp;quot;A simple C program using jansson built with Nix flakes&amp;quot;;

  inputs = {
    nixpkgs.url = &amp;quot;github:NixOS&#x2F;nixpkgs&#x2F;nixpkgs-unstable&amp;quot;;
  };

  outputs = { self, nixpkgs }: {
    packages = nixpkgs.lib.genAttrs [ &amp;quot;aarch64-darwin&amp;quot; &amp;quot;x86_64-linux&amp;quot; ] (system:
    let
      pkgs = import nixpkgs { inherit system; };
    in
    rec {
      simple-parse-example = pkgs.stdenv.mkDerivation {
        pname = &amp;quot;simple-parse-example&amp;quot;;
        version = &amp;quot;1.0&amp;quot;;

        src = .&#x2F;.;

        nativeBuildInputs = [ pkgs.clang ];
        buildInputs = [ pkgs.jansson ];

        buildPhase = &amp;#39;&amp;#39;
          clang -g -Wall -o simple-parse-example simple-parse-example.c -ljansson
        &amp;#39;&amp;#39;;

        installPhase = &amp;#39;&amp;#39;
          mkdir -p $out&#x2F;bin
          cp simple-parse-example $out&#x2F;bin&#x2F;
        &amp;#39;&amp;#39;;

        meta = with pkgs.lib; {
          description = &amp;quot;A simple program using jansson&amp;quot;;
          license = licenses.mit;
          maintainers = [ maintainers.yourname ];
          platforms = platforms.unix;
        };
      };
    });

    defaultPackage = {
      aarch64-darwin = self.packages.aarch64-darwin.simple-parse-example;
      x86_64-linux = self.packages.x86_64-linux.simple-parse-example;
    };

    defaultApp = {
      forAllSystems = nixpkgs.lib.mapAttrs&amp;#39; (system: pkg: {
        inherit system;
        defaultApp = {
          type = &amp;quot;app&amp;quot;;
          program = &amp;quot;${pkg.simple-parse-example}&#x2F;bin&#x2F;simple-parse-example&amp;quot;;
        };
      }) self.packages;
    };
  };
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;breaking-down-the-flake-configuration&quot;&gt;Breaking Down the Flake Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;Let’s break down each component of the &lt;code&gt;flake.nix&lt;&#x2F;code&gt; file to understand what it does.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;1-description&quot;&gt;1. &lt;strong&gt;description&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;description = &amp;quot;A simple C program using jansson built with Nix flakes&amp;quot;;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This provides a brief description of the flake. It’s useful for documentation and understanding the purpose of the flake.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;2-inputs&quot;&gt;2. &lt;strong&gt;inputs&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;inputs = {
  nixpkgs.url = &amp;quot;github:NixOS&#x2F;nixpkgs&#x2F;nixpkgs-unstable&amp;quot;;
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;inputs&lt;&#x2F;code&gt; section defines dependencies for the flake. Here, we are specifying that we want to use the unstable branch of the Nixpkgs repository. This is where we’ll get our packages like &lt;code&gt;clang&lt;&#x2F;code&gt; and &lt;code&gt;jansson&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nixos.wiki&#x2F;wiki&#x2F;Nixpkgs&quot;&gt;Nixpkgs Input&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;3-outputs&quot;&gt;3. &lt;strong&gt;outputs&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;outputs = { self, nixpkgs }: {
  packages = nixpkgs.lib.genAttrs [ &amp;quot;aarch64-darwin&amp;quot; &amp;quot;x86_64-linux&amp;quot; ] (system:
  let
    pkgs = import nixpkgs { inherit system; };
  in
  rec {
    simple-parse-example = pkgs.stdenv.mkDerivation {
      pname = &amp;quot;simple-parse-example&amp;quot;;
      version = &amp;quot;1.0&amp;quot;;

      src = .&#x2F;.;

      nativeBuildInputs = [ pkgs.clang ];
      buildInputs = [ pkgs.jansson ];

      buildPhase = &amp;#39;&amp;#39;
        clang -g -Wall -o simple-parse-example simple-parse-example.c -ljansson
      &amp;#39;&amp;#39;;

      installPhase = &amp;#39;&amp;#39;
        mkdir -p $out&#x2F;bin
        cp simple-parse-example $out&#x2F;bin&#x2F;
      &amp;#39;&amp;#39;;

      meta = with pkgs.lib; {
        description = &amp;quot;A simple program using jansson&amp;quot;;
        license = licenses.mit;
        maintainers = [ maintainers.yourname ];
        platforms = platforms.unix;
      };
    };
  });

  defaultPackage = {
    aarch64-darwin = self.packages.aarch64-darwin.simple-parse-example;
    x86_64-linux = self.packages.x86_64-linux.simple-parse-example;
  };

  defaultApp = {
    forAllSystems = nixpkgs.lib.mapAttrs&amp;#39; (system: pkg: {
      inherit system;
      defaultApp = {
        type = &amp;quot;app&amp;quot;;
        program = &amp;quot;${pkg.simple-parse-example}&#x2F;bin&#x2F;simple-parse-example&amp;quot;;
      };
    }) self.packages;
  };
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;packages&lt;&#x2F;strong&gt;: This section uses &lt;code&gt;nixpkgs.lib.genAttrs&lt;&#x2F;code&gt; to define packages for multiple systems (&lt;code&gt;aarch64-darwin&lt;&#x2F;code&gt; and &lt;code&gt;x86_64-linux&lt;&#x2F;code&gt;). For each system, we import the appropriate version of &lt;code&gt;nixpkgs&lt;&#x2F;code&gt; and define a derivation for &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;defaultPackage&lt;&#x2F;strong&gt;: Specifies the default package for each system. This is used to tell Nix which package to build by default for the current system.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;defaultApp&lt;&#x2F;strong&gt;: Specifies the default application for each system using &lt;code&gt;mapAttrs&#x27;&lt;&#x2F;code&gt; to iterate over systems and create default apps.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Documentation&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nixos.org&#x2F;manual&#x2F;nixpkgs&#x2F;stable&#x2F;#sec-functions-lib-genAttrs&quot;&gt;genAttrs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nixos.org&#x2F;manual&#x2F;nixpkgs&#x2F;stable&#x2F;#chap-stdenv&quot;&gt;mkDerivation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;building-and-running-with-nix-flakes&quot;&gt;Building and Running with Nix Flakes&lt;&#x2F;h3&gt;
&lt;p&gt;To ensure that everything works as expected, follow these steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to your project directory&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;cd ~&#x2F;dev&#x2F;learning-c&#x2F;parsing-json
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Flakes&lt;&#x2F;strong&gt;:
Make sure flakes are enabled in your Nix configuration:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;echo &amp;quot;experimental-features = nix-command flakes&amp;quot; &amp;gt;&amp;gt; ~&#x2F;.config&#x2F;nix&#x2F;nix.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Build the project&lt;&#x2F;strong&gt;:
Build the project using:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;nix build .#simple-parse-example
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run the binary&lt;&#x2F;strong&gt;:
After building, you can run the binary with:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;.&#x2F;result&#x2F;bin&#x2F;simple-parse-example
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h3&gt;
&lt;p&gt;Congratulations! You&#x27;ve successfully updated your C project to use Nix flakes. This modern approach ensures your builds are reproducible and dependencies are well-managed. Nix flakes provide a powerful way to handle complex projects with ease, making your development process smoother and more efficient.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exercise-prompt&quot;&gt;Exercise Prompt&lt;&#x2F;h3&gt;
&lt;p&gt;Try converting another one of your existing projects to use Nix flakes. Start by writing a &lt;code&gt;flake.nix&lt;&#x2F;code&gt; file that includes all your dependencies and build instructions. Share your experience, any challenges you encountered, and how Nix flakes improved your build process.&lt;&#x2F;p&gt;
&lt;p&gt;Happy coding, and may your builds always be reproducible!&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Mastering C: Building a Project with Nix</title>
        <published>2024-06-14T00:00:00+00:00</published>
        <updated>2024-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://parkerjones.dev/posts/mastering-c-nix/"/>
        <id>https://parkerjones.dev/posts/mastering-c-nix/</id>
        <content type="html" xml:base="https://parkerjones.dev/posts/mastering-c-nix/">&lt;p&gt;Welcome, fellow C enthusiasts, to a whimsical journey through the world of library dependencies in C programming! This is the second post in the series &lt;a href=&quot;&#x2F;mastering-c&quot;&gt;&quot;Mastering C with Effective C&quot; series&lt;&#x2F;a&gt;!  Not at all suprising to me, I&#x27;ve yet to write anything at all from the book, and I&#x27;m still poking around with build systems.  I&#x27;ve been learning to use nix as a build system, and some things are becoming clear when learning C, which has no built in package manager...&lt;&#x2F;p&gt;
&lt;p&gt;Today, we will dive into the exciting realm of building C programs with external libraries, and we’ll showcase how to do it using Nix, a modern build system that promises reproducibility and simplicity. But don&#x27;t worry, we’ll also touch upon the classic Makefile approach for comparison. Let’s get started!&lt;&#x2F;p&gt;
&lt;p&gt;The code from this post can be found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;parallaxisjones&#x2F;c&#x2F;tree&#x2F;main&#x2F;parsing-json&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-challenge-of-library-dependencies-in-c&quot;&gt;The Challenge of Library Dependencies in C&lt;&#x2F;h2&gt;
&lt;p&gt;Before we embark on our adventure, let&#x27;s acknowledge the challenge: managing external libraries in C. While modern languages often come with robust package managers, C developers often find themselves navigating the rugged terrain of manual downloads and builds. But fear not! With the power of Nix, we can transform this daunting task into a delightful experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introducing-our-hero-the-simple-json-parsing-example&quot;&gt;Introducing Our Hero: The Simple JSON Parsing Example&lt;&#x2F;h2&gt;
&lt;p&gt;To illustrate our journey, we&#x27;ll create a C program called &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt;. This program will demonstrate basic JSON parsing using the &lt;code&gt;jansson&lt;&#x2F;code&gt; library. Here’s what it will do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Create a JSON object.&lt;&#x2F;li&gt;
&lt;li&gt;Serialize the JSON object to a string.&lt;&#x2F;li&gt;
&lt;li&gt;Parse a JSON string back into an object.&lt;&#x2F;li&gt;
&lt;li&gt;Print the values to prove we’ve successfully navigated the JSON landscape.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-c-program-simple-parse-example&quot;&gt;The C Program: &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Here’s our simple C program using the &lt;code&gt;jansson&lt;&#x2F;code&gt; library:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;&#x2F;&#x2F; simple-parse-example.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;jansson.h&amp;gt;

int main() {
    &#x2F;&#x2F; Creating a JSON object
    json_t *object = json_object();
    json_object_set_new(object, &amp;quot;name&amp;quot;, json_string(&amp;quot;Candlehopper&amp;quot;));
    json_object_set_new(object, &amp;quot;level&amp;quot;, json_integer(5));
    json_object_set_new(object, &amp;quot;score&amp;quot;, json_integer(12345));

    &#x2F;&#x2F; Serialize JSON object to string
    char *json_str = json_dumps(object, JSON_INDENT(2));
    if (!json_str) {
        fprintf(stderr, &amp;quot;Error serializing JSON object.\n&amp;quot;);
        return 1;
    }
    printf(&amp;quot;Serialized JSON:\n%s\n&amp;quot;, json_str);

    &#x2F;&#x2F; Free the serialized string
    free(json_str);

    &#x2F;&#x2F; JSON string to parse
    const char *json_input = &amp;quot;{\&amp;quot;name\&amp;quot;: \&amp;quot;Candlehopper\&amp;quot;, \&amp;quot;level\&amp;quot;: 5, \&amp;quot;score\&amp;quot;: 12345}&amp;quot;;

    &#x2F;&#x2F; Parse JSON string
    json_error_t error;
    json_t *parsed_object = json_loads(json_input, 0, &amp;amp;error);
    if (!parsed_object) {
        fprintf(stderr, &amp;quot;Error parsing JSON string: %s\n&amp;quot;, error.text);
        return 1;
    }

    &#x2F;&#x2F; Extract values
    json_t *name = json_object_get(parsed_object, &amp;quot;name&amp;quot;);
    json_t *level = json_object_get(parsed_object, &amp;quot;level&amp;quot;);
    json_t *score = json_object_get(parsed_object, &amp;quot;score&amp;quot;);

    if (json_is_string(name) &amp;amp;&amp;amp; json_is_integer(level) &amp;amp;&amp;amp; json_is_integer(score)) {
        printf(&amp;quot;Parsed JSON:\n&amp;quot;);
        printf(&amp;quot;name: %s\n&amp;quot;, json_string_value(name));
        printf(&amp;quot;level: %lld\n&amp;quot;, json_integer_value(level));
        printf(&amp;quot;score: %lld\n&amp;quot;, json_integer_value(score));
    } else {
        fprintf(stderr, &amp;quot;Error extracting values from JSON object.\n&amp;quot;);
        json_decref(parsed_object);
        return 1;
    }

    &#x2F;&#x2F; Decrement reference counts to free memory
    json_decref(object);
    json_decref(parsed_object);

    return 0;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;the-classic-approach-using-makefile&quot;&gt;The Classic Approach: Using Makefile&lt;&#x2F;h2&gt;
&lt;p&gt;First, let’s explore how to build this program using a Makefile. Here’s a simple Makefile to compile &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt; with the &lt;code&gt;jansson&lt;&#x2F;code&gt; library:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;makefile&quot;&gt;Makefile&lt;&#x2F;h3&gt;
&lt;pre&gt;&lt;code data-lang=&quot;makefile&quot;&gt;# the compiler to use
CC = clang

# compiler flags:
#  -g    adds debugging information to the executable file
#  -Wall turns on most, but not all, compiler warnings
CFLAGS  = -g -Wall
  
# files to link:
LFLAGS = -ljansson
  
# the names to use for both the target source files, and the output files:
TARGETS = simple-parse-example
  
all: $(TARGETS)
  
simple-parse-example: simple-parse-example.c
	$(CC) $(CFLAGS) -o simple-parse-example simple-parse-example.c $(LFLAGS)

clean:
	rm -f $(TARGETS)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To build the project:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;make
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To clean up the build files:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;make clean
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;pros-and-cons-of-the-makefile-approach&quot;&gt;Pros and Cons of the Makefile Approach&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simple and straightforward.&lt;&#x2F;li&gt;
&lt;li&gt;Easily integrates with various compilers and tools.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Manual management of dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;Non-reproducible builds.&lt;&#x2F;li&gt;
&lt;li&gt;Platform-specific issues.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-modern-approach-using-nix&quot;&gt;The Modern Approach: Using Nix&lt;&#x2F;h2&gt;
&lt;p&gt;Now, let&#x27;s switch gears and harness the power of Nix to build our project. Nix provides reproducibility and isolation, ensuring our builds are consistent across different environments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nix-setup&quot;&gt;Nix Setup&lt;&#x2F;h3&gt;
&lt;p&gt;Here’s how you can set up a &lt;code&gt;default.nix&lt;&#x2F;code&gt; file to build &lt;code&gt;simple-parse-example&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nix&quot;&gt;# default.nix
{ pkgs ? import &amp;lt;nixpkgs&amp;gt; {} }:

let
  jansson = pkgs.jansson;
in
pkgs.stdenv.mkDerivation {
  pname = &amp;quot;simple-parse-example&amp;quot;;
  version = &amp;quot;1.0&amp;quot;;

  src = .&#x2F;.;

  nativeBuildInputs = [ pkgs.clang ];
  buildInputs = [ jansson ];

  buildPhase = &amp;#39;&amp;#39;
    clang -g -Wall -o simple-parse-example simple-parse-example.c -ljansson
  &amp;#39;&amp;#39;;

  installPhase = &amp;#39;&amp;#39;
    mkdir -p $out&#x2F;bin
    cp simple-parse-example $out&#x2F;bin&#x2F;
  &amp;#39;&amp;#39;;

  meta = with pkgs.lib; {
    description = &amp;quot;A simple program using jansson&amp;quot;;
    license = licenses.mit;
    maintainers = [ maintainers.yourname ];
    platforms = platforms.unix;
  };
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;building-with-nix&quot;&gt;Building with Nix&lt;&#x2F;h3&gt;
&lt;p&gt;To build your project using Nix:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to your project directory&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;cd myproject
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Build the project&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;nix-build
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run the binary&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;.&#x2F;result&#x2F;bin&#x2F;simple-parse-example
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;pros-and-cons-of-the-nix-approach&quot;&gt;Pros and Cons of the Nix Approach&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reproducible builds.&lt;&#x2F;li&gt;
&lt;li&gt;Easy dependency management.&lt;&#x2F;li&gt;
&lt;li&gt;Environment isolation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Steeper learning curve.&lt;&#x2F;li&gt;
&lt;li&gt;Requires Nix installation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;exploring-other-build-tools&quot;&gt;Exploring Other Build Tools&lt;&#x2F;h2&gt;
&lt;p&gt;While Makefiles and Nix are fantastic tools, there are other build systems and package managers worth exploring:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CMake&lt;&#x2F;strong&gt;: A cross-platform build system that automates the configuration process. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cmake.org&#x2F;&quot;&gt;Learn more&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;vcpkg&lt;&#x2F;strong&gt;: A C&#x2F;C++ library manager from Microsoft. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microsoft&#x2F;vcpkg&quot;&gt;Learn more&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Conan&lt;&#x2F;strong&gt;: A decentralized package manager for C&#x2F;C++. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;conan.io&#x2F;&quot;&gt;Learn more&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;In this quirky adventure, we’ve explored the classic Makefile approach and the modern Nix approach to building a C program with external library dependencies. We’ve seen how Nix can bring reproducibility and ease of use to the table, making it a fantastic choice for C developers looking to streamline their build processes.&lt;&#x2F;p&gt;
&lt;!-- ### Exercise Prompt --&gt;
&lt;!----&gt;
&lt;!-- Try converting one of your existing C projects to use Nix for its build process. Start by writing a simple `default.nix` file that includes all your dependencies and build instructions. Share your experience and any challenges you encountered along the way. --&gt;
&lt;p&gt;Happy coding, and may your builds always be reproducible!&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blog Post Series: Mastering C with Effective C</title>
        <published>2024-06-14T00:00:00+00:00</published>
        <updated>2024-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://parkerjones.dev/posts/mastering-c/"/>
        <id>https://parkerjones.dev/posts/mastering-c/</id>
        <content type="html" xml:base="https://parkerjones.dev/posts/mastering-c/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Welcome to my blog series, &quot;Mastering C with Effective C&quot;! This series is dedicated to exploring the fundamental concepts and advanced techniques of the C programming language. Inspired by the book &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Effective-Introduction-Professional-Robert-Seacord&#x2F;dp&#x2F;1718501048&quot;&gt;Effective C&lt;&#x2F;a&gt; by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Robert_C._Seacord&quot;&gt;Robert C. Seacord&lt;&#x2F;a&gt;, each post will delve into different aspects of C as I work through this book and make an effort to write a blog post every day.&lt;&#x2F;p&gt;
&lt;p&gt;My ultimate goal is to become comfortable with the C programming language, but ultimately use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.guide&#x2F;&quot;&gt;Zig&lt;&#x2F;a&gt;.... but first we&#x27;re going to touch the stove. You have to get burned to understand why you need the safety and quality of life improvements.&lt;&#x2F;p&gt;
&lt;p&gt;For the past few years I&#x27;ve gone pretty hard learning and working every day in Rust. I began my Rust journey as a (primarily) Typescript and Javascript develper. I began my software engineer as a web developer writing PHP, JavaScript, Typescript, HTML,and CSS.&lt;&#x2F;p&gt;
&lt;p&gt;As a self taught developer, I&#x27;ve built my career on learning side quests, which I&#x27;ve always considered par for the course as a software engineer.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be working through examples and sharing the code from the series in the following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;parallaxisjones&#x2F;c&quot;&gt;Git Repo&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-to-expect&quot;&gt;What to Expect&lt;&#x2F;h2&gt;
&lt;p&gt;In this series, we&#x27;ll cover a wide range of topics, starting from the basics and gradually moving towards more advanced concepts. Here are some of the key areas we&#x27;ll explore:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Getting Started with C&lt;&#x2F;strong&gt;: Understanding the basic structure of a C program, setting up the development environment, and writing your first C program.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Data Types and Variables&lt;&#x2F;strong&gt;: Exploring different data types in C, how to declare and use variables, and the importance of understanding data representation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Control Structures&lt;&#x2F;strong&gt;: Learning about various control structures such as loops, conditional statements, and how to control the flow of your program.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Functions and Modular Programming&lt;&#x2F;strong&gt;: Understanding the role of functions in C, how to define and call them, and the benefits of modular programming.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Pointers and Memory Management&lt;&#x2F;strong&gt;: Delving into pointers, dynamic memory allocation, and techniques for effective memory management in C.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Advanced Topics&lt;&#x2F;strong&gt;: Covering topics such as file I&#x2F;O, multi-threading, and network programming.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Each post will include practical examples, exercises, and explanations to help solidify your understanding of the concepts.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;link-to-subsequent-posts&quot;&gt;Link to Subsequent Posts&lt;&#x2F;h4&gt;
&lt;p&gt;This section will be updated with links to each post in the series as they are published. Stay tuned for new content and be sure to check back regularly!&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Introduction to Makefiles&lt;&#x2F;strong&gt;: &lt;a href=&quot;&#x2F;mastering-c-makefiles&quot;&gt;Read Post&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Converting Makefile to a nix build&lt;&#x2F;strong&gt;: &lt;a href=&quot;&#x2F;mastering-c-nix&quot;&gt;Read Post&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Neovim Configuration for Writing C: [Coming Soon]&lt;&#x2F;li&gt;
&lt;li&gt;Data Types and Variables: [Coming Soon]&lt;&#x2F;li&gt;
&lt;li&gt;Control Structures: [Coming Soon]&lt;&#x2F;li&gt;
&lt;li&gt;Functions and Modular Programming: [Coming Soon]&lt;&#x2F;li&gt;
&lt;li&gt;Pointers and Memory Management: [Coming Soon]&lt;&#x2F;li&gt;
&lt;li&gt;Advanced Topics: [Coming Soon]&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;next-up-introduction-to-makefiles&quot;&gt;Next Up: Introduction to Makefiles&lt;&#x2F;h4&gt;
&lt;p&gt;In the next post, we&#x27;ll dive into the world of Makefiles. We&#x27;ll explore how to automate the build process, manage dependencies, and simplify your workflow using Makefiles. This will include practical examples and a step-by-step guide to creating your own Makefile for a C project.&lt;&#x2F;p&gt;
&lt;p&gt;Stay tuned and happy coding!&lt;&#x2F;p&gt;
</content>
    </entry>
</feed>
