1

I am using a Qt static library. I compiled the static version of Qt5.15.1. I wrote my program which links to the Qt static library.

When I compile it, it shows the error:

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

which is from the C++ std library memory_resource header.

The following is the minimal reproducible example:

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)

The linking error while compiling:

[  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

The error shows the Qt static library cannot find the reference to memory_resource in the std library. How could this happen? I have built Qt static library without any problem.

The reason why I have to use static Qt library is that CUDA requires static linking.

update

I have enabled c++17 in CMakeLists.txt

In my project, it is a little different. My project structure is as below:

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

I add mainwindow as a static library, which inherits QWidget class. and main.cpp links mainwindow.

After I add cxx17 standard, the problem still occurs. I am not sure whether it is the problem of mainwindow subdirectory.

update I have updated my 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 ... ...)
...
...

However, it still doesn't works...

UPDATE

I have updated my CMakeLists.txt by adding

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

It links targets to static stdlibc++ and stdlibc; It works for linking stdlib.

Now I have another problem. Since my project is static linking, it need to link to 3rd party shared libs, for example, third_party_lib.so.

It shows another error:

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

How about link my static libs to a 3rd party shared library?

Bart
  • 9,825
  • 5
  • 47
  • 73
fyl
  • 59
  • 7
  • Looks like you're building on linux. If you do the following: `set(CMAKE_EXPORT_COMPILE_COMMANDS ON)` ... what is it explicitly attempting to do? maybe pastebin that file? also paste out your `link.txt` file that is in your `test/CMakeFiles/test.dir/` folder. – g19fanatic Aug 27 '20 at 19:49
  • main.cpp project probably isn't being built w/ c++17 linking... unless you're explicitly static linking the stdlib in your mainwindow project. basically the [-static](https://stackoverflow.com/a/26107550/496405) linking flag – g19fanatic Aug 27 '20 at 19:55
  • Hi, In the `CMakeLists.txt` of `mainwindow` subdirectory, I set `add_library(mainwindow STATIC ${MAINWINDOW_DIR})` explicitly to add `mainwindow` as static library. What should I do to explicitly link my `mainwindow` lib to stdlib in `CMakeLists.txt`? – fyl Aug 27 '20 at 20:02

3 Answers3

1

It's unclear whether or not C++17 was enabled when you built the test executable. At least, I don't see it in your CMake file. You can enable it for that CMake target using the following:

set_target_properties(test PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

The undefined references (such as std::pmr::get_default_resource) are C++17 features, so adding this to your CMake file may resolve the issue.


You could also try setting the C++17 standard globally for your entire CMake project using the following:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Kevin
  • 16,549
  • 8
  • 60
  • 74
  • Hi, it still doesn't work. I have updated the question. I enabled cxx_standard 17, it still cannot find `std::pmr::get_default_resource`. – fyl Aug 27 '20 at 19:47
  • @fyl If you have a larger project, it may be a good idea to try setting these three properties globally in your top-level CMake file; see my updated response. – Kevin Aug 27 '20 at 19:49
  • Hi, I have set them globally after `project(my_proj_name)` in my `CMakeLists.txt`. It still doesn't work. Is it because static linking? – fyl Aug 27 '20 at 20:00
1

Another way to set c++17 besides explicitly setting its properties is to use target_compile_features

Like the following:

target_compile_features(test PUBLIC cxx_std_17)

Here is the list of features

g19fanatic
  • 10,567
  • 6
  • 33
  • 63
  • Hi, I have enabled cxx_standard but it still doesn't work. I have many subdirectories, should I do it for each target? – fyl Aug 27 '20 at 19:48
0

I don't know the cause (didn't investigate deeply), but with C++17 you need to link your code with QtXML component.

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 Xml REQUIRED)

#include_directories(${Qt5Widgets_INCLUDE_DIRS)

add_executable(test ./main.cpp)

target_link_libraries(test Qt5::Widgets Qt5::Xml)