I am trying to come up with a makefile where the target is linked with object files produced by C and C++ sources.
My setup is Ubuntu/gcc:
$ uname -a
Linux srvr1 2.6.24-24-server #1 SMP Fri Sep 18 17:24:10 UTC 2009 i686 GNU/Linux
gcc version 4.2.4
$ cat main.cpp
#include <iostream>
using namespace std;
extern "C" int clnt(int);
int main(int argc, char *argv[])
{
int x = argv[1] ? atoi(argv[1]) : 100;
int y = 0;
y = clnt(x);
cout << y;
return 0;
}
$ cat client.c
int clnt(int x)
{
int y = 0;
y = (x < 0) ? x * x : x + x;
return(y);
}
$ cat makefile
CFLAGS = -g
CPPFLAGS = -Wall -ansi -g
OBJS = main.o client.o
tester: $(OBJS)
$(CC) -o $@ $(OBJS)
$ make
g++ -Wall -ansi -g -c -o main.o main.cpp
cc -g -Wall -ansi -g -c -o client.o client.c
cc -o tester main.o client.o
main.o: In function `std::__verify_grouping(char const*, unsigned int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/usr/include/c++/4.2/bits/locale_facets.tcc:2562: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const'
/usr/include/c++/4.2/bits/locale_facets.tcc:2571: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
/usr/include/c++/4.2/bits/locale_facets.tcc:2573: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
/usr/include/c++/4.2/bits/locale_facets.tcc:2578: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
main.o: In function `__static_initialization_and_destruction_0':
/usr/include/c++/4.2/iostream:77: undefined reference to `std::ios_base::Init::Init()'
main.o: In function `__tcf_0':
/usr/include/c++/4.2/iostream:77: undefined reference to `std::ios_base::Init::~Init()'
main.o: In function `main':
/home/mgurfink/mydev/amq/cms/main.cpp:12: undefined reference to `std::cout'
/home/mgurfink/mydev/amq/cms/main.cpp:12: undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
main.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
make: *** [tester] Error 1
Question #1: why CPPFLAGS are used for the compilation of client.c - even though it correctly uses 'cc', not 'g++' for C file?
Question #2: why it failed to use C++ related stuff when linking?
I do have a working makefile, where I explicitly say to use g++ and it works, see below:
CC = g++
CFLAGS = -g
CPPFLAGS = -Wall -ansi -g
OBJS = main.o client.o
tester: $(OBJS)
$(CC) -o $@ $(OBJS)
main.o: main.cpp
$(CC) -c $<
client.o: client.c
gcc -c $<
But I'd like to keep it simple, as the actual build has many more different modules and I'd hate to have to write a target for every single one of them.
One more piece of info - actual CPPFLAGS need to be different from CPFLAGS, as some that I need are not supported by C compiler, such as -Wno-non-virtual-dtor
Any suggestions?