Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Qt 6
  4. Qt 6.2 + CMake + extending QML with a C++ class
Forum Updated to NodeBB v4.3 + New Features

Qt 6.2 + CMake + extending QML with a C++ class

Scheduled Pinned Locked Moved Solved Qt 6
qt6.2c++qmlcmake
21 Posts 3 Posters 6.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V vinci
    16 Jan 2022, 17:03

    @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

    @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

    If your Qt installation is for shared libraries then the backing target will be a shared library (.so or .dll) and the plugin target will be a module library (from CMake's point of view some kind of plugin thingy).

    The backing target can be either shared or static independent of what Qt was compiled with. The plugin is going to be either dynamic or module based on the backing target type.

    Not according to my tests. When I overwrite the implicit behavior of qt_add_qml_module I get a STATIC_LIBRARY CMake target and a *plugin.a output.

    K Offline
    K Offline
    kshegunov
    Moderators
    wrote on 16 Jan 2022, 17:05 last edited by
    #5

    @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

    Not according to my tests. When I overwrite the implicit behavior of qt_add_qml_module I get a STATIC_LIBRARY CMake target and a *plugin.a output.

    Create the backing target with add_library and add the QML module to the existing target.

    Read and abide by the Qt Code of Conduct

    V 1 Reply Last reply 16 Jan 2022, 17:10
    0
    • K kshegunov
      16 Jan 2022, 17:05

      @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

      Not according to my tests. When I overwrite the implicit behavior of qt_add_qml_module I get a STATIC_LIBRARY CMake target and a *plugin.a output.

      Create the backing target with add_library and add the QML module to the existing target.

      V Offline
      V Offline
      vinci
      wrote on 16 Jan 2022, 17:10 last edited by
      #6

      @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

      @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

      Not according to my tests. When I overwrite the implicit behavior of qt_add_qml_module I get a STATIC_LIBRARY CMake target and a *plugin.a output.

      Create the backing target with add_library and add the QML module to the existing target.

      Still static.

      add_library(QmlElement STATIC)
      
      qt_add_qml_module(
        QmlElement
        URI
        QmlElement
        VERSION
        0.0.1
        SOURCES
        qml_element.cpp
        qml_element.hpp)
      
      target_include_directories(QmlElementplugin PUBLIC ./)
      
      K 1 Reply Last reply 16 Jan 2022, 17:11
      0
      • V vinci
        16 Jan 2022, 17:10

        @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

        @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

        Not according to my tests. When I overwrite the implicit behavior of qt_add_qml_module I get a STATIC_LIBRARY CMake target and a *plugin.a output.

        Create the backing target with add_library and add the QML module to the existing target.

        Still static.

        add_library(QmlElement STATIC)
        
        qt_add_qml_module(
          QmlElement
          URI
          QmlElement
          VERSION
          0.0.1
          SOURCES
          qml_element.cpp
          qml_element.hpp)
        
        target_include_directories(QmlElementplugin PUBLIC ./)
        
        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 16 Jan 2022, 17:11 last edited by
        #7

        I must not understand what you're attempting to accomplish then.

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        0
        • V Offline
          V Offline
          vinci
          wrote on 16 Jan 2022, 17:23 last edited by
          #8

          We probably talk past each other. You've said that the "plugin target" is going to be either dynamic or module based.
          Translating that to CMake's target TYPE that would be either SHARED_LIBRARY or MODULE_LIBRARY right?

          Now according to my tests the plugin target which gets created is either of TYPE STATIC_LIBRARY or of MODULE_LIBRARY, but never of TYPE SHARED_LIBRARY.

          K 1 Reply Last reply 16 Jan 2022, 17:25
          0
          • V vinci
            16 Jan 2022, 17:23

            We probably talk past each other. You've said that the "plugin target" is going to be either dynamic or module based.
            Translating that to CMake's target TYPE that would be either SHARED_LIBRARY or MODULE_LIBRARY right?

            Now according to my tests the plugin target which gets created is either of TYPE STATIC_LIBRARY or of MODULE_LIBRARY, but never of TYPE SHARED_LIBRARY.

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 16 Jan 2022, 17:25 last edited by
            #9

            @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

            You've said that the "plugin target" is going to be either dynamic or module based.

            Yes, I misspoke. I meant to write that it's either static or module. If you want to link explicitly as a shared library, then use NO_PLUGIN and link against the backing target directly.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • V Offline
              V Offline
              vinci
              wrote on 16 Jan 2022, 17:27 last edited by
              #10

              Thank you for clearing that up! I really hope there will be more blog posts / tutorials on this in the future.

              K 1 Reply Last reply 16 Jan 2022, 17:33
              0
              • V vinci
                16 Jan 2022, 17:27

                Thank you for clearing that up! I really hope there will be more blog posts / tutorials on this in the future.

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 16 Jan 2022, 17:33 last edited by
                #11

                @vinci said in Qt 6.2 + CMake + extending QML with a C++ class:

                Thank you for clearing that up!

                No problem.

                I really hope there will be more blog posts / tutorials on this in the future.

                There probably will be, I imagine. Take note that if you link explicitly to the backing target without a plugin you must use some symbol from it. (look at the blogpost for the volatile pointer trick).

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • V Offline
                  V Offline
                  vinci
                  wrote on 16 Jan 2022, 18:37 last edited by
                  #12

                  Yes thank you, I'm aware of that.

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    paulmasri
                    wrote on 17 Jan 2022, 12:32 last edited by
                    #13

                    I'm grateful to have some responses to my question, but as a total novice when it comes to CMake, I'm still confused and unable to get something to work. The conversation about backing targets and plugins goes over my head.

                    I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                    From what you've said, I've tried appending the following to my CMakeLists.txt shown above...

                    qt_add_library(People STATIC)
                    target_include_directories(Peopleplugin PUBLIC ./)
                    target_link_libraries(myproject PRIVATE People)
                    

                    This builds fine but I still get "QML module not found" in main.qml.

                    Can you provide a cookie-cutter CMakeLists.txt to get me off and running?

                    K 1 Reply Last reply 17 Jan 2022, 12:43
                    0
                    • P paulmasri
                      17 Jan 2022, 12:32

                      I'm grateful to have some responses to my question, but as a total novice when it comes to CMake, I'm still confused and unable to get something to work. The conversation about backing targets and plugins goes over my head.

                      I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                      From what you've said, I've tried appending the following to my CMakeLists.txt shown above...

                      qt_add_library(People STATIC)
                      target_include_directories(Peopleplugin PUBLIC ./)
                      target_link_libraries(myproject PRIVATE People)
                      

                      This builds fine but I still get "QML module not found" in main.qml.

                      Can you provide a cookie-cutter CMakeLists.txt to get me off and running?

                      K Offline
                      K Offline
                      kshegunov
                      Moderators
                      wrote on 17 Jan 2022, 12:43 last edited by kshegunov
                      #14

                      @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                      I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                      I don't believe so. If you're building a 'bundle-all' executable, you wouldn't need a plugin to begin with. I'd try something like this:

                      qt_add_qml_module(People
                          URI People
                          VERSION 1.0
                          STATIC
                          SOURCES Person.h Person.cpp
                          NO_PLUGIN
                          OUTPUT_TARGETS PEOPLE_DEPS
                      )
                      
                      target_link_library(myproject PRIVATE People ${PEOPLE_DEPS})
                      

                      Also you may need to initialize the resources manually, as static builds are pita to begin with. Personally, I wouldn't do it.

                      PS.
                      Also remove the duplicating source files:

                      qt_add_executable(myproject
                          main.cpp
                          Person.h Person.cpp #< Remove this
                      )
                      

                      Read and abide by the Qt Code of Conduct

                      P 1 Reply Last reply 18 Jan 2022, 12:51
                      0
                      • K kshegunov
                        17 Jan 2022, 12:43

                        @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                        I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                        I don't believe so. If you're building a 'bundle-all' executable, you wouldn't need a plugin to begin with. I'd try something like this:

                        qt_add_qml_module(People
                            URI People
                            VERSION 1.0
                            STATIC
                            SOURCES Person.h Person.cpp
                            NO_PLUGIN
                            OUTPUT_TARGETS PEOPLE_DEPS
                        )
                        
                        target_link_library(myproject PRIVATE People ${PEOPLE_DEPS})
                        

                        Also you may need to initialize the resources manually, as static builds are pita to begin with. Personally, I wouldn't do it.

                        PS.
                        Also remove the duplicating source files:

                        qt_add_executable(myproject
                            main.cpp
                            Person.h Person.cpp #< Remove this
                        )
                        
                        P Offline
                        P Offline
                        paulmasri
                        wrote on 18 Jan 2022, 12:51 last edited by
                        #15

                        @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

                        @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                        I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                        I don't believe so. If you're building a 'bundle-all' executable, you wouldn't need a plugin to begin with.

                        I am building a cross-platform app for deployment to Microsoft Store (UWP for Windows 10) and Apple App Store (for iPad), as well as for manual download to Windows 10.

                        I'd try something like this:
                        ... (code)

                        I've tried this but get 2 build errors. See below for my full CMakeLists.txt file and the errors.

                        Also you may need to initialize the resources manually, as static builds are pita to begin with. Personally, I wouldn't do it.

                        Sorry I didn't understand what you're saying. What do you mean by "initialize the resources manually"? And what is it that you wouldn't do?

                        PS.
                        Also remove the duplicating source files:

                        qt_add_executable(myproject
                            main.cpp
                            Person.h Person.cpp #< Remove this
                        )
                        

                        I want to use this class within C++ too. Surely I need to keep retain this line in this case?

                        Here is my CMakeLists.txt file now:

                        cmake_minimum_required(VERSION 3.16)
                        
                        project(myproject VERSION 0.1 LANGUAGES CXX)
                        
                        set(CMAKE_AUTOMOC ON)
                        set(CMAKE_CXX_STANDARD_REQUIRED ON)
                        
                        find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
                        
                        qt_add_executable(myproject
                            main.cpp
                        )
                        
                        qt_add_qml_module(myproject
                            URI myproject
                            VERSION 1.0
                            QML_FILES main.qml
                        )
                        qt_add_qml_module(People
                            URI People
                            VERSION 1.0
                            STATIC
                            SOURCES Person.h Person.cpp
                            NO_PLUGIN
                            OUTPUT_TARGETS PEOPLE_DEPS
                        )
                        
                        target_compile_definitions(myproject
                            PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                        target_link_libraries(myproject PRIVATE Qt6::Quick)
                        target_link_libraries(myproject PRIVATE People ${PEOPLE_DEPS})
                        

                        And these are the errors I get:

                        [ 96%] Linking CXX executable myproject
                        duplicate symbol 'qInitResources_qmake_People()' in:
                            CMakeFiles/People_resources_1.dir/.rcc/qrc_qmake_People.cpp.o
                        duplicate symbol 'qCleanupResources_qmake_People()' in:
                            CMakeFiles/People_resources_1.dir/.rcc/qrc_qmake_People.cpp.o
                        ld: 2 duplicate symbols for architecture arm64
                        clang: error: linker command failed with exit code 1 (use -v to see invocation)
                        make[2]: *** [myproject] Error 1
                        make[1]: *** [CMakeFiles/myproject.dir/all] Error 2
                        make: *** [all] Error 2
                        
                        K 1 Reply Last reply 18 Jan 2022, 13:59
                        0
                        • P paulmasri
                          18 Jan 2022, 12:51

                          @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

                          @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                          I am building a standalone app (executable), so I think that what I'm after is a statically linked plugin.

                          I don't believe so. If you're building a 'bundle-all' executable, you wouldn't need a plugin to begin with.

                          I am building a cross-platform app for deployment to Microsoft Store (UWP for Windows 10) and Apple App Store (for iPad), as well as for manual download to Windows 10.

                          I'd try something like this:
                          ... (code)

                          I've tried this but get 2 build errors. See below for my full CMakeLists.txt file and the errors.

                          Also you may need to initialize the resources manually, as static builds are pita to begin with. Personally, I wouldn't do it.

                          Sorry I didn't understand what you're saying. What do you mean by "initialize the resources manually"? And what is it that you wouldn't do?

                          PS.
                          Also remove the duplicating source files:

                          qt_add_executable(myproject
                              main.cpp
                              Person.h Person.cpp #< Remove this
                          )
                          

                          I want to use this class within C++ too. Surely I need to keep retain this line in this case?

                          Here is my CMakeLists.txt file now:

                          cmake_minimum_required(VERSION 3.16)
                          
                          project(myproject VERSION 0.1 LANGUAGES CXX)
                          
                          set(CMAKE_AUTOMOC ON)
                          set(CMAKE_CXX_STANDARD_REQUIRED ON)
                          
                          find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
                          
                          qt_add_executable(myproject
                              main.cpp
                          )
                          
                          qt_add_qml_module(myproject
                              URI myproject
                              VERSION 1.0
                              QML_FILES main.qml
                          )
                          qt_add_qml_module(People
                              URI People
                              VERSION 1.0
                              STATIC
                              SOURCES Person.h Person.cpp
                              NO_PLUGIN
                              OUTPUT_TARGETS PEOPLE_DEPS
                          )
                          
                          target_compile_definitions(myproject
                              PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                          target_link_libraries(myproject PRIVATE Qt6::Quick)
                          target_link_libraries(myproject PRIVATE People ${PEOPLE_DEPS})
                          

                          And these are the errors I get:

                          [ 96%] Linking CXX executable myproject
                          duplicate symbol 'qInitResources_qmake_People()' in:
                              CMakeFiles/People_resources_1.dir/.rcc/qrc_qmake_People.cpp.o
                          duplicate symbol 'qCleanupResources_qmake_People()' in:
                              CMakeFiles/People_resources_1.dir/.rcc/qrc_qmake_People.cpp.o
                          ld: 2 duplicate symbols for architecture arm64
                          clang: error: linker command failed with exit code 1 (use -v to see invocation)
                          make[2]: *** [myproject] Error 1
                          make[1]: *** [CMakeFiles/myproject.dir/all] Error 2
                          make: *** [all] Error 2
                          
                          K Offline
                          K Offline
                          kshegunov
                          Moderators
                          wrote on 18 Jan 2022, 13:59 last edited by kshegunov
                          #16

                          @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                          I am building a cross-platform app for deployment to Microsoft Store (UWP for Windows 10) and Apple App Store (for iPad), as well as for manual download to Windows 10.

                          To my knowledge none of these require static linking.

                          I've tried this but get 2 build errors. See below for my full CMakeLists.txt file and the errors.

                          These are link errors, look below for the explanation.

                          Sorry I didn't understand what you're saying. What do you mean by "initialize the resources manually"?

                          Look here:
                          https://doc.qt.io/qt-6/resources.html#explicit-loading-and-unloading-of-embedded-resources

                          And what is it that you wouldn't do?

                          I wouldn't go for statically linking unless I have a really good reason.

                          I want to use this class within C++ too. Surely I need to keep retain this line in this case?

                          Then, you need to setup the backing target properly to provide the headers. Look below for more.

                          And these are the errors I get ...

                          I guess that's my fault, link the PEOPLE_DEPS that already should include the needed dependencies and linking People explicitly leads to the symbol duplication.
                          Example below (not tested, but should work with a bit of tweaking if necessary):

                          ...
                          qt_add_executable(myproject
                              main.cpp
                          )
                          
                          qt_add_qml_module(myproject
                              URI myproject
                              VERSION 1.0
                              QML_FILES main.qml
                          )
                          
                          qt_add_qml_module(People
                              URI People
                              VERSION 1.0
                              STATIC
                              SOURCES
                                   Person.h
                                   Person.cpp
                              NO_PLUGIN
                              OUTPUT_TARGETS PEOPLE_DEPS
                          )
                          
                          target_include_directories(People
                               PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                          )
                          
                          
                          target_compile_definitions(myproject
                              PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                          target_link_libraries(myproject
                              PRIVATE Qt6::Quick ${PEOPLE_DEPS}
                          )
                          

                          You may need to do the volatile pointer trick from the blog post as well.

                          Read and abide by the Qt Code of Conduct

                          P 1 Reply Last reply 18 Jan 2022, 19:50
                          1
                          • K kshegunov
                            18 Jan 2022, 13:59

                            @paulmasri said in Qt 6.2 + CMake + extending QML with a C++ class:

                            I am building a cross-platform app for deployment to Microsoft Store (UWP for Windows 10) and Apple App Store (for iPad), as well as for manual download to Windows 10.

                            To my knowledge none of these require static linking.

                            I've tried this but get 2 build errors. See below for my full CMakeLists.txt file and the errors.

                            These are link errors, look below for the explanation.

                            Sorry I didn't understand what you're saying. What do you mean by "initialize the resources manually"?

                            Look here:
                            https://doc.qt.io/qt-6/resources.html#explicit-loading-and-unloading-of-embedded-resources

                            And what is it that you wouldn't do?

                            I wouldn't go for statically linking unless I have a really good reason.

                            I want to use this class within C++ too. Surely I need to keep retain this line in this case?

                            Then, you need to setup the backing target properly to provide the headers. Look below for more.

                            And these are the errors I get ...

                            I guess that's my fault, link the PEOPLE_DEPS that already should include the needed dependencies and linking People explicitly leads to the symbol duplication.
                            Example below (not tested, but should work with a bit of tweaking if necessary):

                            ...
                            qt_add_executable(myproject
                                main.cpp
                            )
                            
                            qt_add_qml_module(myproject
                                URI myproject
                                VERSION 1.0
                                QML_FILES main.qml
                            )
                            
                            qt_add_qml_module(People
                                URI People
                                VERSION 1.0
                                STATIC
                                SOURCES
                                     Person.h
                                     Person.cpp
                                NO_PLUGIN
                                OUTPUT_TARGETS PEOPLE_DEPS
                            )
                            
                            target_include_directories(People
                                 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                            )
                            
                            
                            target_compile_definitions(myproject
                                PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                            target_link_libraries(myproject
                                PRIVATE Qt6::Quick ${PEOPLE_DEPS}
                            )
                            

                            You may need to do the volatile pointer trick from the blog post as well.

                            P Offline
                            P Offline
                            paulmasri
                            wrote on 18 Jan 2022, 19:50 last edited by
                            #17

                            @kshegunov said in Qt 6.2 + CMake + extending QML with a C++ class:

                            Look here:
                            https://doc.qt.io/qt-6/resources.html#explicit-loading-and-unloading-of-embedded-resources

                            Thanks!

                            Then, you need to setup the backing target properly to provide the headers. Look below for more.

                            So... if I understand right, the instruction starting qt_add_qml_module(People,...) is where I'm setting up the backing target for People. Is that right? And by including the .h & .cpp sources here, they should become available to C++?

                            Example below (not tested, but should work with a bit of tweaking if necessary):

                            Some forward progress...

                            • Build & link works fine, no errors.
                            • After closing and reopening the project, main.qml stopped complaining about import People and is now recognising and formatting Person correctly.
                            • However when I run the application, it fails with:
                            QQmlApplicationEngine failed to load component
                            qrc:/myproject/main.qml:2:1: module "People" is not installed
                            

                            Any ideas? Do I somehow need to link People to main.qml in the CMake?

                            (Also, you refer to volatile pointers. Even if it's not relevant here, that's something I should read up on. Which blog article were you referring to?)

                            1 Reply Last reply
                            0
                            • P Offline
                              P Offline
                              paulmasri
                              wrote on 18 Jan 2022, 21:59 last edited by
                              #18

                              OK... with a bit of fiddling, I've got something that builds & links, shows no errors in main.qml and runs without error.

                              As I don't honestly have a clue about CMake yet, this may technically have problems or cause me problems down the road — do let me know if that looks likely — but it does appear to work properly and it lets me progress with coding.

                              Below is the complete CMakeLists.txt.

                              For the benefit of others finding this thread, I've made some subtle alterations that help distinguish between what is a target and what's a URI:

                              • Folder structure is:
                                • Parent folder MyProject
                                • Files CMakeLists.txt, main.cpp, main.qml, Person.h, Person.cpp all sit in this folder
                              • The project is MyProject
                              • The executable that is generated (the target) is appMyProject
                              • The class Person becomes target Peopleplugin with URI People (accessed in QML via import People)
                              • Within Qt Creator a virtual folder structure is autogenerated with main.cpp & main.qml in virtual folder appMyProject; and Person.h & Person.cpp in virtual folder Peopleplugin
                              • Following any changes, to be sure of a good build, delete the build folder and close QML files. Then make changes to CMakeLists.txt, build and then you can open QML files.

                              CMakeLists.txt

                              cmake_minimum_required(VERSION 3.16)
                              
                              project(MyProject VERSION 0.1 LANGUAGES CXX)
                              
                              set(CMAKE_AUTOMOC ON)
                              set(CMAKE_CXX_STANDARD_REQUIRED ON)
                              
                              find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
                              
                              qt_add_executable(appMyProject
                                  main.cpp
                              )
                              
                              qt_add_qml_module(appMyProject
                                  URI MyProject
                                  VERSION 1.0
                                  QML_FILES main.qml
                              )
                              qt_add_qml_module(Peopleplugin
                                  URI People
                                  VERSION 1.0
                                  SOURCES Person.h Person.cpp
                              )
                              
                              target_include_directories(Peopleplugin
                                   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                              )
                              
                              target_compile_definitions(appMyProject
                                  PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                              target_link_libraries(appMyProject
                                  PRIVATE Qt6::Quick Peopleplugin)
                              

                              I took out the STATIC, NO_PLUGIN & OUTPUT_TARGETS and instead let it create a plugin called Peopleplugin.

                              I think the key changes from when I posted the original question are:

                              • Change qt_add_qml_module(People URI People... to qt_add_qml_module(Peopleplugin URI People...
                              • Add target_include_directories(Peopleplugin PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
                              • Add Peopleplugin to the list within target_link_libraries(... PRIVATE...)

                              Thoughts & comments welcome.

                              K 1 Reply Last reply 19 Jan 2022, 05:53
                              0
                              • P paulmasri
                                18 Jan 2022, 21:59

                                OK... with a bit of fiddling, I've got something that builds & links, shows no errors in main.qml and runs without error.

                                As I don't honestly have a clue about CMake yet, this may technically have problems or cause me problems down the road — do let me know if that looks likely — but it does appear to work properly and it lets me progress with coding.

                                Below is the complete CMakeLists.txt.

                                For the benefit of others finding this thread, I've made some subtle alterations that help distinguish between what is a target and what's a URI:

                                • Folder structure is:
                                  • Parent folder MyProject
                                  • Files CMakeLists.txt, main.cpp, main.qml, Person.h, Person.cpp all sit in this folder
                                • The project is MyProject
                                • The executable that is generated (the target) is appMyProject
                                • The class Person becomes target Peopleplugin with URI People (accessed in QML via import People)
                                • Within Qt Creator a virtual folder structure is autogenerated with main.cpp & main.qml in virtual folder appMyProject; and Person.h & Person.cpp in virtual folder Peopleplugin
                                • Following any changes, to be sure of a good build, delete the build folder and close QML files. Then make changes to CMakeLists.txt, build and then you can open QML files.

                                CMakeLists.txt

                                cmake_minimum_required(VERSION 3.16)
                                
                                project(MyProject VERSION 0.1 LANGUAGES CXX)
                                
                                set(CMAKE_AUTOMOC ON)
                                set(CMAKE_CXX_STANDARD_REQUIRED ON)
                                
                                find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
                                
                                qt_add_executable(appMyProject
                                    main.cpp
                                )
                                
                                qt_add_qml_module(appMyProject
                                    URI MyProject
                                    VERSION 1.0
                                    QML_FILES main.qml
                                )
                                qt_add_qml_module(Peopleplugin
                                    URI People
                                    VERSION 1.0
                                    SOURCES Person.h Person.cpp
                                )
                                
                                target_include_directories(Peopleplugin
                                     PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                                )
                                
                                target_compile_definitions(appMyProject
                                    PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                                target_link_libraries(appMyProject
                                    PRIVATE Qt6::Quick Peopleplugin)
                                

                                I took out the STATIC, NO_PLUGIN & OUTPUT_TARGETS and instead let it create a plugin called Peopleplugin.

                                I think the key changes from when I posted the original question are:

                                • Change qt_add_qml_module(People URI People... to qt_add_qml_module(Peopleplugin URI People...
                                • Add target_include_directories(Peopleplugin PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
                                • Add Peopleplugin to the list within target_link_libraries(... PRIVATE...)

                                Thoughts & comments welcome.

                                K Offline
                                K Offline
                                kshegunov
                                Moderators
                                wrote on 19 Jan 2022, 05:53 last edited by kshegunov
                                #19

                                Yes, looks correct, although I'd say use qt_add_qml_module(People ...
                                The cmake function already creates a plugin for you (as you'd removed the NO_PLUGIN and that binary is going to be called Peoplepuginplugin - e.g. libPeoplepluginplugin.so, which is somewhat confusing).

                                So... if I understand right, the instruction starting qt_add_qml_module(People,...) is where I'm setting up the backing target for People. Is that right? And by including the .h & .cpp sources here, they should become available to C++?

                                Yes. Although as usual those headers must be supplied to the consuming target (myproject), whence the target_include_directories)

                                Which blog article were you referring to?

                                It was mentioned somewhere above, I belive: https://www.qt.io/blog/qml-modules-in-qt-6.2

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                0
                                • P Offline
                                  P Offline
                                  paulmasri
                                  wrote on 19 Jan 2022, 11:18 last edited by
                                  #20

                                  Thanks. I've changed qt_add_qml_module(Peopleplugin... to qt_add_qml_module(People... and correspondingly Peopleplugin to People in the target_link_libraries() and can confirm that this all works well.

                                  Thanks for all your help!

                                  1 Reply Last reply
                                  0
                                  • P Offline
                                    P Offline
                                    paulmasri
                                    wrote on 19 Jan 2022, 12:25 last edited by
                                    #21

                                    So for clarity for anyone with the same question, the following CMakeLists.txt makes the class Person available to QML via import People, by packaging it behind the scenes as Peopleplugin.

                                    cmake_minimum_required(VERSION 3.16)
                                    
                                    project(MyProject VERSION 0.1 LANGUAGES CXX)
                                    
                                    set(CMAKE_AUTOMOC ON)
                                    set(CMAKE_CXX_STANDARD_REQUIRED ON)
                                    
                                    find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
                                    
                                    qt_add_executable(appMyProject
                                        main.cpp
                                    )
                                    
                                    qt_add_qml_module(appMyProject
                                        URI MyProject
                                        VERSION 1.0
                                        QML_FILES main.qml
                                    )
                                    qt_add_qml_module(People
                                        URI People
                                        VERSION 1.0
                                        SOURCES Person.h Person.cpp
                                    )
                                    
                                    target_include_directories(Peopleplugin
                                         PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                                    )
                                    
                                    target_compile_definitions(appMyProject
                                        PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
                                    target_link_libraries(appMyProject
                                        PRIVATE Qt6::Quick People)
                                    

                                    and for those eagle-eyed, main.qml was buggy and should be:

                                    import QtQuick
                                    import People
                                    
                                    Window {
                                        width: 640
                                        height: 480
                                        visible: true
                                    
                                        Text {
                                            text: personBob.name + " wears size " + personBob.shoeSize + " shoes."
                                        }
                                    
                                        Person {
                                            id: personBob
                                            name: "Bob Jones"
                                            shoeSize: 12
                                        }
                                    }
                                    

                                    The C++ class Person is derived from QObject:

                                    #include <QObject>
                                    #include <QtQml/qqml.h>
                                    
                                    class Person : public QObject
                                    {
                                        Q_OBJECT
                                        Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
                                        Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize NOTIFY shoeSizeChanged)
                                        QML_ELEMENT
                                    ...
                                    

                                    main.cpp is as autogenerated when creating a new Qt Quick 6.2 project in Qt Creator and makes no mention of Person or the People plugin.

                                    Other C++ classes can #include "Person.h" and make use of the Person class.

                                    1 Reply Last reply
                                    2

                                    14/21

                                    17 Jan 2022, 12:43

                                    • Login

                                    • Login or register to search.
                                    14 out of 21
                                    • First post
                                      14/21
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved