I tried to link a static library (compiled with gcc) to a c++ program and I got 'undefined reference'. I used gcc and g++ version 4.6.3 on a ubuntu 12.04 server machine. For example, here is the simple library file for factorial method:
mylib.h
#ifndef __MYLIB_H_
#define __MYLIB_H_
int factorial(int n);
#endif
mylib.c
#include "mylib.h"
int factorial(int n)
{
return ((n>=1)?(n*factorial(n-1)):1);
}
I created object for this mylib.c using gcc:
gcc -o mylib.o -c mylib.c
Again the static library was created from the object file using AR utility:
ar -cvq libfact.a mylib.o
I tested this library with a C program (test.c) and C++ program (test.cpp)
Both C and C++ program have the same body:
#include "mylib.h"
int main()
{
int fact = factorial(5);
return 0;
}
Assuming static library libfact.a is available in /home/test directory, I compiled my C program without any issues:
gcc test.c -L/home/test -lfact
However while testing C++ program, it threw a link error:
g++ test.cpp -L/home/test -lfact
test.cpp:(.text+0x2f): undefined reference to `factorial(int)'
collect2: ld returned 1 exit status
I even tried adding extern command in test.cpp:
extern int factorial(int n) //added just before the main () function
Still the same error.
test.cpp
to make it work?The problem is that you haven't told your C++ program that factorial is written in C. You need to change your test.h header file. Like this
#ifndef __MYLIB_H_
#define __MYLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
int factorial(int n);
#ifdef __cplusplus
}
#endif
#endif
Now your header file should work for both C and C++ programs. See here for details.
BTW names containing a double underscore are reserved for the compliler (so are names starting with an underscore and a capital letter) so #ifndef __MYLIB_H_
is illegal strictly speaking. I would change to #ifndef MYLIB_H #define MYLIB_H
While the accepted answer is absolutely correct, I thought I'd just add an observation. Some editors have trouble with the open / close brace, and will indent the entire extern "C"
scope in the header. If mylib.h
is a key header for a library, you might consider:
#if defined (__cplusplus)
#define _MYLIB_INIT_DECL extern "C" {
#define _MYLIB_FINI_DECL }
#else
#define _MYLIB_INIT_DECL
#define _MYLIB_FINI_DECL
#endif
All other headers in mylib
library, e.g., mylib_aux.h
, can be of the form:
#ifndef _MYLIB_AUX_H
#define _MYLIB_AUX_H
#include <mylib.h>
_MYLIB_INIT_DECL
... header content ...
_MYLIB_FINI_DECL
#endif /* _MYLIB_AUX_H */
Obviously, the names I'm using are arbitrary, but for multiple library headers, this approach has been useful to me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With