我正在使用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'
如何将我的静态库链接到第三方共享库?
答案 0 :(得分:1)
尚不清楚在构建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)
答案 1 :(得分:1)
设置c ++ 17的另一种方法是除显式设置其属性外,还使用target_compile_features
类似以下内容:
target_compile_features(test PUBLIC cxx_std_17)