cancel
Showing results for 
Search instead for 
Did you mean: 

Don't Use Static Libraries in Embedded Project?

Issinski.Anton
Associate II
Posted on June 20, 2018 at 19:21

I found a problem with static libraries that prevents their use at least with Atollic true studio and wondering if there are other tools on the market that will be able to handle it or should I forget the libraries once and forever

:(

.

We have a system consisting of multiple STM32H7 MCUs communicating over some data bus. The natural and proper way to organize such project workspace is to have several static libraries (one for cross-platform algorithms, one for project-specific such as data bus protocol functions, one for sharing data formats with back office software, etc). Executable project for MCU will have most of its code implementation residing in such static libraries and only invoking public interfaces from them.

However, linker removes symbols from the library if its symbols are not explicitly referenced by the executable project and only referenced by the other static libraries.

For example, lets say we have two static libraries Lib1 and Lib2. Lib2 implements function 'Main' that uses function 'Calc' which is implemented in Lib1. Executable project links Lib1 and then links Lib2. Because executable project does not use function 'Calc' explicitly, it gets removed after linking Lib1. After linking Lib2 linker reports that symbol 'Calc' is not found.

In the real life libraries contain thousands of symbols and simple work arounds such as dummy explicit references from the executable don't work (because of private symbol declaratoins in libraries as one of the reasons). Disabling optimization such as dead code removal also does not help.

The only work around that I presently see is not to use static libraries at all in any projects, which will be a disappointing decision.

5 REPLIES 5
Posted on June 20, 2018 at 20:19

Sounds like a tool issue rather than a library issue

A library should be a collection of objects, the objects in two libraries should be combinable.

The linker should be able to get closure from wherever the objects come from. Dead code should remove objects that don't fulfill any dependencies.

The linker may only report public symbols into the final object.

Try this on professional tools like IAR or Keil, rather than GNU/GCC retreads.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III
Posted on June 20, 2018 at 23:10

This is a common issue with GNU toolchain, of course it can use static libs. See for example

https://stackoverflow.com/questions/2738292/how-to-deal-with-recursive-dependencies-between-static-libraries-using-the-binut

 

https://gcc.gnu.org/ml/gcc-help/2011-01/msg00164.html

 

- pa

Posted on June 20, 2018 at 23:14

Yes, this is not an STM32-specific issue; rather, gcc (more precisely, binutils)-related.

However, linker removes symbols from the library if its symbols are not explicitly referenced by the executable project and only referenced by the other static libraries.

Not quite so. The linking process is slightly bit more involved, and - in the name of speed/efficiency - it treats libraries differently than objects. While adding objects, the unresolved links from previous objects are stored and checked against the symbols from the newly added object (or, equivalently, objects are searched for all already unresolved symbols repeatedly - there are several ways to treat this and I don't know the exact algorithm used); libraries are searched only once, 'linearly', as it's not anticipated that there are unresolved symbols in libraries, and if there are a few, they are supposed to be provided by the application (and this is why gcc, i.e. the 'driver' program, places the 'default libraries' from specs to the end of the line, after all the objects and user libraries).

The best explanation is perhaps given directly with the switches you might want to use:

-(

archives

-)

or

--start-group 

archives

--end-group

The archives should be a list of archive files. They may be either explicit file names, or -l options.

The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.

Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.

Google for 'why libraries orders matters when linking' if you want additional information on the matter.

JW

Posted on June 20, 2018 at 22:26

Yes, IAR does not have this issue.

Issinski.Anton
Associate II
Posted on June 21, 2018 at 01:20

Pavel, Waclawek.jan:

Thanks, you are right, this fixes the issue. I was about to spend a week porting everything to IAR. Now will give gcc another chance  !