linuxlinkerg++static-librariesxdotool

Undefined References After Linking Against Static Library


I wrote a simple program to test if xdotool can fulfill my requirements. (Well, not really. My first step is to make sure if I can make calls into the xdotool library.)

#include <xdo.h>
#include <iostream>

using namespace std;

int main(){
    cout << xdo_version() << endl;
    xdo_new(NULL);
    return 0;
}

However, when I compile this with g++ -o a main.cpp libxdo.a -lXtst -lX11 -lXinerama -I ../test/xdotool-2.20110530.1, I get the following error message:

/tmp/ccW95RQx.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `xdo_version()'
main.cpp:(.text+0x29): undefined reference to `xdo_new(char*)'
collect2: error: ld returned 1 exit status
make: *** [sendkey] Error 1

I didn't use the development packages from apt-get install because it installs a dynamic library. So, I did a apt-get source and built the library myself. I verified that xdo_version and xdo_new are defined functions in the static library by performing the following commands:

$ nm libxdo.a | grep xdo_version
00000000000002b0 T xdo_version
$ nm libxdo.a | grep xdo_new
0000000000004070 T xdo_new
0000000000003c90 T xdo_new_with_opened_display

If I am not mistaken, the T besides the symbol's name means that the function is defined.

In conclusion, I'm trying to get the above C++ snippet to compile successfully and statically linking against xdotool but encountered some errors as stated above.


Solution

  • Hint: if the linker shows the signature of a function, then it knows the signature of that function. What does this mean? It means that it has been somehow encoded in the function name at compilation time, i. e. you are the victim of C++ name mangling.

    It seems that the xdo.h header doesn't contain safeguards for the case when the C code is compiled as C++. Declare the functions as extern "C" manually for yourself, then recompile, and it will work.