3

abc.c file

#include "abc.h"
int abc()
{
    return 10;
}

abc.h file

int abc();

mymain.cpp file

#include "abc.h"
int main()
{
    abc();
    return  0;
}

Makefile

CC=gcc -O2 
CP=g++

mymain: mymain.o abc.o
    $(CP) -o mymain mymain.o abc.o

mymain.o: mymain.cpp abc.h
    $(CP) -c mymain.cpp abc.h

abc.o: abc.c abc.h
    $(CC) -c abc.c abc.h

clean:  
    $(RM) *.o mymain

output

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
g++ -o mymain mymain.o abc.o
mymain.o: In function `main':
mymain.cpp:(.text+0x5): undefined reference to `abc()'
collect2: error: ld returned 1 exit status
make: *** [mymain] Error 1

Why abc() is undefined reference ??

UPDATE

new abc.h

extern "C" {
    int abc();
}

error

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
In file included from abc.c:1:0:
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
make: *** [abc.o] Error 1
shantanu
  • 2,408
  • 2
  • 26
  • 56
  • 2
    Don't pass `abc.h` to the compiler. Header files are processed when they're `#include`ed by `.c` or `.cpp` files. – Keith Thompson Jan 22 '14 at 21:07
  • 2
    Also, `CP` is a really bad name for this. Most people will think you're trying to copy a file. The default variable name in make for C++ compiler is `CXX` (and `CXXFLAGS` for C++ compiler-specific flags). – MadScientist Jan 22 '14 at 21:28

1 Answers1

9

The problem is you're trying to link a C function into a C++ object, without telling the compiler this is what you're doing.

If your header file (abc.h) looked like this:

extern "C" {
    int abc();
}

it would work (when included into a C++ source... but would break when included into a C source).

You can enclose the extern "C" { and its trailing } within macros as shown in Combining C++ and C - how does #ifdef __cplusplus work? in order to be suitable for both C and C++ inclusion.

Note that $(CP) -c mymain.cpp abc.h in your makefile does not make sense -- you don't want to specify the header on your compiler command line. This goes for both instances of that pattern.

Community
  • 1
  • 1
mah
  • 39,056
  • 9
  • 76
  • 93
  • @shantanu You need to conditionally exclude it when compiling the .c file because the C compiler doesn't know about `extern "C"` – JustSid Jan 22 '14 at 21:10
  • I got it. It's makefile. I need to remove abc.h from $(CP) -c mymain.cpp – shantanu Jan 22 '14 at 21:11