2

I compiled a library with g++ and I want to link against it with gcc.
Problem is I get an error while linking against it:

undefined reference to 'functionName`

(functionName is the function name in the library)

although the function exists in the symbols list and I specify the path to gcc while linking.

It happens because the function appears in the list with surrounding characters (I think this is for overriding?):

Z12functionNameiSt9__va_list

I know that to remove these characters I should surround the function declaration with extern "C". And I did that:

//header.hpp
extern "C" int functionName(int argc, ...);

But the surrounding characters still appear around the function name in the symbols list. And that's why gcc can't find it.

I'm cross compiling for linux arm yokto with arm-poky-linux-gnueabi-gcc and arm-poky-linux-gnueabi-g++ on Ubuntu desktop 16.

Why aren't the surrounding characters being removed and how can I remove them? I will never override this function so if these are really for overriding then I don't need them.


edit:

Solved. The function signature in its declaration was different from the signature in its definition... So the extern keyword was for nothing.

int functionName(int argc, ...); //declaration
int functionName(int argc, va_list args) //definition
Alaa M.
  • 4,961
  • 10
  • 54
  • 95

2 Answers2

2

Those characters are name mangling. They encode the function signature so C++ overloading can work correctly (eg. int foo(int) and int foo(float) are different symbols).

If your API is C, you need to fix the library to not have the mangling. Build it as C or add extern "C" in its code. If your API is meant to be C++, remove the extern "C" from your header.

If the mangled names don't match (different mangling), then you probably have an ABI compatibility problem. In that case, trying to fix the link problem is the wrong solution. You need to make sure you build your code with the same ABI as the library instead.

The c++filt tool should be able to decode the mangled symbol into a signature. That can be useful to figure out what the difference is about.

Given you built the library with g++ and are trying to link with gcc, it's likely you want a C API and rebuilding the library with the extern "C" in place is what you need.

Olivier
  • 1,144
  • 1
  • 8
  • 15
  • The API is c (no classes) but the function uses c++ libraries. I added `extern "C"` to the header (see post) but it's not deleting the surrounding characters. Might it be because the function signature has an ellipsis (`...`)? – Alaa M. Dec 21 '16 at 17:43
  • @AlaaM. No, it works fine with ellipsis. Did you rebuild the library with the `extern "C"` present? I understood from your post that the linker looks for `functionName` but the library contains `Z12functionNameiSt9__va_list`, which means the problem is with the library. Also make sure the library is actually including the header and not simply defining the function without any `extern "C"`. – Olivier Dec 21 '16 at 18:09
  • As I said in the post, I know that the problem is in the library. The problem is that it still contains the surrounding characters – Alaa M. Dec 21 '16 at 18:11
  • @AlaaM. sorry it wasn't clear if you had rebuilt the lib. In that case I'd suggest reducing the problem complexity: start with g++ on a single file containing an empty `extern "C"` function and see if that still exports with name mangling. I've seen a few very weird problems explained by compiling the wrong code in my career (ie. an old copy of the header without `extern "C"` in it). – Olivier Dec 21 '16 at 19:29
0

The "surrounding characters" are actually for name mangling. So better speak of mangled names.

You probably should add

#ifdef __cplusplus
extern "C" {
#endif

near the start of your (public) header file (that you'll better code in the common subset of C and C++), and the matching

#ifdef __cplusplus
}; // end of extern "C"
#endif

near its end. See also this.

You should wrap all your public header (and perhaps standard C headers included by it) with such things (not only individual functions).

You could compile with gcc -H to list the included headers or g++ -C -E to get the preprocessed form (and examine it).

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I don't understand how is that different of what I mentioned I did? I already added `extern "C"` . – Alaa M. Dec 22 '16 at 07:28