【问题标题】:Qt static linking problem: undefined reference to C++ std libraryQt静态链接问题:对C++标准库的未定义引用
【发布时间】:2020-12-16 17:11:24
【问题描述】:

我正在使用 Qt 静态库。我编译了Qt5.15.1的静态版本。我编写了链接到 Qt 静态库的程序。

当我编译它时,它显示错误:

undefined reference to std::pmr::get_default_resource()

来自 C++ 标准库 memory_resource 标头。

以下是最小的可重现示例:

OS: archlinux
c++ compiler: gcc10
c++ standard: c++17

main.cpp

////main.cpp
#include <QWidget>
#include <QApplication>

int main(int argc, char* argv)
{
    QApplication app;
    QWidget w;
    w.show();
    return app.exec(); 
}

CMakeLists.txt

////CMakeLists.txt
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(test LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt5 COMPONENTS Widgets REQUIRED)
include_directories(${Qt5Widgets_INCLUDE_DIRS)
add_executable(test ./main.cpp)
target_link_libraries(test Qt5::Widgets)

编译时的链接错误:

[  3%] Automatic MOC and UIC for target w
[  3%] Built target w_autogen
[ 50%] Built target w
[ 53%] Automatic MOC and UIC for target test
[ 53%] Built target test_autogen
[ 57%] Linking CXX executable ../bin/test
/usr/bin/ld: /opt/qt_5_15_1_static/lib/libQt5FontDatabaseSupport.a(qfontconfigdatabase.o): in function `QFontconfigDatabase::fallbacksForFamily(QString const&, QFont::Style, QFont::StyleHint, QChar::Script) const':
qfontconfigdatabase.cpp:(.text._ZNK19QFontconfigDatabase18fallbacksForFamilyERK7QStringN5QFont5StyleENS3_9StyleHintEN5QChar6ScriptE+0x1f3): undefined reference to `std::pmr::get_default_resource()'
/usr/bin/ld: qfontconfigdatabase.cpp:(.text._ZNK19QFontconfigDatabase18fallbacksForFamilyERK7QStringN5QFont5StyleENS3_9StyleHintEN5QChar6ScriptE+0x1fa): undefined reference to `vtable for std::pmr::monotonic_buffer_resource'
/usr/bin/ld: qfontconfigdatabase.cpp:(.text._ZNK19QFontconfigDatabase18fallbacksForFamilyERK7QStringN5QFont5StyleENS3_9StyleHintEN5QChar6ScriptE+0x443): undefined reference to `std::pmr::monotonic_buffer_resource::~monotonic_buffer_resource()'
/usr/bin/ld: /opt/qt_5_15_1_static/lib/libQt5Core.a(qstringlist.o): in function `QtPrivate::QStringList_removeDuplicates(QStringList*)':
qstringlist.cpp:(.text._ZN9QtPrivate28QStringList_removeDuplicatesEP11QStringList+0x3c): undefined reference to `std::pmr::get_default_resource()'
/usr/bin/ld: qstringlist.cpp:(.text._ZN9QtPrivate28QStringList_removeDuplicatesEP11QStringList+0x57): undefined reference to `vtable for std::pmr::monotonic_buffer_resource'
/usr/bin/ld: qstringlist.cpp:(.text._ZN9QtPrivate28QStringList_removeDuplicatesEP11QStringList+0x486): undefined reference to `std::pmr::monotonic_buffer_resource::~monotonic_buffer_resource()'
/usr/bin/ld: qstringlist.cpp:(.text._ZN9QtPrivate28QStringList_removeDuplicatesEP11QStringList+0x4c1): undefined reference to `std::pmr::monotonic_buffer_resource::~monotonic_buffer_resource()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:398: ../bin/test] Error 1
make[1]: *** [CMakeFiles/Makefile2:137: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:104: all] Error 2

错误显示 Qt 静态库在 std 库中找不到对 memory_resource 的引用。这怎么可能发生?我已经构建了 Qt 静态库,没有任何问题。

我必须使用静态Qt库的原因是CUDA需要静态链接。

更新

我在 CMakeLists.txt 中启用了 c++17

在我的项目中,它有点不同。 我的项目结构如下:

.
|--include 
|--src
|   |--mainwindow
|   |      |--mainwindow.h
|   |      |--mainwindow.cpp
|   |      |--CMakeLists.txt
|   |
|   |--other
|
|--main.cpp
|--CMakeLists.txt

我将mainwindow 添加为静态库,它继承QWidget 类。和 main.cpp 链接mainwindow

我添加cxx17标准后,问题依旧。 不知道是不是mainwindow子目录的问题。

更新 我已经更新了我的 CMakeLists.txt

//CMakeLists.txt
project(my_proj LANGUAGES CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt5 ... ...)
...
...

但是还是不行……

更新

我通过添加更新了我的 CMakeLists.txt

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static")

它将目标链接到静态 stdlibc++ 和 stdlibc; 它适用于链接标准库。

现在我有另一个问题。由于我的项目是静态链接,所以需要链接到第三方共享库,例如third_party_lib.so

显示另一个错误:

/usr/bin/ld: attempted static link of dynamic object '/usr/local/lib/librealsense2.so.2.30.0'

如何将我的静态库链接到第 3 方共享库?

【问题讨论】:

  • 看起来你是在 linux 上构建的。如果您执行以下操作:set(CMAKE_EXPORT_COMPILE_COMMANDS ON) ... 它明确尝试做什么?也许pastebin那个文件?还要粘贴您的 link.txt 文件,该文件位于您的 test/CMakeFiles/test.dir/ 文件夹中。
  • main.cpp 项目可能没有使用 c++17 链接构建...除非您在主窗口项目中明确静态链接标准库。基本上是-static 链接标志
  • 您好,在mainwindow 子目录的CMakeLists.txt 中,我明确设置add_library(mainwindow STATIC ${MAINWINDOW_DIR})mainwindow 添加为静态库。我应该怎么做才能将我的mainwindow lib 明确链接到CMakeLists.txt 中的stdlib?

标签: c++ qt cmake linker


【解决方案1】:

除了显式设置其属性之外,设置 c++17 的另一种方法是使用target_compile_features

如下:

target_compile_features(test PUBLIC cxx_std_17)

Here is the list 的功能

【讨论】:

  • 您好,我已启用 cxx_standard 但它仍然无法正常工作。我有很多子目录,我应该为每个目标都做吗?
【解决方案2】:

尚不清楚在构建 test 可执行文件时是否启用了 C++17。至少,我在您的 CMake 文件中没有看到它。您可以使用以下命令为该 CMake 目标启用它:

set_target_properties(test PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

未定义的引用(例如 std::pmr::get_default_resource)是 C++17 功能,因此将其添加到您的 CMake 文件可能会解决问题。


您还可以尝试使用以下方法为您的整个 CMake 项目全局设置 C++17 标准:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

【讨论】:

  • 您好,还是不行。我已经更新了这个问题。我启用了cxx_standard 17,它仍然找不到std::pmr::get_default_resource
  • @fyl 如果您有一个较大的项目,最好尝试在您的顶级 CMake 文件中全局设置这三个属性;查看我的更新回复。
  • 嗨,我在CMakeLists.txt 中的project(my_proj_name) 之后全局设置了它们。它仍然不起作用。是因为静态链接吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多