gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 73704d2: Library's linking and summary section


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 73704d2: Library's linking and summary sections added
Date: Thu, 15 Sep 2016 14:06:44 +0000 (UTC)

branch: master
commit 73704d20d2111b4180659da328549ef2dec92828
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Library's linking and summary sections added
    
    A first draft of the Library chapter's linking and summary sections are now
    written in the book. The header's section was also edited and updated to
    blend in better.
---
 doc/gnuastro.texi |  584 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 446 insertions(+), 138 deletions(-)

diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index f6f31cd..79c33c6 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -502,6 +502,7 @@ Review of library fundamentals
 
 * Headers::                     Header files included in source.
 * Linking::                     Linking the compiled source files into one.
+* Summary and small example::   Short summary and a building instructions.
 
 Developing
 
@@ -14055,7 +14056,7 @@ the outside world. This gives you the chance to write 
your own @code{main}
 function and call library functions from within it. After compiling your
 program into a binary executable, you just have to @emph{link} it to the
 library and you are ready to run (execute) your program. In this way, you
-can use Gnuastro at a much lower-level and in combination with other
+can use Gnuastro at a much lower-level, and in combination with other
 libraries on your system, you can significantly boost your creativity.
 
 This chapter starts with a basic introduction to libraries and how you can
@@ -14080,18 +14081,37 @@ provided with Gnuastro to easily add a new utility.
 Gnuastro's libraries are written in the C programming language. In @ref{Why
 C}, we have thoroughly discussed the reasons behind this choice. C was
 actually created to write Unix. Therefore understanding the way C works can
-greatly help in effectively using of programs and libraries. Unfortunately
-most documentation on these important aspects are too technical. So for the
-readers that are not yet fully familiar with this, in the following
-subsections we will give a brief review of some important aspects of C that
-can help your use of the libraries and understand the confusing errors you
-get when trying to install programs that depend on other libraries. If you
-are already familiar with these concepts, please skip this section and go
-directly to @ref{Gnuastro library} for the function details.
+greatly help in effectively using of programs and libraries in all
+Unix-like operating systems. Unfortunately most documentation on these
+important aspects are too technical for a beginner. So for the readers that
+are not yet fully familiar with this, in the following subsections we will
+give a brief review of some important aspects of C that can help your use
+of the libraries and understand the confusing errors you get when trying to
+install programs that depend on other libraries. First we will discuss
+header files in @ref{Headers} and then go onto @ref{Linking}. If you are
+already familiar with these concepts, please skip this section and go
+directly to @ref{Gnuastro library}.
+
address@hidden Modularity
+In theory, a full operating system (or any software) can be written as one
+function. Such a software would not need any headers or linking (that are
+discussed in the subsections below). However, writing that single function
+and maintaining it (adding new features, fixing bugs, documentation and
+etc) would be a programmer or scientist's worst nightmare! Futhermore, all
+the hard work that went into creating it cannot be reused in other
+software: every programmer or scientist would have to re-invent the
+wheel. The ultimate purpose behind libraries (which come with headers and
+have to be linked) is to address this problem and increase modularity:
+``the degree to which a system's components may be separated and
+recombined'' (from Wikipedia). The more modular the source code of a
+program or library, the easier maintaining it will be, and all the hard
+work that went into creating it can be reused by others for a wider range
+of problems.
 
 @menu
 * Headers::                     Header files included in source.
 * Linking::                     Linking the compiled source files into one.
+* Summary and small example::   Short summary and a building instructions.
 @end menu
 
 @node Headers, Linking, Review of library fundamentals, Review of library 
fundamentals
@@ -14101,155 +14121,443 @@ directly to @ref{Gnuastro library} for the function 
details.
 C source code is read from top to bottom in the source file, therefore
 program components (for example variables, data structures and functions)
 should all be @emph{defined} or @emph{declared} closer to the top of the
-source file (before they are used). @emph{Defining} something in C or C++
-is jargon for providing its full details. @emph{Declaraing} it, on the
+source file: before they are used. @emph{Defining} something in C or C++ is
+jargon for providing its full details. @emph{Declaraing} it, on the
 other-hand, is jargon for only providing the minimum information needed for
 the compiler to pass it temporarily and fill in the detailed definition
 later.
 
-As an example, for a function, the @emph{declaration} only contains the
-inputs and their data-types along with the output's address@hidden
-that in C, functions only have one output.}. The @emph{definition} adds to
-the declaration by including the exact details of what operations are done
-to the inputs to generate the output. You can think of the declaration as a
-building's address in the city, and the definition as the building's
-complete blueprints. When the compiler confronts a function during its
-processing, it doesn't need to know anything about how the inputs are
-processed to generate the output, the declaration (the address) is
+For a function, the @emph{declaration} only contains the inputs and their
+data-types along with the output's address@hidden that in C,
+functions only have one output.}. The @emph{definition} adds to the
+declaration by including the exact details of what operations are done to
+the inputs to generate the output. As an example, take this simple
+summation function:
+
address@hidden
+double
+sum(double a, double b)
address@hidden
+  return a + b;
address@hidden
address@hidden example
address@hidden
+What you see above is the @emph{definition} of this function: it shows you
+(and the compiler) exactly what it does to the two @code{double} type
+inputs and that the output also has a @code{double} type. Note that a
+function's internal operations are rarely so simple and short, it can be
+arbitrarily long and complicated. The declaration for this function is:
+
address@hidden
+double
+sum(double a, double b);
address@hidden example
+
address@hidden
+You can think of a function's declaration as a building's address in the
+city, and the definition as the building's complete blueprints. When the
+compiler confronts a call to a function during its processing, it doesn't
+need to know anything about how the inputs are processed to generate the
+output. Just as the postman doesn't need to know the inner structure of a
+building when delivering the mail. The declaration (address) is
 enough. Therefore by @emph{declaring} the functions once at the start of
 the source files, we don't have to worry about @emph{defining} them after
 they are used.
 
-Function definitions can become very long and managing all the necessary
-functions in one file is any programmer's nightmare. Therefore, as we will
-see later (in @ref{Linking}), the functions don't necessarily need to be
-defined in the source file where they are used. As long as their
-definitions are ultimately linked to the final executable, everything will
-be fine. For now, it is just important to remember that the functions that
-are called within one source file have to be declared within the source
-file (declarations are mandatory), but not necessarily defined there.
-
address@hidden Modularity
-The ultimate purpose of all the above is modularity, or ``the degree to
-which a system's components may be separated and recombined'' (from
-Wikipedia). The more modular the source code of a program or library, the
-more all the hard work that went into creating it can be reused by others
-for a wider range of problems. So in the design of libraries and programs,
-it is common to define contextually similar functions in one source
-file. For example, in Gnuastro, functions that calculate the median, mean
-and other statistical functions are defined in @file{lib/statistics.c},
-while functions that deal directly with FITS files are defined in
address@hidden/fits.c}.
+Even for a simple real-world operation (not a simple summation like
+above!), you will soon need many functions (for example, some for
+reading/preparing the inputs, some for the processing, and some for
+preparing the output). Although it is technically possible, managing all
+the necessary functions in one file is not easy and is contrary to the
+modularity principle (see @ref{Review of library fundamentals}), for
+example the functions for preparing the input can be usable in your other
+projects with a different processing. Therefore, as we will see later (in
address@hidden), the functions don't necessarily need to be defined in the
+source file where they are used. As long as their definitions are
+ultimately linked to the final executable, everything will be fine. For
+now, it is just important to remember that the functions that are called
+within one source file must be declared within the source file
+(declarations are mandatory), but not necessarily defined there.
+
+In the spirit of modularity, it is common to define contextually similar
+functions in one source file. For example, in Gnuastro, functions that
+calculate the median, mean and other statistical functions are defined in
address@hidden/statistics.c}, while functions that deal directly with FITS files
+are defined in @file{lib/fits.c}.
 
 Keeping the definition of similar functions in a separate file greatly
-helps their management and modularity, but it doesn't make things much
-easier for the caller's source code: recall that while definitions are
-optional, declarations are mandatory. To make things easier, programmers
-have adopted the header file convention: the header file of a source code
-contains all the declarations that a caller would need to be able to use
-its functions. For example, in Gnuastro, @file{lib/statistics.c} (file
-containing function definitions) comes with a
address@hidden/gnuastro/statistics.h} (only containing function declarations).
-
-The declarations in the header need to be @emph{include}d into the caller's
+helps their management and modularity, but this fact alone doesn't make
+things much easier for the caller's source code: recall that while
+definitions are optional, declarations are mandatory. So if this was all,
+the caller would have to manually copy and paste (@emph{include}) all the
+declarations from the various source files into the file they are working
+on now. To address this problem, programmers have adopted the header file
+convention: the header file of a source code contains all the declarations
+that a caller would need to be able to use any of its functions. For
+example, in Gnuastro, @file{lib/statistics.c} (file containing function
+definitions) comes with @file{lib/gnuastro/statistics.h} (only containing
+function declarations).
+
+The discussion above was mainly focused on functions, however, there are
+many more programming constructs such as data structures and pre-processor
+macros. Like functions, they also need to be known to the compiler when it
+confronts a call to them. So the header file also contains their
+definitions or declarations when they are necessary for the functions.
+
+The contents in the header need to be @emph{include}d into the caller's
 source code with a special pre-processor command: @code{#include
 <path/to/header.h>}. As the name suggests, the @emph{pre-processor} goes
 through the source code prior to the processor (or compiler). One of its
-jobs is to include, or merge, the contents of files that are mentioned like
-this in the source code, so the compiler sees them all as one. This allows
-you (the caller) to include many declarations into your code with only one
-line.
-
-Try opening some of the @file{.c} files in @file{lib/} with a text editor
-to see the include directives at the start of the file (after the copyright
-notice). Let's take @file{lib/fits.c} as an example. You will notice that
-files like @file{stdio.h}, or @file{string.h} are not in this directory (or
-anywhere within Gnuastro. However, the Gnuastro header files (like
address@hidden/fits.h}) are indeed within this directory. To find the
-header files, the pre-processor can also search in places other than the
-current directory. You can specify those with the
address@hidden/path/to/include/directory} option when calling the compiler
-(which includes the pre-processor). On most systems the basic C header
-files (like the @file{stdio.h} and @file{string.h} mentioned above) are
-located in @file{/usr/include/} (this @file{include/} is taken from the
-pre-processor's @code{#include} directive). Your compiler is configured to
-automatically search that directory (and some others), so you don't have to
-explictly mention it. Go ahead, look into the @file{/usr/include} directory
+jobs is to include, or merge, the contents of files that are mentioned with
+this directive in the source code. Therefore the compiler sees a single
+entity containing the contents of the main file and all the included
+files. This allows you to include many (sometimes thousands of)
+declarations into your code with only one line. Since the headers are also
+installed with the library into your system, you don't even need to keep a
+copy of them for each separate program, making things even more convenient.
+
+Try opening some of the @file{.c} files in Gnuastro's @file{lib/} directory
+with a text editor to see the include directives at the start of the file
+(after the copyright notice). Let's take @file{lib/fits.c} as an
+example. You will notice that Gnuastro's header files (like
address@hidden/fits.h}) are indeed within this directory (the @file{fits.h}
+file is in the @file{gnuastro/} directory). You will notice that files like
address@hidden, or @file{string.h} are not in this directory (or anywhere
+within Gnuastro).
+
+To find the header files, the pre-processor can also search in places other
+than the current directory. You can specify those directories with the
address@hidden/path/to/include/directory} option @footnote{Try running
+Gnuastro's @command{make} and find the directories given to the compiler
+with the @option{-I} option.} when calling the compiler (which includes the
+pre-processor). On most systems the basic C header files (like
address@hidden and @file{string.h} mentioned above) are located in
address@hidden/usr/include/address@hidden @file{include/} directory name is 
taken
+from the pre-processor's @code{#include} directive, which is also the
+motivation behind the `I' in the @option{-I} option to the
+pre-processor.}. Your compiler is configured to automatically search that
+directory (and possibly others), so you don't have to explictly mention
+these directories. Go ahead, look into the @file{/usr/include} directory
 and find @file{stdio.h} for example.
 
 If the pre-processor can't find the included files, it will abort with an
-error. Infact not knowing a library's installation directory is a very
-common when building programs that depend on it, see @ref{Known
-issues}. However in the build system used by Gnuastro (and most other
-programs/libraries), the compiler is invoked many address@hidden
-every command you see being executed after @command{make} is one call to
-the compiler.}. Hence, it is really hard (not to mention error-prone,
-frustrating and ugly) to manually add or modify this option on each
-call. To solve this problem, there are conventional environment variables
-for the various kinds of compiler options (or flags).  These environment
-variables are used in every call to the compiler. The environment variable
-used for the C Pre-Processor (or CPP) is @command{CPPFLAGS}. So by giving
address@hidden a value once, you can be sure that each call to the
-compiler will be affected. See @ref{Known issues} for an example of how to
-set this variable at configure time.
+error. Infact a common error when building programs that depend on a
+library is that the compiler doesn't not know where a library's header are
+(see @ref{Known issues}). So you have to inform the compiler of the
+location of the library's headers when its building the higher-level
+software. For a small software with one or two source files, this can be
+done manually. However, to enhance modularity, Gnuastro (and most other
+programs/libraries) contain many source files, so the compiler is invoked
+many address@hidden every command you see being executed after
+running @command{make} is one call to the compiler.}. This makes manual
+addition or modification of this function practically impossible.
 
address@hidden @command{CPPFLAGS}
+To solve this problem, there are conventional environment variables for the
+various kinds of compiler options (or flags).  These environment variables
+are used in every call to the compiler (they can be empty). The environment
+variable used for the C Pre-Processor (or CPP) is @command{CPPFLAGS}. By
+giving @command{CPPFLAGS} a value once, you can be sure that each call to
+the compiler will be affected. See @ref{Known issues} for an example of how
+to set this variable at configure time.
+
address@hidden GNU Build system
 As described in @ref{Installation directory}, you can select the top
-installation directory of a library, when you @command{./configure} it. All
-the separate components will be put in their separate subdirectory under
-that, for example the utilities/programs, compiled libraries and library
-headers will go into @file{prefix/bin}, @file{prefix/lib}, and
address@hidden/include} respectively. Libraries that contain diverse
-collections of functions (like GSL, WCSLIB, and Gnuastro), put their header
-files in a subdirectory unique to themselves for easier management, for
-example @file{prefix/include/gnuastro}. Since the top @file{include/}
-directory is usually known to the compiler, you need to keep the
-subdirectory when including the headers from such libraries, for example
address@hidden <gnuastro/fits.h>}.
-
-
address@hidden Linking,  , Headers, Review of library fundamentals
+installation directory of a software using the GNU build system, when you
address@hidden/configure} it. All the separate components will be put in their
+separate subdirectory under that, for example the utilities/programs,
+compiled libraries and library headers will go into @file{prefix/bin},
address@hidden/lib}, and @file{prefix/include} respectively. For enhanced
+modularity, libraries that contain diverse collections of functions (like
+GSL, WCSLIB, and Gnuastro), put their header files in a subdirectory unique
+to themselves. For example all Gnuastro's header files are installed in
address@hidden/include/gnuastro}. Since the top @file{prefix/include}
+directory is usually known to the compiler, in your source code, you need
+to keep the library's subdirectory when including the headers from such
+libraries, for example @code{#include <gnuastro/fits.h>}. Not all libraries
+need to follow this convension, for example CFITSIO only has one header
+(@file{fitsio.h}) which is directly installed in @file{prefix/include}.
+
+
+
+
address@hidden Linking, Summary and small example, Headers, Review of library 
fundamentals
 @subsection Linking
 
-After you run `make' during the building of Gnuastro you will see that for
-each @file{.c} file, two new files are created:
-
-All Gnuastro library functions are compiled into one file depending on how
-you would like to link to the libraries: @file{libgnuastro.a} and
address@hidden Both contain all the functions that are discussed in
-this chapter. They are both installed in the @file{prefix/lib} directory
-(see @ref{Installation directory} for @file{prefix}).
-
address@hidden Static library
address@hidden Dynamic library
address@hidden Library, static
address@hidden Library, dynamic
-The first compiled code (with a @file{.a} suffix) is a static library which
-actually gets included into your program's executable file when you link to
-it. Since it is integrated into your program's code, it can be very
-efficient and if you uninstall Gnuastro or try to run it on a system that
-doesn't have Gnuastro, your program will still run. The second (with a
address@hidden suffix) is known as a dynamic library, the code from dynamic
-libraries will not be included in your executable file, each time your
-program is run, it will find the library and take the code from there. The
-main advantage of dynamic libraries is that when the library is updated,
-your program will use the updated library without the need to recompile
-your program. If you do static linking, you will have to recompile your
-program to benefit from the updated library. There are more factors to
-consider, these might be some of the more important ones but this is
-certainly not a thorough comparison.
-
-The compiled library files described above are not enough for actually
-using the libraries. Before linking, the compiler also needs to know the
-general description of the functions which you will be linking to: what
-type of input arguments each function needs and what type of output it
-produces. In C, these description files are known as a `header'
-(conventionally having a @file{.h} suffix). Unlike the compiled library
-code which was only one file, there are commonly many headers, classified
-by context (with similar functions described in one header file). In the
-case of Gnuastro, all the headers are installed in
address@hidden/include/gnuastro/} (see @ref{Installation directory}). Another
-major difference is that headers are human-readable: you can open them in a
-text editor and actually read them.
address@hidden GNU Libtool
+To enhance modularity, similar functions are defined in one source file
+(with a @file{.c} suffix, see @ref{Headers} for more). After running
address@hidden, each human-readable, @file{.c} file is translated (or
+compiled) into a computer-readable ``object'' file (ending with
address@hidden). Note that object files are also created when building
+utilities/programs, they aren't particular to libraries. Try opening
+Gnuastro's @file{lib/} and @file{src/progname/} directories after running
address@hidden to see these object address@hidden uses GNU Libtool
+for portable library creation. Libtool will also make a @file{.lo} file for
+each @file{.c} file when building libraries (@file{.lo} files are
+human-readable).}. Afterwards, the object files are @emph{linked} together
+to create an executable program or a library.
+
address@hidden GNU Binutils
+The object files contain the full definition of the functions in the
+respective @file{.c} file along with a list of any other function (or
+generally ``symbol'') that is referenced there. To get a list of those
+functions you can use the @command{nm} utility which is part of GNU
+Binutils. For example from the top Gnuastro directory, run:
+
address@hidden
+$ nm src/arithmetic/arithmetic.o
address@hidden example
+
address@hidden
+This will print a list of all the functions (more generally, `symbols')
+that were called within @file{src/arithmetic/arithmetic.c} along with some
+further information (for example a @code{T} in the second column shows that
+this function is actually defined here, @code{U} says that it is undefined
+here. Try opening the @file{.c} file to check for your self. Run
address@hidden nm} for more information.
+
address@hidden Static linking
address@hidden Linking: Static
+In the case of Arithmetic (a program/utility) the contents of all these
+object files are copied (and re-ordered) into one final executable file
+which we can run from the operating system. When the symbols
+(computer-readable function definitions in most cases) are copied into the
+output like this, we call the process @emph{static} linking. Let's assume
+you have installed Gnuastro into the default @file{/usr/local} (see
address@hidden directory}). So please try @command{nm} on it to see how
+it now contains the symbols from all the @file{.o} files that went into
+making it:
+
address@hidden
+$ nm /usr/local/bin/astarithmetic
address@hidden example
+
address@hidden
+But you will notice that there are still many undefined symbols (have a
address@hidden in the second column), for example all the Gnuastro library
+functions that start with address@hidden':
+
address@hidden
+$ nm /usr/local/bin/astarithmetic | grep gal_
address@hidden example
+
address@hidden GNU Libtool
address@hidden Shared library
address@hidden Library: shared
address@hidden Dynamic linking
address@hidden Linking: dynamic
+These undefined symbols (functions) will be linked to the executable
+everytime you run arithmetic. Therefore they are known as dynamically
address@hidden libraries @footnote{Do not confuse dynamicly @emph{linked}
+libraries with dynamically @emph{loaded} libraries. The former (that is
+discussed here) are only loaded at the program startup. However, the latter
+can be loaded anytime during the program's execution, they are also known
+as plugins.}. When the functions of a library need to be dynamically
+linked, the library is known as a shared library. As we saw above, static
+linking is done when the executable is being built. However, when a library
+is linked dynamically, its symbols are only checked with the available
+libraries at build time: they are not actually copied into the
+executable. Everytime you run the program, the linker will be activated and
+link to the installed library. If you want all the libraries to be
+statically linked to the executables, you have to tell Libtool (which
+Gnuastro uses for the linking) to disable shared libraries at configure
address@hidden is very common and is commonly used. Therefore, you
+can use this option to configure on most programs using the GNU build
+system if you want static linking.}:
+
address@hidden
+$ configure --disable-shared
address@hidden example
+
address@hidden
+Try configuring, building and installing Gnuastro like this. Then check the
address@hidden symbols in the installed Arithmetic executable like before. You
+will see that they are actually copied this time (have a @code{T} in the
+second column). If the second column doesn't convince you, look at the
+executable file size with the following command:
+
address@hidden
+$ ls -lh /usr/local/bin/astarithmetic
address@hidden example
+
address@hidden
+It is roughly 100 kilo-bytes and 4.2 mega-bytes with dynamic and static
+linking respectively. This huge difference would have been very significant
+in the old days, but with the roughly tera-byte storages commonly in use
+today, it is negligible. Fortunately, output file size is not the only
+benefit of dynamic linking: since it links to the libraries at run-time
+(rather than build-time), when an update comes for the required libraries,
+you don't have to re-build the programs or libraries that depend on it. The
+updated implementation will automatically be used. To be fair, this also
+does present a few other problems:
+
address@hidden
address@hidden
+Reproducibility: Even though your high-level program or library has the
+same version as before, with the updated library, you might not get the
+same results.
address@hidden
+Broken links: if some functions have been changed or removed in the updated
+library, then the linker will abort with an error at run-time. Therefore
+you need to re-build your higher-level program or library.
address@hidden itemize
+
address@hidden GNU C library
+To see a list of all the shared libraries that are needed for a program or
+a shared library, you can use the GNU C library's @address@hidden
+your operating system is not using the GNU C library, you might need
+another tool.} program, for example:
+
address@hidden
+$ ldd /usr/local/bin/astarithmetic
address@hidden example
+
+The Library file names start with a @file{lib} and end with suffix
+depending on their type as described below. In between these two is the
+name of the library, for example @file{libgnuastro.a} (is Gnuastro's static
+library) and @file{libgsl.so.0.0.0} is GSL's shared library.
+
address@hidden
address@hidden
+A static library is known as an archive file and has a @file{.a} suffix. A
+static library is not an executable file.
+
address@hidden
address@hidden Shared library versioning
address@hidden Versioning: Shared library
+A shared library ends with a @file{.so.X.Y.Z} suffix and is executable. The
+three numbers in the prefix are the version of the shared library. Shared
+library versions are defined to allow multiple versions of a shared library
+simultaneously on a system and to help detect possible updates in the
+library and programs that depend on it by the linker. It is very important
+to mention that this version number is differnent from from the software
+version number (see @ref{Version numbering}), so do not confuse the
+two. See the ``Library interface versions'' chapter of GNU Libtool for
+more.
+
+For each shared library, we also have two symbolic links ending with
address@hidden and @file{.so}. They are automatically set by the installer,
+but you can change them when you have multiple versions of a library.
+
address@hidden itemize
+
address@hidden GNU Libtool
+For those libraries that use GNU Libtool (including Gnuastro and its
+dependencies), both static and dynamic libraries are built and installed in
+the @file{prefix/lib/} directory (see @ref{Installation directory}). In
+this way other programs can make which ever kind of link that they want.
+
+To link with a library, the linker needs to know where to find the
+library. You do that with two separate options to the linker:
+
address@hidden @option
address@hidden -L
+This option is used to specify the directories to search for libraries, for
+example @file{-L/usr/local/lib}, or @file{-L/home/yourname/.local/lib}. You
+can make multiple calls to this option, guiding the linker to look into
+several directories.
+
address@hidden -l
+The unique filename of the library. As discussed above, library file names
+have fixed parts which must not be given to this option. So @option{-lgsl}
+will guide the linker to either look for @file{libgsl.a} or
address@hidden (depending on the type of linking it is suppose to do).
+
+One very important issue about this option is that its place on the command
+line matters: As soon as the linker hits this option, it gets a list of the
+undefined symbols it has found so far and tries to find them in the library
+specified by this option. After the search in this library has finished,
+this library's contents are completely discarded from the linker's
+memory. So if a later object file or library uses one of the symbols in
+this library and this library is not present any more on the command-line,
+the linker will abort with an error. As an example, Gnuastro's
address@hidden function depends on the @code{log10} function
+of the C Math library (specified with @option{-lm}). So this will fail:
address@hidden -lgnuastro}, but @option{-lgnuastro -lm}, it will successfully
+build your program.
+
address@hidden table
+
+
+
+
address@hidden Summary and small example,  , Linking, Review of library 
fundamentals
address@hidden Summary and small example
+
+After the mostly abstract discussions of @ref{Headers} and @ref{Linking},
+we'll give a small tutorial here. But before that, let's recall the general
+steps of how your source code is prepared, compiled and linked to the
+librays it depends on so you can run it:
+
address@hidden
address@hidden
+The @strong{pre-processor} includes the header (@file{.h}) files into the
+function definition (@file{.c}) files, expands pre-processor macros and
+generally prepares the human-readable source for compilation (reviewed in
address@hidden).
+
address@hidden
+The @strong{compiler} will translate (compile) the human-readable contents
+of each source (merged @file{.c} and the @file{.h} files, or generally the
+output of the pre-processor) into the computer-readable code of @file{.o}
+files.
+
address@hidden
+The @strong{linker} will link the called function definitions from various
+compiled files to create one unified object. When the unified product has a
address@hidden function, this function is the product's only entry point,
+enabling the operating system or user to directly interact with it, so the
+product is a program/utility. When the product doesn't have a @code{main}
+function, the linker's product is a library and its exported functions can
+be linked to other executables (it has many entry points).
address@hidden enumerate
+
address@hidden GCC
address@hidden GNU Compiler Collection
+
+The GNU Compiler Collection (or GCC for short) will do all three steps. So
+as a first example, copy the @file{tests/lib/versionc.c} in a test
+directory, this small program will use the Gnuastro library function
address@hidden to print the version of Gnuastro. It is good
+practice for a program to report the versions of its dependencies for later
+reproducibility, so this function will (hopefully) be used a lot. To
+compile this program you can run this command:
+
address@hidden
+$ gcc versionc.c -o gnuastro-version -lgnuastro
address@hidden example
+
+If your top installation directory (let's call it @file{$prefix}) is not
+recognized by GCC, you will get errors for unknown header files or
+libraries. So you should run GCC as follows (telling it where to find the
+header files and libraries as described in the previous sections):
+
address@hidden
+$ gcc -I$prefix/include -L$prefix/lib versionc.c -lgnuastro     \
+      -o gnuastro-version
address@hidden example
+
address@hidden
+The @option{-o} option is used to specify the name of the output
+executable, without it the output file name will be @file{a.out},
+independent of your input file name(s). This single command has done all
+the three steps above: try removing the @option{-lgnuastro} option and you
+will see a linker error. You are now ready to run the program with
+
address@hidden
+$ ./gnuastro-version
address@hidden example
+
+This simple Gnuastro function didn't need linking to any other library. But
+if your program needs WCS coordinate transformations, needs to read a FITS
+file, or needs mathematical operations (which include its linear algebra
+operations), you also need to add these libraries in the call to GCC:
address@hidden -lwcs -lcfitsio -lgsl -lgslcblas -lm}. In @ref{Gnuastro
+library} where we document each function, it is mentioned which libraries
+(if any) must also be linked when you call a function.
+
+
 
 @node Gnuastro library, The TEMPLATE utility, Review of library fundamentals, 
Libraries
 @section Gnuastro library



reply via email to

[Prev in Thread] Current Thread [Next in Thread]