I am attempting to create a library much like the Arduino in C.

I have tried in the past and although I have lost the code, I remember simply getting loads of undefined references to functions specified in the header files and in the library which did contain all the object files (checked by avr-objdump).

I want to know how I should compile the library (example makefile) and how the program should be compiled to it. Also, do I need to re-compile the library for every AVR and Clock speed, or is there a way around it?

If you need any more information, just ask.


EDIT: Example (not working)


#include "test.h"

int main(void)


#include "test.h"

void test_function()
    int i;


#ifndef __TEST_H_
#define __TEST_H_

void test_function(void);


1 Answer 1


The AVR-Libc user manual has an entire chapter on how to build a library. I would suggest starting there. If you use an IDE like eclipse, there will be project settings that are applicable if you want to build as a library instead of an executable.


Here's what eclipse does when I set it up for your example:

So that it couldn't be trivially compiled away, I changed your test_function to:

#include "test.h"

void test_function()
    volatile int i = 0;

Building the library:

avr-gcc -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"test.d" -MT"test.d" -c -o"test.o" "../test.c"

avr-ar -r "libtest.a"  ./test.o 

avr-objdump -h -S libtest.a  >"libtest.lss"

avr-size --format=avr --mcu=atmega328p libtest.a

Building the main program

avr-gcc -I"C:\path\to\my\workspace\test" -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"program.d" -MT"program.d" -c -o"program.o" "../program.c"

avr-gcc -Wl,-Map,MainProgram.map -L"C:\path\to\my\workspace\test\Release" -mmcu=atmega328p -o"MainProgram.elf"  ./program.o   -ltest

avr-objdump -h -S MainProgram.elf  >"MainProgram.lss"

avr-size --format=avr --mcu=atmega328p MainProgram.elf

... and it builds without error. My guess is you need include paths specified in the command lines. Following proper naming conventions is pretty important too, try and follow the pattern above. Obviously the avr-objdump and avr-size commands are just for more information and not required if you're just building.

I'm pretty certain that if you'll need to recompile your library for specific target architectures and clock speeds as well.

  • \$\begingroup\$ I have created a header containing the prototype 'void test_function(void);' compiled it using 'avr-gcc test.c -c -o test.o' and archieved it using 'avr-ar rcs libtest.a test.o'. I then attempted to use it will 'avr-gcc temp.c -I. -L. -ltest -o temp'. I still get undefined error! Am I doing something wrong? \$\endgroup\$
    – Will03uk
    Feb 28, 2012 at 17:18
  • \$\begingroup\$ @Will03uk Try avr-gcc -o temp temp.c -I. libtest.a \$\endgroup\$ Feb 28, 2012 at 17:21
  • \$\begingroup\$ Same error again (I also had an incorrect header name error now and so the undefined error occurs before it pre-processes the program file, if that helps) \$\endgroup\$
    – Will03uk
    Feb 28, 2012 at 17:35
  • \$\begingroup\$ You actually implemented test_function in test.c, right? Not just declared it? \$\endgroup\$ Feb 28, 2012 at 17:37
  • \$\begingroup\$ Yeah, it's so wierd; I'll edit the code into the question. \$\endgroup\$
    – Will03uk
    Feb 28, 2012 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.