<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2024-04-15T11:25:35+00:00</updated><id>/feed.xml</id><title type="html">PoissonC Blog</title><subtitle>Sharing my thoughts and experiences~</subtitle><entry><title type="html">How a C program works? Linking, static and dynamic library</title><link href="/cs/2024/04/01/libft.html" rel="alternate" type="text/html" title="How a C program works? Linking, static and dynamic library" /><published>2024-04-01T18:24:25+00:00</published><updated>2024-04-01T18:24:25+00:00</updated><id>/cs/2024/04/01/libft</id><content type="html" xml:base="/cs/2024/04/01/libft.html"><![CDATA[<h2 id="introduction">Introduction</h2>
<p>In the “How a C program works?” series, I am going to explain what is happening when we execute a C program. In this article, I will introduce the concepts of linking ,static and dynamic library. I assume the readers already know how to code in C. But don’t worry, if you know “Hello, World!” in C, that’s enough…I think.</p>

<p>In the whole series, I will use linux command line to illustrate the concept, so maybe you need the basic bash skills.</p>

<h2 id="what-is-linking">What is linking?</h2>

<h1 id="the-key-is-reusing">The Key is reusing</h1>

<p>In the case that we made a useful function, and we want to use it at many projects. We don’t want to copy the same code all the time. Even though we can use “#include” to simply copy a file before compilation, it takes time and resource to compile the code. So if we can reuse the compiled binary, the world will be more wonderful!</p>

<h1 id="how-to-reuse-the-compiled-files">How to reuse the compiled files?</h1>

<p>Here comes the “Object file”. You may see the files with .o extension sometimes; they are the binary files made by the compiler(such as clang, gcc).</p>

<p>We can make an object file by simpliy adding -c flag, you can see the explanation from help:</p>

<figure class="highlight"><pre><code class="language-r" data-lang="r"><span class="o">&gt;</span><span class="w"> </span><span class="n">gcc</span><span class="w"> </span><span class="o">--</span><span class="n">help</span><span class="w">
</span><span class="n">...</span><span class="w">
</span><span class="o">-</span><span class="n">c</span><span class="w">          </span><span class="n">Compile</span><span class="w"> </span><span class="n">and</span><span class="w"> </span><span class="n">assemble</span><span class="p">,</span><span class="w"> </span><span class="n">but</span><span class="w"> </span><span class="n">do</span><span class="w"> </span><span class="n">not</span><span class="w"> </span><span class="n">link.</span><span class="w">
</span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="o">&lt;</span><span class="n">file</span><span class="o">&gt;</span><span class="w">   </span><span class="n">Place</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="n">into</span><span class="w"> </span><span class="o">&lt;</span><span class="n">file</span><span class="o">&gt;</span><span class="n">.</span><span class="w">
</span><span class="n">...</span></code></pre></figure>

<p>If we don’t use -o flag to specify the name of the output file, the default name of the output file is <filename>.o, for example the binary made from "hello_world.c" is "hello_world.o".</filename></p>

<p>So the process of making an executable can be divided to 2 steps, building object files, and link them to generate the final executable file.</p>

<h1 id="lets-link-it">Let’s link it!</h1>

<p>The first C program that most people learn is to print a “Hello, World!” string, right?</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>But for illustration, let’s do some useless trick, we divide this code to 2 parts:</p>

<p>The first part we name it as “hello_world.c”, it will call “my_printf” instead of the printf in standard library:</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// hello_world.c</span>
<span class="kt">void</span>  <span class="nf">my_printf</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">);</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">my_printf</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>The second part we name it as “my_printf.c”, it defines the function “my_printf”:</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// my_printf.c</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span><span class="kt">void</span>  <span class="nf">my_printf</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"%s"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<p>We compile them by the following commands:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc <span class="nt">-c</span> my_printf.c
<span class="o">&gt;</span> gcc <span class="nt">-c</span> hello_world.c</code></pre></figure>

<p>These will generate “my_printf.o” and “hello_world.o”, and we call gcc again to build the executable by these 2 files:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc my_printf.o hello_world.o <span class="nt">-o</span> linking</code></pre></figure>

<p>This will build an executable named as “linking”, let’s execute it:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> ./linking
Hello, World!</code></pre></figure>

<p>I think you got the basic idea of linking, but this illustration is not enough to show you what linking is exactly. It can only shows how to reuse the binary without re-compilation.</p>

<p>Here I provide a easy way to understand what linking is:</p>

<p><code class="language-plaintext highlighter-rouge">Linking just simply "links" different binary files together to generate another binary file.</code></p>

<p>But this process is not simply about merging files; it’s fundamentally concerned with resolving and connecting references to functions, variables, and other resources between these files. By doing so, linking ensures that function calls and variable references across different modules are accurately matched and accessible in the final binary file.</p>

<p>I will explain it more in <a href="/preparing/index.html">How a C program works? The ELF file</a>.</p>

<h2 id="easy-begin-static-library">Easy begin, static library</h2>

<p>By the basic understanding of what linking is, we can simply explain the static library in one sentence:</p>

<p><code class="language-plaintext highlighter-rouge">The static library is just a group of object files that are put together.</code></p>

<p>But I am going to introduce you a useful tool, it’s call <code class="language-plaintext highlighter-rouge">ar</code>, with this command, you can build the static library with archived  index, helps the linker to find the target functions more quickly.</p>

<p>This will generate a static library named as “libmy_staticlib.a”:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> ar <span class="nt">-rcs</span> libmy_staticlib.a my_printf.o</code></pre></figure>

<p>And we use this static library to compile the program:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc hello_world.o libmy_staticlib.a <span class="nt">-o</span> staticLib</code></pre></figure>

<p>We can also execute it:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> ./staticLib
Hello, World!</code></pre></figure>

<h2 id="standard-library-dynamic">Standard library, dynamic?</h2>

<h1 id="dynamic-library">Dynamic library</h1>
<p>Besides static library, the other kind of library is called dynamic library. To distinguish them simply by their name, “dynamic” means the contents needed from the library are not copied into the target binary file while the “static” indicates the contents needed from the library will be copied directly into the target binary file.</p>

<p>I will provide a clear illustration to show what a dynamic library is.</p>

<p>Let’s take a look to the origin version of the “Hello, World!” code:</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>We are now calling a function that helps us to output the string, and to call this function, we add the “#include &lt;stdio.h&gt;” at the first line. This line will copy all the content inside stdio.h to the current file before being compiled. But if you try to read the stdio.h, you will find that there is no function definition in it.</p>

<h1 id="making-our-own-dynamic-library">Making our own dynamic library</h1>

<p>If there is no function definition in the header file, how do we know what the functions do?</p>

<p>Let’s make a little experiment. Compile the “my_printf.c” without flags, which means the compiler will compile, assemble and “link”:</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// hello_world.c</span>
<span class="kt">void</span>  <span class="nf">my_printf</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">);</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">my_printf</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>It outputs the following error message:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc my_printf.c
/usr/bin/ld: /tmp/ccmAg7qR.o: <span class="k">in function</span> <span class="sb">`</span>main<span class="s1">':
hello_world.c:(.text+0x13): undefined reference to `my_printf'</span>
collect2: error: ld returned 1 <span class="nb">exit </span>status</code></pre></figure>

<p>So this is what will happen when we try to build an executable file with an undefined function. Back to the previous example, why can we use the standard library without the function definition? Well, the answer is simple, beacuse the compiler knows the function.</p>

<p>Let’s make some efforts to make it work. First, compile our my_printf.c with -c and -fPIC flags.</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// my_printf.c</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span><span class="kt">void</span>  <span class="nf">my_printf</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">printf</span><span class="p">(</span><span class="s">"%s"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc <span class="nt">-c</span> <span class="nt">-fPIC</span> my_printf.c</code></pre></figure>

<p>And use gcc again with following line to build the dynamic library:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc my_printf.o <span class="nt">-shared</span> <span class="nt">-o</span> libmy_printf.so</code></pre></figure>

<p>Beware that do NOT put these 2 lines as 1 line command, it will just output a single object file with the name of “libmy_printf.so”, not really a “shared library”.</p>

<p>And then run this command to compile hello_world.c:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> gcc hello_world.c  <span class="nt">-L</span><span class="nb">.</span> <span class="nt">-lmy_printf</span> <span class="nt">-o</span> dynamicLib</code></pre></figure>

<p>Execute the dynamicLib:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> ./dynamicLib
./dynamicLib: error <span class="k">while </span>loading shared libraries: libmy_printf.so: cannot open shared object file: No such file or directory</code></pre></figure>

<p>If you see this error output, it means you did it right. The exectutable “dynamicLib” tried to find the shared library outside its content!</p>

<p>This is because the -L flag only finds the library during compilation, not to address the directory into the executable.</p>

<p>So we need to address where our shared library is before executing it:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> <span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>./ ./dynamicLib
Hello, World!</code></pre></figure>

<p>When we execute a program which uses “dynamic library”, it will try to find the binary file of the target library and load it into memory.</p>

<h1 id="let-me-explain-what-we-have-done-just-now">Let me explain what we have done just now:</h1>

<p>First we created an object file with -fPIC flag, this means we don’t assign the absolute memory address of the output compiled file. This ensures the consistency of the library (check: <a href="/preparing/index.html">How a C program works? The ELF file</a>).</p>

<p>And then, we use this object file to generate a shared library, create the executable with our hello_world.c and this generated library.</p>

<p>At the last step, We execute ./dynamicLib by assigning the library directory.</p>

<h1 id="one-last-thing-before-heading-to-conclusion">One last thing before heading to conclusion</h1>

<p>I want to proof that the content of dynamic library is not included in our executable. Although we already know the executable using dynamic libraries will find where the library is, it’s not obvious enough.</p>

<p>Let’s check the file size by using ll:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">&gt;</span> ll
...
<span class="nt">-rwxr-xr-x</span>  1 poissonc poissonc 16032 Apr  2 16:24 linking
<span class="nt">-rwxr-xr-x</span>  1 poissonc poissonc 16032 Apr  2 16:41 staticLib
<span class="nt">-rwxr-xr-x</span>  1 poissonc poissonc 15952 Apr  2 17:15 dynamicLib
...</code></pre></figure>

<p>Number 16032 and 15952 denote the size of the file. We can see that the size of “linking” and “staticLib” are the same, and “dynamicLib” is less than them!</p>

<p>So if we want to execute a program that uses any dynamic library, it needs its “dependency”, otherwise, there is no the function definition in it.</p>

<p>We also know that all the standard libraries are dynamic libraries since we don’t assign the library when we compile our program.</p>

<h2 id="conclusion">Conclusion</h2>

<p>If you are a gamer, now you understand why we need to install Microsoft Visual C++ Redistributable Package for some games, they are all dynamic library! (The extension of dynamic library in Windows is .dll)</p>

<p>In the next article, I will lead you to read through the details of an exectuble (ELF file), to give a further insight of what is happening when we execute a C program.</p>

<h1 id="see-more">See more:</h1>

<p><a href="/preparing/index.html">How a C program works? The ELF file</a></p>

<p><a href="/preparing/index.html">How a C program works? Virtual memory</a></p>]]></content><author><name></name></author><category term="cs" /><summary type="html"><![CDATA[Introduction In the “How a C program works?” series, I am going to explain what is happening when we execute a C program. In this article, I will introduce the concepts of linking ,static and dynamic library. I assume the readers already know how to code in C. But don’t worry, if you know “Hello, World!” in C, that’s enough…I think.]]></summary></entry><entry><title type="html">Welcome to Jekyll!</title><link href="/jekyll/update/2024/04/01/welcome-to-jekyll.html" rel="alternate" type="text/html" title="Welcome to Jekyll!" /><published>2024-04-01T14:52:25+00:00</published><updated>2024-04-01T14:52:25+00:00</updated><id>/jekyll/update/2024/04/01/welcome-to-jekyll</id><content type="html" xml:base="/jekyll/update/2024/04/01/welcome-to-jekyll.html"><![CDATA[<h1 id="well-i-keep-this-page-to-show-that-i-am-really-lazy-just-want-to-share-the-things-interesting-for-me-i-only-do-the-minimum-works-laziness-makes-new-technology-">Well, I keep this page to show that I am really lazy. Just want to share the things interesting for me. I only do the minimum works. Laziness makes new technology ^^</h1>

<p>You’ll find this post in your <code class="language-plaintext highlighter-rouge">_posts</code> directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run <code class="language-plaintext highlighter-rouge">jekyll serve</code>, which launches a web server and auto-regenerates your site when a file is updated.</p>

<p>Jekyll requires blog post files to be named according to the following format:</p>

<p><code class="language-plaintext highlighter-rouge">YEAR-MONTH-DAY-title.MARKUP</code></p>

<p>Where <code class="language-plaintext highlighter-rouge">YEAR</code> is a four-digit number, <code class="language-plaintext highlighter-rouge">MONTH</code> and <code class="language-plaintext highlighter-rouge">DAY</code> are both two-digit numbers, and <code class="language-plaintext highlighter-rouge">MARKUP</code> is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.</p>

<p>Jekyll also offers powerful support for code snippets:</p>

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">print_hi</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="s2">"Hi, </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="n">print_hi</span><span class="p">(</span><span class="s1">'Tom'</span><span class="p">)</span>
<span class="c1">#=&gt; prints 'Hi, Tom' to STDOUT.</span></code></pre></figure>

<p>Check out the <a href="https://jekyllrb.com/docs/home">Jekyll docs</a> for more info on how to get the most out of Jekyll. File all bugs/feature requests at <a href="https://github.com/jekyll/jekyll">Jekyll’s GitHub repo</a>. If you have questions, you can ask them on <a href="https://talk.jekyllrb.com/">Jekyll Talk</a>.</p>]]></content><author><name></name></author><category term="jekyll" /><category term="update" /><summary type="html"><![CDATA[Well, I keep this page to show that I am really lazy. Just want to share the things interesting for me. I only do the minimum works. Laziness makes new technology ^^]]></summary></entry></feed>