Results 1 to 6 of 6

Thread: Cmake resource file link error

  1. #1
    Join Date
    Jan 2008
    Posts
    20
    Thanks
    1

    Default Cmake resource file link error

    Hi,

    I'm setting up my environment for a C++/Qt Quick application (Windows VS2013 x64) with cmake. I'm having trouble to get a (shared) library be compiled and linked to my executable and using a resource file from it (just a simple qml file to test the setup.

    I have set(CMAKE_AUTOMOC ON) and set(CMAKE_AUTORCC ON) in my root CMakeLists.txt
    The CMakeLists.txt of my shared library is as follows (BEQMLResource.qrc is in the same directory as CMakeLists.txt):

    Qt Code:
    1. cmake_minimum_required(VERSION 3.2)
    2.  
    3. if(UNIX)
    4. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++11")
    5. endif()
    6.  
    7. SET(QT_ROOT_DIR "C:/Qt/5.7/msvc2013_64/")
    8.  
    9. set(QT_QMAKE_EXECUTABLE ${QT_ROOT_DIR}/bin/qmake)
    10.  
    11. find_package(Qt5 COMPONENTS Quick Core Network Widgets Gui Qml Positioning PATHS ${QT_ROOT_DIR})
    12.  
    13. project("BEQML")
    14. set(PROJECT_RESOURCES BEQMLResource.qrc)
    15. qt5_add_resources(BEQML_RESOURCES ${PROJECT_RESOURCES})
    16. file(GLOB BEQML_SRC_LIBRARY
    17. "BEQMLLibrary.h" #contains dll import/export defines for windows.
    18. "BEQMLLibraryInitializer.cpp" #dummy class with some functions so the library is created.
    19. "BEQMLLibraryInitializer.h"
    20. )
    21. source_group("Library" FILES ${BEQML_SRC_LIBRARY})
    22. add_library(BEQML SHARED ${BEQML_SRC_LIBRARY} ${BEQML_RESOURCES})
    23. target_include_directories(BEQML PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../BELibraries/)
    To copy to clipboard, switch view to plain text mode 

    When I compile the library, I get two linker errors in qrc_BEQMLResource.obje (unresolved external symbol for qRegisterResourceData and qUnregisterResourceData).
    Any idea what can be wrong?
    Kind regards,

    Jan

  2. #2
    Join Date
    Jan 2008
    Posts
    20
    Thanks
    1

    Default Re: Cmake resource file link error

    Adding qt5_use_module(BEQML core) solved my first problem. The BEQML library is building without errors, but now I got a link error in my executable project: unresolved external symbol qInitResource_BEQMLResource.
    The CMakeLists.txt from my exe project is as follows:
    Qt Code:
    1. cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
    2.  
    3. if(UNIX)
    4. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++11")
    5. endif()
    6.  
    7. set(CMAKE_INCLUDE_CURRENT_DIR ON)
    8.  
    9. SET(QT_ROOT_DIR "C:/Qt/5.7/msvc2013_64/")
    10.  
    11. set(QT_QMAKE_EXECUTABLE ${QT_ROOT_DIR}/bin/qmake)
    12.  
    13. find_package(Qt5 COMPONENTS Quick Core Network Widgets Gui Qml Positioning PATHS ${QT_ROOT_DIR})
    14.  
    15. project("StormExe")
    16.  
    17. qt5_add_resources(RESOURCES StormExe.qrc)
    18.  
    19. file(GLOB STORMEXE_SRC_QML
    20. "QML/Main.qml"
    21. )
    22. file(GLOB STORMEXE_SRC_EXE
    23. "Main.cpp"
    24. )
    25.  
    26. source_group("Exe" FILES ${STORMEXE_SRC_EXE})
    27. source_group("QML" FILES ${STORMEXE_SRC_QML})
    28.  
    29. add_executable(Storm ${STORMEXE_SRC_EXE} ${RESOURCES} ${STORMEXE_SRC_QML})
    30. qt5_use_modules(Storm Quick Core Network Widgets Gui Qml Positioning)
    31.  
    32. target_link_libraries(Storm BEQML)
    33. target_include_directories(Storm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../BELibraries/)
    To copy to clipboard, switch view to plain text mode 
    In my Main.cpp i have:
    Qt Code:
    1. #include <QApplication>
    2. #include <QQmlApplicationEngine>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication app(argc, argv);
    7.  
    8. Q_INIT_RESOURCE(BEQMLResource);
    9.  
    10. QQmlApplicationEngine engine;
    11. engine.load(QUrl(QStringLiteral("qrc:/Main.qml")));
    12.  
    13. return app.exec();
    14. }
    To copy to clipboard, switch view to plain text mode 
    Do I need to do something special to get access to the resources from the shared library?
    Regards,

    Jan

    Btw, if i build as a static lib, everything works just fine...

  3. #3
    Join Date
    Jan 2008
    Posts
    20
    Thanks
    1

    Default Re: Cmake resource file link error

    Ok, found a workaround by exporting a custom method from the dll which calls the initialisation of the resource like this:

    Qt Code:
    1. int BEQMLLibraryInitializer::init()
    2. {
    3. extern int qInitResources_BEQMLResource();
    4. return qInitResources_BEQMLResource();
    5. }
    To copy to clipboard, switch view to plain text mode 

    Is there a better way to do it?
    Regards,

    Jan

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Cmake resource file link error

    Is there a better way to do it?
    Almost certainly. I've never had to write such code to initialize resources in a DLL. A call with the macro Q_INIT_RESOURCE( MyDll ) after the DLL is loaded has always worked. It appears that there might be something wrong with the way your DLL is built if this symbol isn't defined. Does your QRC file have the same base name as your DLL? (i.e. MyDll.qrc for MyDll.dll) That could very well be the cause of the failure, because compiling a QRC file with another name generates a different symbol name.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jan 2008
    Posts
    20
    Thanks
    1

    Default Re: Cmake resource file link error

    Thanks for the suggestion, that was not the case. Though after changing the name to BEQML.qrc (the dll is called BEQML.dll), I still get the same link error:

    Main.obj : error LNK2019: unresolved external symbol "int __cdecl qInitResources_BEQML(void)" (?qInitResources_BEQML@@YAHXZ) referenced in function main

    Jan

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Cmake resource file link error

    RCC should be generating a qrc_BEQML.cpp file for you. Look for it and compare the last part of it to the comparable file I have for my project (called "Composer"); it should look similar to this:

    Qt Code:
    1. #ifdef QT_NAMESPACE
    2. # define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
    3. # define QT_RCC_MANGLE_NAMESPACE0(x) x
    4. # define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
    5. # define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
    6. # define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
    7. QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
    8. #else
    9. # define QT_RCC_PREPEND_NAMESPACE(name) name
    10. # define QT_RCC_MANGLE_NAMESPACE(name) name
    11. #endif
    12.  
    13. #ifdef QT_NAMESPACE
    14. namespace QT_NAMESPACE {
    15. #endif
    16.  
    17. bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
    18.  
    19. bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
    20.  
    21. #ifdef QT_NAMESPACE
    22. }
    23. #endif
    24.  
    25. int QT_RCC_MANGLE_NAMESPACE(qInitResources_composer)();
    26. int QT_RCC_MANGLE_NAMESPACE(qInitResources_composer)()
    27. {
    28. QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
    29. (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    30. return 1;
    31. }
    32.  
    33. int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_composer)();
    34. int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_composer)()
    35. {
    36. QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
    37. (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
    38. return 1;
    39. }
    40.  
    41. namespace {
    42. struct initializer {
    43. initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_composer)(); }
    44. ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_composer)(); }
    45. } dummy;
    46. }
    To copy to clipboard, switch view to plain text mode 

    It is the struct initializer at the end that's giving rise to your undefined symbol references. Check the Makefile to be sure the command line is generating this code as you expect. There might be something in the CMake commands that is causing something different to occur.

    I suppose the next thing to look at after that is to be sure that the calling convention is indeed __cdecl.
    Last edited by d_stranz; 22nd February 2017 at 19:55.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 3
    Last Post: 19th November 2014, 20:44
  2. SOLVED: CMake link errors (A.K.A .moc handling)
    By pdoria in forum Qt Programming
    Replies: 3
    Last Post: 18th July 2012, 14:38
  3. Replies: 0
    Last Post: 3rd June 2010, 05:54
  4. Replies: 4
    Last Post: 17th February 2010, 11:52
  5. Replies: 1
    Last Post: 27th March 2009, 07:22

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.