Mohamed Noaman
Mohamed Noaman

Reputation: 43

static and dynamic linking using gcc

I've been recently reading about static and dynamic linking and I understood the differences and how to create static and dynamic library and link it to my project

But, a question came to my mind that I couldn't answer or find answer for it as It's a specific question ... when I compile my code on linux using the line

#include <stdio.h>
int main()
{
  printf("hello, world!\n");
}

compiling using this command

[root@host ~]# gcc helloworld.c -o helloworld

which type of linking is this?? so the stdio.h is statically or dynamically linked to my project???

Upvotes: 2

Views: 5513

Answers (2)

2785528
2785528

Reputation: 5566

which type of linking is this?? so the stdio.h is statically or dynamically linked to my project???

stdio.h is not linked, it is a header file, and contains code / text, no compiled objects.

The normal link process prefers the '.so' library over the '.a' archive when both are found in the same directory. Your simple command is linking with the .so (if that is in the correct path) or the .a (if that is found in a path with no .so equivalent).

To achieve static linking, you have several choices, including

1) copy the '.a' archive to a directory you create, then specify that 
directory (-L)

2) specify the path to the '.a' in the build command.   Boost example:

$(CC) $(CC_FLAGS)  $<  /usr/local/lib/libboost_chrono.a  -o $@  $(LIB_DIRs) $(LIB_NMs)

I have used both techniques, I find the first easier.

Note that archive code might refer to symbols in another archive. You can command the linker to search a library multiple times.

If you let the build link with the .so, this does not pull in a copy of the entire .so into the build. Instead, the .so (the entire lib) is loaded into memory (if not already there) at run-time, after the program starts. For most applications, this is considered a 'small' start-up performance hit as the program adjusts its memory map (auto-magically behind the scenes) Note that the app itself can control when to load the .so, called dynamic library.


Unrelated:

// If your C++ 'Hello World' has no class ... why bother?
#include <iostream>

class Hello_t {
public:
   Hello_t()  { std::cout << "\n  Hello"  << std::flush; }
   ~Hello_t() { std::cout <<    "World!" << std::endl; }
   void operator() () { std::cout << " C++ "; }
};
int main(int, char**) { Hello_t()(); }

Upvotes: 0

Serge
Serge

Reputation: 12354

Libraries are mostly used as shared resources so, that several different programs can reuse the same pre-compiled code in some manner. Some libraries come as standard libraries which are delivered with the operating system and/or the compiler package. Some libraries come with other third party projects.

When you run just gcc in the manner of your example, you really run a compiler driver which provides you with few compilation-related functions, calling different parts of the compilation process and finally linking your application with a few standard libraries. The type of the libraries is chosen based on the qualifiers you provide. By default it will try to find dynamic (shared) libraries and if missing will attempt for static. Unless you tell it to use static libs only (-static).

When you link to project libraries you tell the gcc/g++ which libraries to use in a manner (-lname). In such a way it will do the same as with the standard libraries, looking for '.so' first and '.a' second, unless -static is used. You can directly specify the path to the full library name as well, actually telling it which library to use. There are several other qualifiers which control the linking process, please look man for 'g++' and 'ld'.

A library must contain real program code and data. The way it is linked to the main executable (and other libraries) is through symbol tables which are parts of the libraries. A symbol table contains entries for global functions an data.

There is a slight difference in the structure of the shared and static libs. The former one is actually a pre-linked object, similar to an executable image with some extra info related to the symbols and relocation (such a library can be loaded at any address in the memory and still should work correctly). The static library is actually an archive of '.o' files, ready for a full-blown linking.

The usual steps to create a library is to compile multiple parts of your program into '.o' files which in turn could be linked in a shared library by 'ld' (or g++) or archived in .a with 'ar'. Afterwards you can use them for linking in a manner described above.

An object file (.o) is created one per a .cpp source file. The source file contains code and can include any number of header files, as 'stdio.h' in your case (or cstdio) or whatever. These files become a part of the source which is insured by the cpp preprocessor. The latter takes care of macros and flattening all the #include hierarchies so that the compiler sees only a single text stream which it converts into '.o'. In general header files should not contain executable code, but declarations and macros, though it is not always true. But it does not matter since they become welded with the main source file.

Hope this would explain it.

Upvotes: 4

Related Questions