Rajesh Rajesh - 3 years ago 41
C Question

multiple inclusion of static library in C

I have

libTimer.a
,
lib2.a
,
lib3.a
and application code.
lib2.a
created by linking
libTimer.a
(created from
timer.o
) with other object files
a.o
and
b.o
.
Even
lib3.a
also created by linking
libTimer.a
and other object files such as
c.o
and
d.o
.

Now application
main.o
is linked with libraries
lib2.a
and
lib3.a
.
I understand that size of the application does not increase (multiple inclusion does not happen) by this method. I just tested and found no change in application size when application is built by linking libraries or by adding individual source files
a.o
,
b.o
,
c.o
,
d.o
and
timer.o
.

But are there any guidelines in nesting libraries in this way?

Given below is the command summary:



libTimer.a

Compilation Command:

avr-gcc.exe -Os -Wextra -Wall -mmcu=atmega328p -std=gnu99 \
-fshort-enums -ffunction-sections -fdata-sections -DF_CPU=16000000UL \
-g -Os -Wmain -Wextra -Wall -c CL_Timer.c -o Debug\CL_Timer.o


Linking Command:

avr-g++.exe -o Debug\Timer.elf Debug\Timer.o -mmcu=atmega328p \
-Wl,-Map=Debug\timer.map -Wl,--gc-sections


Post Build Command:

avr-ar rcs libTimer.a Debug\timer.o
ranlib libTimer.a


Lib2.a

Linking Command:

avr-g++.exe -o Debug\library2.elf Debug\a.o Debug\b.o -mmcu=atmega328p \
-Wl,-Map=Debug\library2.map -Wl,--gc-sections .\libTimer.a


Post Build:

avr-ar rcs lib2.a Debug\a.o Debug\b.o
ranlib lib2.a


lib3.a

Linking Command:

avr-g++.exe -o Debug\library3.elf Debug\c.o Debug\c.o -mmcu=atmega328p \
-Wl,-Map=Debug\library3.map -Wl,--gc-sections .\libTimer.a


Post Build Command:

avr-ar rcs lib3.a Debug\c.o Debug\d.o
ranlib lib3.a


Main Application Linking:

avr-g++.exe -o Debug\main.elf Debug\main.o -mmcu=atmega328p \
-Wl,-Map=Debug\main.map -Wl,--gc-sections .\liba.a .\liba.b

Answer Source

What you show as "linking commands" is unnecessary except for your main application. I'm actually surprised that it doesn't throw errors, as your library code shouldn't contain main().

The commands creating the static library are the ar commands (in your case the cross-compiler avr-ar commands). The only thing they do is to place all object files for the library in an archive file (*.a).

With shared libraries, you would have some dependency information, so a shared library can link against another shared library. With static libraries, no such thing exists, they are just archives of object files and in your final linking step of your main application, you have to make sure to link all required libraries. Therefore, with liba and libb both depending on libTimer as you describe, the final linking step is wrong, it should look like this:

avr-g++.exe -o Debug\main.elf Debug\main.o -mmcu=atmega328p \
    -Wl,-Map=Debug\main.map -Wl,--gc-sections .\liba.a .\libb.a .\libTimer.a

This assumes they are actually named liba.a and libb.a -- you have some confusion in your question with libraries called lib2.a and lib3.a as well.

Important thing to note: In your linking command, always list libraries and object files before their dependencies. The linker works by maintaining unresolved symbols and can only resove them from libraries and object files coming later at the command line.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download