微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Qt静态链接问题:对C ++标准库的未定义引用

如何解决Qt静态链接问题:对C ++标准库的未定义引用

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

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

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

来自C ++ std库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静态库在标准库中找不到对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; 它适用于链接stdlib。

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

显示了另一个错误

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

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

解决方法

尚不清楚在构建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)
,

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

类似以下内容:

target_compile_features(test PUBLIC cxx_std_17)

Here is the list功能

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。