0

I am trying to call a C++ function from a C file. So I declared the function as extern "C" and declared it in C file as well. Created a object file from the cpp file let's call it cpp_object.o, then created a object file for the main.c.

It is not that obvious that I can use g++ to link them. No, the main calls some c libs so I cannot link them with g++. So I have to link them with gcc. I tried the followings:

main: main.o cpp_object.o
    ${CROSS}${CC} $^ -o $@ ${LDFLAGS}

It shows error that the object file cannot find the C++ stdlib. I did not know what happened. Googled it tried the following:

main: main.o get_config.o
    ${CROSS}${CC} $^ -o $@ ${LDFLAGS}  -lstdc++

Then it worked!? Does it mean the gcc compile the code with the c++ stdlib? But I am bit confused, how do we need to compile a C code with c++ stl?

So is this actually did what I wanted? Or I missed something?

J.R.
  • 769
  • 2
  • 10
  • 25
  • Why do you assume that the C code needs the C++ STL? It makes much more sense to assume that the C++ function needs the C++ STL. – nwp Nov 01 '17 at 15:46
  • @nwp hi. what I wanted to say is the C++ function that the C file calls need stl. But my question is does this option rly mean the gcc compile the C code with stl? – J.R. Nov 01 '17 at 15:52
  • 1
    `main.o` isn't C code. You're linking, not compiling. – melpomene Nov 01 '17 at 15:53

2 Answers2

2

the C++ object you linked with needs the C++ library.

If you're linking with the C driver (ex: gcc), you need to add linkage to C++ library because of this C++ object, not because of the C object. C driver isn't aware of C++.

Had you linked with the C++ driver (ex: g++), the C++ library is set by default (you don't need to add it to the link options)

Note that at this point all objects are compiled, the phase is the link phase.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Thnx. I thought the stl is already compiled into the object file. how come are they still necessary while linking? – J.R. Nov 01 '17 at 15:53
  • Much of the std:: library is "compiled into the object file" as you described (since they are largely template header files), but these header files in turn invoke functions that are in the std lib. Hence, there's stuff to link. (e.g. "new and delete"). – selbie Nov 01 '17 at 15:56
  • @selbie alright. Seems I learnt something new. Thnx. – J.R. Nov 01 '17 at 16:00
1

Most likely, you just need to use the C++ compiler to initiate the final link. By doing that, all the correct linkage parameters will get passed to the linker.

main: main.o get_config.o
    ${CROSS}${CXX} $^ -o $@ ${LDFLAGS}
selbie
  • 100,020
  • 15
  • 103
  • 173
  • Hey. I cannot compile it as cpp file. Cause actually the main.c calls other c libs. If I compile main.c with g++ I get over thousands errors... – J.R. Nov 01 '17 at 16:01
  • I didn't say compile the .c file with the c++ compiler, I'm saying have all generated .o files linked by invoking: `g++ -o main main.o get_config.o`. In this case, there's nothing to "compile" and the C++ compiler will in turn just invoke the linker with the correct parameters. – selbie Nov 01 '17 at 16:27
  • Hi. sorry it was my mistake, I wanted to say it is at the linking stage I have a dynamic c lib to link with the main. Would it work? – J.R. Nov 01 '17 at 17:08
  • Most likely. Linking is independent of the programming language. It's just the the compiler just invokes the linker for you with the correct flags and parameters. So I was suggesting if your Makefile will *compile* everything into a .o using the correct compiler, then you can can link all your .o files and get the correct C++ libs passed to the linker by using the c++ compiler. – selbie Nov 01 '17 at 17:24
  • Thnx. I was not very aware with the linking process. I thought it is language dependent. But if things are as you state, what are the differences between g++ linker and gcc linker? Do they actually both call ld but just with different default parameters? – J.R. Nov 01 '17 at 17:53
  • There is no "g++ linker" or "gcc linker". There's just `ld` (the linker) which combines all the `.o` files and all the additional libraries into a single executable with `main` as your entry point. When you invoke `gcc` or `g++`, it launches a child process for `ld` and passes all the appropriate arguments for a C or C++ program including the list of additional libraries needed for C and C++. It's just that C++ also needs all the C libs. That's why the above should work. – selbie Nov 01 '17 at 19:56