{"id":1502,"date":"2012-01-28T09:58:13","date_gmt":"2012-01-28T08:58:13","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=1502"},"modified":"2012-01-28T09:58:13","modified_gmt":"2012-01-28T08:58:13","slug":"development-of-a-dynamic-library-13","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2012\/01\/28\/development-of-a-dynamic-library-13\/","title":{"rendered":"Development of a dynamic library (1\/3)"},"content":{"rendered":"<p style=\"text-align: justify;\">(<a title=\"Mise au point de biblioth\u00e8que dynamique (1\/3)\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/01\/28\/mise-au-point-de-bibliotheque-dynamique-1-compilation-versions-et-liens-symboliques\/\">Version originale en fran\u00e7ais<\/a>)<\/p>\n<p style=\"text-align: justify;\">During a recent training session, a conversation with a participant gave me the idea to check the options needed to perform debugging and coverage tests on a shared library.<\/p>\n<p>\n<!--more-->\n<\/p>\n<p style=\"padding-left: 60px; text-align: justify;\">A dynamic library (<code>lib<em>XXXX<\/em>.so<\/code> file &#8211; \u00ab\u00a0<code>so<\/code>\u00a0\u00bb standing for <em>Shared Object<\/em>) is loaded into memory when the process starts. The executable file and the library file are independent before launching the application, and can be maintained separately.<\/p>\n<p style=\"text-align: justify;\">I realized that some points were far from obvious, such as managing version numbers or activating coverage tests. Here is a list of the steps needed for the development of a dynamic library. The first article is devoted to compilation, version control and symbolic links. The <a title=\"Development of a dynamic library (2\/3)\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/02\/04\/development-of-a-dynamic-library-23\/\" target=\"_blank\">second one<\/a> will focus on debugging and step-by-step tracing of the library code. The third will describe how to perform coverage tests on the library.<\/p>\n<h1>Compiling and installing the library<\/h1>\n<h2>Compiling library code<\/h2>\n<p style=\"text-align: justify;\">Let&rsquo;s start by creating a small dynamic library, with a simple function: the implementation of the mathematical \u00ab\u00a0factorial\u00a0\u00bb.<\/p>\n<p style=\"text-align: justify;\">I create a working directory named <code>factorial<\/code> including all the files. Then we make three sub-directories:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><code>src\/<\/code> containing the source code of the library,<\/li>\n<li style=\"text-align: justify;\"><code>lib\/<\/code> where stand binary files and symbolic links described below,<\/li>\n<li style=\"text-align: justify;\"><code>include\/<\/code> storing the header files of the library.<\/li>\n<\/ul>\n<pre>[~]$ <strong>mkdir factorial<\/strong>\n[~]$ <strong>mkdir factorial\/src<\/strong>\n[~]$ <strong>mkdir factorial\/include<\/strong>\n[~]$ <strong>mkdir factorial\/lib<\/strong>\n[~]$ <strong>cd factorial<\/strong>\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">Let&rsquo;s create a file named <a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact.c\" target=\"_blank\"><code>src\/fact.c<\/code><\/a> containing our function.<\/p>\n<p style=\"text-align: justify; padding-left: 60px;\">And if you think you have found a bug in the code below, be kind and read the entire article before sending me a mocking mail \ud83d\ude09<\/p>\n<pre>#include &lt;fact.h&gt;\n\nlong long int factorial(long int n)\n{\n        long long int f = 1;\n        do {\n                f = f * n;\n                n = n - 1;\n        } while (n &gt; 1);\n        return f;\n}<\/pre>\n<p style=\"text-align: justify;\">This file includes its own header, which ensures consistency of the prototype and implementation.<\/p>\n<p style=\"text-align: justify;\">The file <a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact.h\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact.h\" target=\"_blank\"><code>include\/fact.h<\/code><\/a> contains the following lines.<\/p>\n<pre>#ifndef LIB_FACT_H\n#define LIB_FACT_H\n    long long int factorial(long int n);\n#endif<\/pre>\n<p style=\"text-align: justify;\">When compiling this file we will provide the following options on the <code>gcc<\/code> command line:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><code>-c<\/code> to tell <code>gcc<\/code> to stop his job after the compilation phase and thus providing an object file (not linking).<\/li>\n<li style=\"text-align: justify;\"><code>-I include\/<\/code> telling <code>gcc<\/code> to look for <code>.h<\/code> header files in the <code>include\/<\/code> directory in addition to the usual directories (<code>\/usr\/include<\/code>\u2026).<\/li>\n<li style=\"text-align: justify;\"><code>-fPIC<\/code> to request the generation of a relocatable code (PIC stands for <em>Position Independent Code<\/em>). It is necessary for the creation of shared libraries even if this option has no effect on some architectures (x86 32-bit for example).<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Here is an example of compilation:<\/p>\n<pre>[factorial]$ <strong>ls src\/<\/strong>\nfact.c\n[factorial]$ <strong>ls include\/<\/strong>\nfact.h\n[factorial]$ <strong>gcc -c -I include\/ -fPIC -Wall -o src\/fact.o src\/fact.c<\/strong>\n[factorial]$ <strong>ls src\/<\/strong>\nfact.c fact.o\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">The generated <code>fact.o<\/code> object file will be used below.<\/p>\n<p style=\"text-align: justify;\">Note that during the development and testing phase, we do not use any optimization option, otherwise the compiler may change the executable code created and there won&rsquo;t be an exact matching with the source file.<\/p>\n<h2>Generation of the library<\/h2>\n<p style=\"text-align: justify;\">The library itself is created by invoking <code>gcc<\/code> with the <code>-shared<\/code> option. We ask him to save the library in the <code>libfact.so.1.0<\/code> file. The numbers 1 and 0 correspond respectively to the major and minor numbers of the library version.<\/p>\n<p style=\"text-align: justify;\">It is customary to consider that a major number change represents a break in binary compatibility of the library and requires recompilation of applications, while a variation of the minor number represents only internal corrections or improvements that do not interfere with the programming interface.<\/p>\n<p style=\"text-align: justify;\">We will tell <code>gcc<\/code> with the <code>-Wl<\/code> option to record in the heade rof the library its official name of the library including the major version number. It passes to the linker the string that follows the <code>-Wl<\/code> option after replacing commas by spaces. Thus the linker gets the <code>-soname libfact.so.1<\/code> string.<\/p>\n<p style=\"text-align: justify;\">It is recommanded to repeat the options passed in the previous compilation, such as <code>-fPIC<\/code>.<\/p>\n<pre>[factorial]$ <strong>gcc -fPIC -shared -Wl,-soname,libfact.so.1 -o lib\/libfact.so.1.0 src\/fact.o<\/strong>\n[factorial]$ <strong>ls lib\/<\/strong>\nlibfact.so.1.0\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">So we get the <code>libfact.so.1.0<\/code> file, whose header contains the <code>libfact.so.1<\/code> name.<\/p>\n<h2>Creating symbolic links<\/h2>\n<p style=\"text-align: justify;\">When we compile an application, we tell <code>gcc<\/code> to link it with the <code>fact<\/code> library. He looks for a file named <code>libfact.so<\/code>, not <code>libfact.so.1.0<\/code>. So we have to create a symbolic link named <code>libfact.so<\/code> pointing to the real library file. This link is created manually using the <code>ln<\/code> command.<\/p>\n<pre>[factorial]$ <strong>cd lib\/<\/strong>\n[lib]$ <strong>ln -sf libfact.so.1.0 libfact.so<\/strong>\n[lib]$ <strong>ls -l lib*<\/strong>\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:04 libfact.so -&gt; libfact.so.1.0\n-rwxrwxr-x 1 cpb cpb 6659 2012-01-27 10:02 libfact.so.1.0\n[lib]$<\/pre>\n<p style=\"text-align: justify;\">During compilation <code>gcc<\/code> records the name of the library he used into the executable. This is the \u00ab\u00a0official\u00a0\u00bb name found in the <code>SONAME<\/code> section we filled previously with the <code>-Wl,-soname<\/code> option.<\/p>\n<p style=\"text-align: justify;\">At runtime, the loader searches the library which major number matches those used during compilation. So he has to find a file named <code>libfact.so.1<\/code>, or rather a symbolic link named <code>libfact.so.1<\/code> pointing to <code>libfact.so.1.0<\/code>.<\/p>\n<p style=\"text-align: justify;\">The creation of the first symbolic link was needed to compile an application with the library, the second link is essential to run a program associated with it. This link is used much more frequently than the first one. To make the life of the administrator easier, a command named <code>ldconfig<\/code> will help to automatically create the links needed to allow users to run applications. It searches the directories containing system libraries (<code>\/lib<\/code>, <code>\/usr\/lib<\/code>, <code>\/usr\/local\/lib<\/code>, etc&#8230; and all given in <code>\/etc\/ld.so.conf<\/code>) and creates links on each library file with the name contained in the <code>section<\/code>. Let&rsquo;s see an example where I force <code>ldconfig<\/code> through its <code>-n<\/code> option to explore only our <code>lib\/<\/code> directory.<\/p>\n<pre>[lib]$ <strong>ldconfig -n .<\/strong>\n[lib]$ <strong>ls -l lib*<\/strong>\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:04 libfact.so -&gt; libfact.so.1.0\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:05 libfact.so.1 -&gt; libfact.so.1.0\n-rwxrwxr-x 1 cpb cpb 6659 2012-01-27 10:02 libfact.so.1.0\n[lib]$<\/pre>\n<p style=\"text-align: justify;\">The links will allow us to compile an application that requires our library (through <code>libfact.so<\/code>) and then run it by making sure the major version is the right one (with <code>libfact.so.1<\/code>).<\/p>\n<h1>Using the library<\/h1>\n<h2>Compiling an application<\/h2>\n<p style=\"text-align: justify;\">Let&rsquo;s write a small program that uses our library. The <code><a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/factorial.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/factorial.c\" target=\"_blank\">factorial.c<\/a><\/code> file will call our <code>factorial()<\/code> function for all the numbers found on the command line.<\/p>\n<pre>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;fact.h&gt;\n\nint main (int argc, char * argv[])\n{\n        long int n;\n        int i;\n        if (argc &lt; 2) {\n                fprintf(stderr, \"usage: %s value...n\", argv[0]);\n                exit(EXIT_FAILURE);\n        }\n        for (i = 1; i &lt; argc; i ++)\n                if (sscanf(argv[i], \"%ld\", &amp; n) == 1)\n                        fprintf(stdout, \"%ld! = %lldn\", n, factorial(n));\n        return EXIT_SUCCESS;\n}<\/pre>\n<p style=\"text-align: justify;\">This file is located in the <code>factorial\/test\/<\/code> directory that we create now. It includes the <code>&lt;fact.h&gt;<\/code> header file. So the compiler has to find this header file. Two solutions:<\/p>\n<ul>\n<li style=\"text-align: justify;\">Put the header file in <code>\/usr\/include<\/code>, <code>\/usr\/local\/include<\/code> or any other directory where <code>gcc<\/code> searches. This should be reserved for critical files, needed by several applications and useful for the entire system.<\/li>\n<li style=\"text-align: justify;\">Keep the file in an application specific directory and tell <code>gcc<\/code> where to find it.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">I will obviously choose the second one.<\/p>\n<p style=\"text-align: justify;\">In addition, we will put the <code>-lfact<\/code> option at the end of the command line, asking the <em>linker<\/em> to perform the linking with the <code>libfact.so<\/code> library. As for the header file, <code>gcc<\/code> must be told where he can find the <code>libfact.so<\/code> file we created previously as symbolic link. It is the role of the <code>-L<\/code> option.<\/p>\n<pre>[factorial]$ <strong>gcc -I .\/include\/ -L .\/lib\/ -o .\/test\/factorial .\/test\/factorial.c -lfact<\/strong>\n[factorial]$ <strong><\/strong>\n[factorial]$ <strong>ls -l test\/<\/strong>\ntotal 12\n-rwxrwxr-x 1 cpb cpb 7359 2012-01-27 10:41 factorial\n-rw-r--r-- 1 cpb cpb  382 2012-01-25 18:29 factorial.c\n[factorielle]$<\/pre>\n<h2>Running the application<\/h2>\n<p style=\"text-align: justify;\">If we run our program directly, the execution fails.<\/p>\n<pre>$ <strong>.\/test\/factorial 4 5 6<\/strong>\n.\/test\/factorial: error while loading shared libraries: libfact.so.1: cannot open shared object file: No such file or directory\n$<\/pre>\n<p style=\"text-align: justify;\">Indeed, the dynamic linker which should start the process does not know where to find the library. We can see that it searches for the <code>libfact.so.1<\/code> file (with the major number as extension). If our application is important enough to be used regularly by different users, it is legitimate to place library files in <code>\/usr\/local\/lib<\/code> where the loader will find them. However if the application is currently under development or reserved for personnal use, it is preferable to leave the library in a sub-directory of our home directory. In this case, we must be fill (possibly in a startup script) the environment variable <code>LD_LIBRARY_PATH<\/code> to add the path to the library file.<\/p>\n<pre>[factorial]$ <strong>export LD_LIBRARY_PATH=.\/lib\/ <\/strong>\n[factorial]$ <strong>.\/test\/factorial 4 5 6<\/strong>\n4! = 24\n5! = 120\n6! = 720\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">Of course, the <code>LD_LIBRARY_PATH<\/code> variable can be given an absolute path rather than a relative one if you want to lauch the application from any location of the filesystem tree.<\/p>\n<div id=\"attachment_1526\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-1-en.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1526\" class=\"size-medium wp-image-1526\" title=\"Dynamic library v. 1.0\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-1-en-300x188.png\" alt=\"Dynamic library v. 1.0\" width=\"300\" height=\"188\" \/><\/a><p id=\"caption-attachment-1526\" class=\"wp-caption-text\">Dynamic library v. 1.0<\/p><\/div>\n<h1>Maintaining the library<\/h1>\n<h2>Minor version update<\/h2>\n<p style=\"text-align: justify;\">Our library seems to works, let&rsquo;s engage intensive testings:<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial 3<\/strong>\n3! = 6\n[factorial]$<\/pre>\n<p style=\"padding-left: 60px;\">Very good!<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial 2<\/strong>\n2! = 2\n[factorial]$<\/pre>\n<p style=\"padding-left: 60px;\">Perfect!<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial 1<\/strong>\n1! = 1\n[factorial]$<\/pre>\n<p style=\"padding-left: 60px;\">No problem.<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial 0<\/strong>\n0! = 0\n[factorial]$<\/pre>\n<p style=\"padding-left: 60px;\">Ouch!<\/p>\n<p style=\"text-align: justify;\">By convention, it is hypothesized that <code>0! = 1<\/code> (you can <a title=\"http:\/\/en.wikipedia.org\/wiki\/Factorial\" href=\"http:\/\/en.wikipedia.org\/wiki\/Factorial\" target=\"_blank\">check on Wikipedia<\/a> if you wish). Our program is defective. The correction is fairly simple, just replace the loop<\/p>\n<pre>        do {\n                f = f * n;\n                n = n - 1;\n        } while (n &gt; 1);<\/pre>\n<p>by<\/p>\n<pre>        while (n &gt; 1) {\n                f = f * n;\n                n = n - 1;\n        }<\/pre>\n<p style=\"text-align: justify;\">That&rsquo;s what I did in <code><a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact-2.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/en\/article-2012-01-28\/fact-2.c\" target=\"_blank\">fact-2.c<\/a><\/code> file. Theoretically I should keep the same source file and replace it in the new version of the library. I wanted to keep the previous version here for demonstration purposes so did I rename the file.<\/p>\n<p style=\"text-align: justify;\">I will compile and generate a new library version incrementing the minor number. The interface of the <code>factorial()<\/code> function is not changed, executable files that depend on the library will continue to operate normally.<\/p>\n<pre>[factorial]$ <strong>gcc -c -I include\/ -fPIC -Wall -o src\/fact.o src\/fact-2.c<\/strong>\n[factorial]$ <strong>gcc -fPIC -shared -Wl,-soname,libfact.so.1 -o lib\/libfact.so.1.1 src\/fact.o<\/strong><\/pre>\n<p style=\"text-align: justify;\">Our library has been re-created with a new file name, so it&rsquo;s necessary to rerun the <code>ldconfig<\/code> command.<\/p>\n<pre>[factorial]$ <strong>ldconfig -n lib\/<\/strong>\n[factorial]$ <strong>ls -l lib\/<\/strong>\ntotal 16\nlrwxrwxrwx 1 cpb cpb   12 2012-01-27 10:04 libfact.so -&gt; libfact.so.1\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:11 libfact.so.1 -&gt; libfact.so.1.1\n-rwxrwxr-x 1 cpb cpb 6659 2012-01-27 10:02 libfact.so.1.0\n-rwxrwxr-x 1 cpb cpb 6661 2012-01-27 10:10 libfact.so.1.1\n[factorial]$\n[factorial]$ <strong>.\/test\/factorial 0 1 2<\/strong>\n0! = 1\n1! = 1\n2! = 2\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">Our code works correctly for <code>0!<\/code>. The previous version of the library is no more used, so we can delete it<\/p>\n<pre>[factorial]$ <strong>rm -f lib\/libfact.so.1.0 <\/strong>\n[factorial]$<\/pre>\n<div id=\"attachment_1528\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-2-en.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1528\" class=\"size-medium wp-image-1528\" title=\"Dynamic library v. 1.1\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-2-en-300x188.png\" alt=\"Dynamic library v. 1.1\" width=\"300\" height=\"188\" \/><\/a><p id=\"caption-attachment-1528\" class=\"wp-caption-text\">Dynamic library v. 1.1<\/p><\/div>\n<h2>Major version update<\/h2>\n<p style=\"text-align: justify;\">After a few tests, we are facing a new problem with our library.<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial -3<\/strong>\n-3! = 1\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">Our function returns a value when given a negative number. in mathematics, the factorial is only defined for natural numbers, not for negative integers. The function should report the argument error and not return a value (coherent but misleading).<\/p>\n<p style=\"text-align: justify;\">We choose to modify the interface of our routine, which will take as argument a pointer to a <code>long long<\/code> integer where it will store the result and return a success (zero) or failure (-1) value. This change will involve an interface adaptation and recompilation of the applications using the library. So must we change the major version.<\/p>\n<p>The new function in <a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact-3.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact-3.c\" target=\"_blank\"><code>fact-3.c<\/code><\/a> is implemented as follow:<\/p>\n<pre>int factorial(long int n, long long int * result)\n{\n        * result = 1;\n        if (n &lt; 0)\n                return -1;\n         do {\n                 (*result) = (*result) * n;\n                 n = n - 1;\n         } while (n &gt; 1);\n        return 0;\n}<\/pre>\n<p>Of course, we change the header file (<a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact-3.h\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/fact-3.h\" target=\"_blank\"><code>fact-3.h<\/code><\/a>):<\/p>\n<pre>#ifndef LIB_FACT_H\n#define LIB_FACT_H\n        int factorial(long int n, long long int * result);\n#endif<\/pre>\n<p style=\"text-align: justify;\">We compile our library as we did before:<\/p>\n<pre>[factorial]$ <strong>gcc -c -I include\/ -fPIC -Wall -o src\/fact.o src\/fact-3.c<\/strong>\n[factorial]$ <strong>gcc -fPIC -shared -Wl,-soname,libfact.so.2 -o lib\/libfact.so.2.0 src\/fact.o<\/strong>\n[factorial]$ <strong>ldconfig -n lib\/<\/strong>\n[factorial]$ <strong>ls -l lib\/<\/strong>\ntotal 16\nlrwxrwxrwx 1 cpb cpb   12 2012-01-27 10:04 libfact.so -&gt; libfact.so.1\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:11 libfact.so.1 -&gt; libfact.so.1.1\n-rwxrwxr-x 1 cpb cpb 6661 2012-01-27 10:10 libfact.so.1.1\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:26 libfact.so.2 -&gt; libfact.so.2.0\n-rwxrwxr-x 1 cpb cpb 6661 2012-01-27 10:26 libfact.so.2.0\n[factorial]$ <strong>cd lib\/<\/strong>\n[lib]$ <strong>ln -sf libfact.so.2 libfact.so<\/strong>\n[lib]$ <strong>ls -l<\/strong>\ntotal 16\nlrwxrwxrwx 1 cpb cpb   12 2012-01-27 10:27 libfact.so -&gt; libfact.so.2\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:11 libfact.so.1 -&gt; libfact.so.1.1\n-rwxrwxr-x 1 cpb cpb 6661 2012-01-27 10:10 libfact.so.1.1\nlrwxrwxrwx 1 cpb cpb   14 2012-01-27 10:26 libfact.so.2 -&gt; libfact.so.2.0\n-rwxrwxr-x 1 cpb cpb 6661 2012-01-27 10:26 libfact.so.2.0\n[lib]$ <strong>cd ..<\/strong>\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">The links are in place to compile a new version of the test program (<a title=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/factorial-2.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-01-28\/en\/factorial-2.c\" target=\"_blank\"><code style=\"text-align: justify;\">factorial-2.c<\/code><\/a>).<\/p>\n<pre>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;fact.h&gt;\n\nint main (int argc, char * argv[])\n{\n        long int n;\n        long long int f;\n        int i;\n        if (argc &lt; 2) {\n                fprintf(stderr, \"usage: %s value...n\", argv[0]);\n                exit(EXIT_FAILURE);\n        }\n        for (i = 1; i &lt; argc; i ++)\n                if (sscanf(argv[i], \"%ld\", &amp; n) == 1) {\n                        if (factoriel(n, &amp; f) == 0)\n                                fprintf(stdout, \"%ld! = %lldn\", n, f);\n                        else\n                                fprintf(stdout, \"%ld! doesn't existn\", n);\n                }\n        return EXIT_SUCCESS;\n}<\/pre>\n<p style=\"text-align: justify;\">Let us compile and try it:<\/p>\n<pre>[factorial]$ <strong>gcc -I .\/include\/ -L .\/lib\/ -o .\/test\/factorial-2 .\/test\/factorial-2.c -lfact<\/strong>\n[factorial]$ <strong>.\/test\/factorial-2 3 0 -3<\/strong>\n3! = 6\n0! = 0\n-3! doesn't exist\n[factorial]$<\/pre>\n<p style=\"text-align: justify;\">This time our application behaves correctly. We can remark that the presence of the former major release enables our previous executable to continue operating.<\/p>\n<pre>[factorial]$ <strong>.\/test\/factorial 3 0 -3<\/strong>\n3! = 6\n0! = 1\n-3! = 1\n[factorial]$<\/pre>\n<div id=\"attachment_1529\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-3-en.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1529\" class=\"size-medium wp-image-1529\" title=\"Dynamic library v. 2.0\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/01\/figure-3-en-300x188.png\" alt=\"Dynamic library v. 2.0\" width=\"300\" height=\"188\" \/><\/a><p id=\"caption-attachment-1529\" class=\"wp-caption-text\">Dynamic library v. 2.0<\/p><\/div>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">The management of major and minor numbers of dynamic library versions offers the following advantages:<\/p>\n<ul>\n<li style=\"text-align: justify;\">The internal only modifications, represented by changes in the minor number, allow already compiled executables to run directly with the new version of the library and enjoy &#8211; without recompilation &#8211; the latest improvements.<\/li>\n<li style=\"text-align: justify;\">Changes in the external interface of the library require a recompilation (possibly after adaptation) of the application.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Several major versions of the same library can coexist simultaneously for proper operation of different generations of an application. However, the compiler uses the new major version pointed to by the main symbolic link of the library (libfact.so)<\/p>\n<p style=\"text-align: justify;\">We will see in the <a title=\"Mise au point de biblioth\u00e8que dynamique (2\/3)\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/02\/04\/mise-au-point-de-bibliotheque-dynamique-23\/\" target=\"_blank\">next article<\/a> how to debug the code in the dynamic library, tracing it with step-by-step execution and examining the contents of its variables.<\/p>","protected":false},"excerpt":{"rendered":"<p>(Version originale en fran&ccedil;ais) During a recent training session, a conversation with a participant gave me the idea to check the options needed to perform debugging and coverage tests on a shared library.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-1502","post","type-post","status-publish","format-standard","hentry","category-linux-2"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/1502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=1502"}],"version-history":[{"count":0,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/1502\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=1502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=1502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=1502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}