static library: undefined reference error ...

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to bring some functions into a static library.

But I get undefined reference errors for all functions form the library which are used in the main project (AS 7.0)

 

- all functions are void functions in the library.c-file

- the  liblibrary.a file is created

 

- the liblibrary.a-file is listed under libraries in the main project

- I have included a header-file for the library-file in my main project

 

But I get "undefined reference error" for each call to on of the library-functions - And I do not find the problem!

 

Can someone give me help how to track down the problem , please

This topic has a solution.

I program like a man:
COPY CON: > firmware.hex

Last Edited: Sat. Feb 10, 2018 - 07:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Shame on me ...

I forgot to include the library  ....

I program like a man:
COPY CON: > firmware.hex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What possible use are static libs in an AVR development environment?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AFAIK, each and every library avr is static.... Use is maximum, then.... (seems like a lapalissade https://en.wikipedia.org/wiki/Lapalissade, anyway; maybe a useful one)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well of course the libraries are static if you choose to use them (dynamic linking would presumably suggests SPM of the AVR at runtime? Either that or come complex RAM based trampoline system).

 

My question was "what is the point of using static libs for an AVR?". In the old day you used to do it because you could isolate each function in a separate source (and hence .o) file and it ensured that only things that were referenced were pulled in. That still happens for things like libm, libc and libgcc - you only get a copy of strcpy() in the code if you call it. But the "modern" equivalent is -ffunction-sections and -gc-sections. So now only functions that actually referenced in a pile of .c source files remain in the final linked image - everything else is "garbage collected" and discarded. So you don't need static links to achieve the same.

 

The downside of static links is that AVR has 17 different binary formats (some models have MUL, some don't, some use LPM, some use ELPM, some use 16 bit JMPs, some use 24 bit JMPs etc). So if you prebuild code as a static lib then to be able to later use it with any model of AVR you need 17 different builds. If you look at the C compiler you will see 17 different libc.a, 17 different libm.a and 17 different libgcc.a for this very reason...

C:\SysGCC\avr\avr\lib>dir libc.a /s /b
C:\SysGCC\avr\avr\lib\libc.a
C:\SysGCC\avr\avr\lib\avr25\libc.a
C:\SysGCC\avr\avr\lib\avr25\tiny-stack\libc.a
C:\SysGCC\avr\avr\lib\avr3\libc.a
C:\SysGCC\avr\avr\lib\avr31\libc.a
C:\SysGCC\avr\avr\lib\avr35\libc.a
C:\SysGCC\avr\avr\lib\avr4\libc.a
C:\SysGCC\avr\avr\lib\avr5\libc.a
C:\SysGCC\avr\avr\lib\avr51\libc.a
C:\SysGCC\avr\avr\lib\avr6\libc.a
C:\SysGCC\avr\avr\lib\avrtiny\libc.a
C:\SysGCC\avr\avr\lib\avrxmega2\libc.a
C:\SysGCC\avr\avr\lib\avrxmega4\libc.a
C:\SysGCC\avr\avr\lib\avrxmega5\libc.a
C:\SysGCC\avr\avr\lib\avrxmega6\libc.a
C:\SysGCC\avr\avr\lib\avrxmega7\libc.a
C:\SysGCC\avr\avr\lib\tiny-stack\libc.a

The other argument against static libs is for example say you create a libuart.a to provide UART functions then what baud rate does it use. If you just have a uart.c that you build into your code you can do stuff like:

#if F_CPU == 11589200
   UBRR = 137;
#elif F_CPU == 16000000
   UBRR = 93;
etc

so now you just set F_CPU right and build the code and just one line setting UBRR to the right value for that speed is used. But if you have it in a prebuilt binary then the code has to calculate it on the fly with something like:

uart_init(uint32_t f_cpu) {
    if (f_cpu == 11589200) {
        UBRR = 137;
    }
    else if (f_cpu == 16000000) {
        UBRR = 93;
    }
    etc.
}

So now the code is doing loads of stuff at run time that could have been precompiled if you just used uart.c in the the project rather than building the code then linking to one of your 17 copies of libuart.a

 

I know AS7 offers to build "executable" or "static library" but it's only doing that because the Visual Studio it inherits from offers those choices. Really, for AVR, it shouldn't offer a choice as it just confuses folks as this thread serves to highlight.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your information.

 

I wrote "drivers" fro several hardware peripheral such as CAN--Controller, LED-Display, Motro-controller.

 

So, I found it useful to re-use that code and have a library and header-file ready when I want to use it. Or split my project into several sub-projects - just to keep it better readable. Maybe that is too much.

I can see the disadvantages already as my library is compiled for a certain device - say ATmega32. For an AT90CANxxx I have to re-compile it.

 

For this project, i think I have to live with it.

And I even have a more complex problem:

One project (which is not hardware-related) was written in c++.

 

My other projects are c.

All projects compile successful, but I get undefined reference errors for each call to a function from the c++ library.

 

What can I do ?

How can I

 

I program like a man:
COPY CON: > firmware.hex

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C++ uses ‘name mangling’ - google that.
Yours is a common problem when mixing C with C++
Read up on the use of extern ‘C’.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can call C from C++ by using the "extern" that Kartman mentions but what you can't do is call C++ from C. This often means converting main.c to main.cpp so it gets compiled as C++ even if anything but the class instantiation and invocation actually look like C.

Last Edited: Sat. Feb 10, 2018 - 12:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then, "only" fast solution would be to rewrite C++ library in C (majority being C). 

I wrote "fast", it is faster on the short term... On the long term, I donot know...