【发布时间】:2020-11-10 08:46:52
【问题描述】:
我在构建动态库时遇到了一个相当奇怪的问题。以下是一个小例子的详细信息:
一个名为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 是如何相互关联的?
这里是重现问题的 repo: https://github.com/skgbanga/shared
【问题讨论】:
-
附带说明,
static和shared是有问题的名称...尝试使用其他名称... -
@OrenIshShalom 我使用这些名称认为它们更好地传达了问题的意图。很好奇为什么它们会出现问题?
标签: c++ cmake shared-libraries