【问题标题】:how to remove pthread undefined reference while building single thread library如何在构建单线程库时删除 pthread 未定义的引用
【发布时间】:2024-01-16 03:01:02
【问题描述】:

我收到 pthread API未定义参考,但我不知道如何解决?

这里是场景:

libA.a -- 这是第 3 方库 [它包含许多依赖于 pthread 的 API]

libB.a -- 这是我自己的库。我正在使用少数 3rd 方库的 API [libA.a] 并创建了我自己的库。[我自己在 libB.a 中没有使用任何 pthread API]

我将 libA.a + libB.a + (A + B) 的标头提供给我的客户端 exe。 -- 比如说 MAIN.exe

MAIN.cpp -- 将使用我的库提供的 API。

当我尝试运行 MAIN.exe 时,出现未定义的引用错误。

以下是源代码:

libA.a:只包含A.h和A.cpp

啊.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);
}

创建 libA.a 的命令:

cd /练习/A

g++ -c A.cpp

ar -cvq libA.a *.o

libB.a:只包含B.h和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();
}

创建 libB.a 的命令:

cd /练习/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;
}

创建 main.exe 的命令:

cd /practice/MAIN

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

我得到的错误: ../A/libA.a(A.o):在函数A::printNumber()': A.cpp:(.text+0x8c): undefined reference topthread_create' collect2: ld 返回 1 个退出状态

注意: 我知道,如果我尝试使用 -lrt 标志,它不会给出任何错误。 但问题是我的客户端 [MAIN.cpp] 不能使用 -lrt 标志或 -lpthread 或任何与线程相关的库。因此,他建议我提供单线程库。

那么,如何提供单线程库????

libA.a 是第三方,我无法更改其代码。 libB.a 是我自己的库 [我必须使用来自 libA.a 的 API]

我可以使用任何特定的标志来使 main.cpp 正常运行吗??

另一个疑问:

为什么 Main.cpp 给我错误,即使客户端只调用 线程无关 函数:

    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;
    }

【问题讨论】:

  • 如果你确定没有pthread 代码被你的应用程序的执行路径调用,我想你可以创建虚拟的pthread symbols/calls 并链接到它?
  • @Galik:你能告诉我该怎么做吗?如何创建虚拟 pthread 符号?
  • 只需在您自己的 .cpp 文件中创建 pthread 调用的虚拟版本,该文件包含 libA.a 使用的所有内容,并在您链接程序时包含它。

标签: c++ g++ pthreads static-libraries gnu-make


【解决方案1】:

如果您确定没有实际的 pthread 代码从您的库使用的代码路径中调用,那么您可以尝试制作 ptherad 调用的虚拟版本,如下所示:

DummyPThreads.c(注意 c 不是 c++)

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

void pthread_exit(void*)
{
}

// etc...

编译:

gcc -c -o DummyPThreads.o DummyPThreads.c

添加到您的应用程序:

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

【讨论】:

    【解决方案2】:

    这是不可能的。由于其中一个库依赖于 pthread,因此您需要将该库链接到您的最终可执行文件。

    唯一的选择是从 libA.a 中提取您真正需要的文件,并且它们不依赖于 pthread。但这是一项艰巨的任务,很可能是不可能的,因为通常存在交叉依赖关系,最后但并非最不重要的一点是,如果库发生变化,则非常脆弱。

    【讨论】:

      最近更新 更多