在只读部分“.text”中针对 xxx 进行重定位 - SUSE 中错误的编译器或 linux 设置?

问题描述 投票:0回答:6

我不是 Linux 的常客,我想我做错了什么。

这是我正在生成的测试动态库“.so”的代码。

class InternalClass
{
public:
    int Function(){ return 10; }
};

extern "C"
{
    int WrapperFunctionSimple() { return 10; }
    void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }
}

编译失败,出现以下错误:

g++ -Wall -fexceptions -O2  -c /home/lidia/compartida/TestLibrary/TestLibrary/main.cpp -o obj/Release/main.o
g++ -shared  obj/Release/main.o  -o bin/Release/libTestLibrary.so -s  
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: warning: relocation against `_Znwm@@GLIBCXX_3.4' in read-only section `.text'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: relocation R_X86_64_PC32 against symbol `_Znwm@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

我按照建议尝试使用 -fPIC 并编译。但是当使用这个库时,当我添加最后一个函数时它无法加载:

void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }

问题是使用内部类,没有这个功能一切正常。


我正在使用 VirtualBox。我安装的是OpenSUSE 64bit,使用库的app也是64bit的。在另一个 linux 发行版 (Mint) 中,具有完全相同的项目和设置(没有 fPIC),它可以被编译。当我使用那个库 (.so) 时,它在 SUSE 中工作。

我也在用 :

  • gcc (SUSE Linux) 7.5.0
  • g++ (SUSE Linux) 7.5.0
  • 我的 IDE 是 Code::Blocks 20(最新版本)。除了 -m64 标志外,设置为空。

我做错了什么?这似乎是高级 Linux 用户可以帮助我理解的东西。

编辑: 要添加更多信息,可以在 Ubuntu 中使用相同的设置进行编译。不在 SUSE 中

c++ linux compiler-errors suse dynamic-library
6个回答
7
投票

对我来说这发生了,如果一个库 (A) 依赖于另一个库 (B) 并且库 A 在库 B 之前被链接。解决方案是先链接库 B 然后再链接 A.


5
投票

我在用GCC编译一个CPP文件的时候遇到过。因此,对于 C++ 文件,仅使用 g++,显然不是 GCC,它适用于 c 文件。


1
投票

我在 ubuntu 中使用 cmake 和 GCC,我得到了同样的错误。

在我的例子中,我添加了 XX.h 文件以包含目录,并在我的 main.cpp 中使用了 XX.h 头文件中定义的“typedef struct x”。但是我忘了将 XX.c 添加到可执行源中。

当我在Cmake的add_executable()中将XX.c添加到目标可执行源时,这个错误就被清除了

我希望我能清楚地说明我的情况。


1
投票

在我的例子中,这发生在我有一个抽象类 A 和两个派生类 B 和 C 时,如下所示。

class BaseAbstractClass
{
public:
    virtual void doNothing(void) = 0;
};

class A : public BaseAbstractClass
{
public:
    void doNothing(void){
        return;
    }
};

class B : public BaseAbstractClass
{
public:
    void doNothing(void);    // Only declaration, definition is nowhere
};

但是其中一个派生类(这里是

class B
)只有
doNothing()
的声明,但在项目文件中的任何地方都没有定义。


0
投票

我有一个类似的问题,链接答案的顺序对我很有用。结果是我包含了 cpp 文件而不是标题(include 在错误的时间被调用。)


0
投票

我的项目有这个错误,两个错误消息.

我使用 CMake。在我的

CMakeLists.txt
中,我有这样一段代码:

target_sources(${PROJECT_NAME}
    PUBLIC  ${HEADERS}
    PRIVATE ${SOURCES}
    )

target_link_libraries(${PROJECT_NAME} PRIVATE
   AnotherLib
)

A

.cpp
(在 SOURCES 中提到)是罪魁祸首,它没有被访问。 删除
PRIVATE
解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.