fno异常和POSITION INDEPENDENT CODE的交互作用



我在构建动态库时遇到了一个相当奇怪的问题。下面是一个小例子的细节:

一个名为static.h的简单文件,其内容为:

#pragma once
#include <string>
std::string static_speak();

static.cpp看起来像这样:

#include "static.h"
std::string static_speak() {
return "I am static";
}

可以使用以下两个文件(使用cmake(构建一个静态库:

add_library(static
static.cpp
)

现在,考虑另一个名为shared.cpp的文件,其内容为:

#include "static.h"
std::string dynamic_speak() {
return static_speak() + " I am dynamic";
}

可以尝试构建一个动态库(再次使用cmake(作为:

add_library(shared SHARED
shared.cpp
)
target_link_libraries(shared PRIVATE
static
)

当一个人试图构建以上内容时,会遇到以下错误:

[4/4] Linking CXX shared library libshared.so
FAILED: libshared.so
: && /opt/vatic/bin/clang++ -fPIC -g   -shared -Wl,-soname,libshared.so -o libshared.so CMakeFiles/shared.dir/shared.cpp.o  libstatic.a && :                                 
/usr/bin/ld: libstatic.a(static.cpp.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC                    
/usr/bin/ld: final link failed: Nonrepresentable section on output
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

这是有道理的。我们没有用POSITION_INDEPENDENT_CODE编译static。这很容易通过解决

add_library(static
static.cpp
)
set_target_properties(static
PROPERTIES
POSITION_INDEPENDENT_CODE ON
)

现在编译shared库时,一切都很完美。

现在问题来了。假设我没有启用POSITION_INDEPENDENT_CODE,而是将代码中的异常(!(禁用为:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")

现在,当我尝试编译shared时,一切仍然有效!!异常和fPIC是如何相互关联的?

以下是重现该问题的回购:https://github.com/skgbanga/shared

异常和fPIC是如何相互关联的?

它们(大部分(不是。

使用-fno-exceptions进行编译会更改重新定位(某些与异常相关的数据不再被引用(,因此,在链接时不会发生导致错误的重新定位。

您可以通过使用和不使用-fno-exceptions构建并比较objdump -dr CMakeFiles/static.dir/static.cpp.o的输出来确认这一点。

附言:我无法使用g++ (Debian 9.3.0-8)重现您的问题,因为它默认使用-fPIE构建,并且两个链接都成功了。

如果我添加-fno-pie,那么两个链接的失败方式相同。

最新更新