2
votes

I am getting undefined reference for pthread API's and I don't know how to resolve them?

Here is the scenario:

libA.a -- this is 3rd party library [it contains lots of API's which are pthread dependent]

libB.a -- This is my own library. I am using few API's of 3rd party library[libA.a] and created my own library.[I myself havn't used any pthread API in libB.a]

I am giving libA.a + libB.a + headers of (A + B) to my client exe. -- say MAIN.exe

MAIN.cpp -- will be using API's provided by my library.

When, I am trying to run MAIN.exe, I am getting undefined reference errors.

Below is the source code:

libA.a: It only contains A.h and A.cpp

A.h

class A { public: void dispA(); void printNumber(); };

A.cpp:

#include "iostream"
#include "A.h"
#include<stdlib.h>
#include "pthread.h"
using namespace std;

void* printNum(void*)
{
    sleep(1);

    for(int i = 1; i<= 10; i++)
    {
       cout<<"i: "<<i<<endl;
    }
    pthread_exit(NULL);
    return NULL;
}
void A::dispA()
{
    cout<<"A::disp()"<<endl;
}
void A::printNumber()
{
    pthread_t t1;
    pthread_create(&t1, NULL, &printNum, NULL);
    pthread_exit(NULL);
}

Command to create libA.a:

cd /practise/A

g++ -c A.cpp

ar -cvq libA.a *.o

libB.a: It only contains B.h and B.cpp

B.h:

class B
{
public:
    void funB();
    void dispB();
};

B.cpp:

#include "B.h"
#include "iostream"
#include "A.h"
using namespace std;

void B::funB()
{
    cout<<"B::funB()"<<endl;
}

void B::dispB()
{
    A a;
    a.dispA();
    a.printNumber();
}

Command to create libB.a:

cd /practise/B

g++ -c B.cpp -I../A

ar -cvq libB.a *.o

Main.cpp:

#include "iostream"
#include "B.h"
using namespace std;

int main()
{
    B b;
    b.dispB();
    b.funB(); 
    return 0;
}

Command to create main.exe:

cd /practise/MAIN

g++ -o noThread MAIN.cpp -I../A -I../B -L../A -L../B -lB -lA

Error I am getting: ../A/libA.a(A.o): In function A::printNumber()': A.cpp:(.text+0x8c): undefined reference topthread_create' collect2: ld returned 1 exit status

NOTE: I know, if I try to use -lrt flag, it will not give any error. But the problem is that my client [MAIN.cpp] cannot use -lrt flag or -lpthread or any thread related library. and hence, he has suggested me to provide SINGLE THREAD LIBRARY.

So, How to provide SINGLE THREAD LIBRARY ????

libA.a is third party and I cant change its code. libB.a is my own library [and I have to use API's from libA.a]

Is there any specific flag which I can use to make main.cpp run properly??

Another Doubt:

Why Main.cpp is giving me error, even when client is only calling thread independent function :

    int main()
    {
        B b;
        //b.dispB(); <== commented thread dependent function
        b.funB(); <== this doesn't depend on pthread. but still main.cpp is failing. Don't know WHY !!
        return 0;
    }
2
If you're certain that no pthread code gets called by your application's execution path then, I suppose` you could create dummy pthread symbols/calls` and link against that? - Galik
@Galik: Can you tell me how to do what you're saying? How to create dummy pthread symbols ? - Jatin
Just make dummy versions of the pthread calls in your own .cpp file of everything libA.a uses and include that when you link your program. - Galik

2 Answers

1
votes

If you are certain no actual pthread code gets called from the code path your library uses then you could try making dummy versions of the ptherad calls like this:

DummyPThreads.c (note c not c++)

int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void *), void*)
{
    return 0;
}

void pthread_exit(void*)
{
}

// etc...

Compile with:

gcc -c -o DummyPThreads.o DummyPThreads.c

Add to your application:

g++ -o noThread MAIN.cpp -I../A -I../B DummyPThreads.o -L../A -L../B -lB -lA
0
votes

It's not possible. As one of the libraries depend on pthread, you need to link the library to your final executable.

The only option would be to extract the files from libA.a which you really need and they don't depend on pthread. But quite tough task to do, most probably not possible as there are usually cross dependencies and last but not least, highly fragile if the library change for example.