Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. (reopened) using subdirectories in a CMake project
Forum Updated to NodeBB v4.3 + New Features

(reopened) using subdirectories in a CMake project

Scheduled Pinned Locked Moved Solved QML and Qt Quick
22 Posts 3 Posters 5.7k Views 3 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.
  • JKSHJ JKSH

    @mzimmers said in using subdirectories in a CMake project:

    for now, let's assume a directory with a few qml files: A.qml, B.qml, C.qml.

    And also assuming that...

    • You're using a non-EOL version of Qt 6
    • Your top-level project already uses Qt Quick

    ...then your subdirectory's CMakeLists.txt should look like this:

    cmake_minimum_required(VERSION 3.16)
    project(custom)
    qt_add_qml_module(custom
        URI custom
        VERSION 1.0
        QML_FILES A.qml B.qml C.qml
        STATIC
    )
    

    And your top-level CMakeLists.txt should contain these lines:

    add_subdirectory(custom)
    target_link_libraries(appMyApp       # Replace "appMyApp" with the name you passed to qt_add_executable()
        PRIVATE Qt6::Quick customplugin
    )
    

    And your top-level *.qml file should contain import custom (i.e. you import the URI specified in qt_add_qml_module())

    mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #5

    @JKSH said in using subdirectories in a CMake project:

    PRIVATE Qt6::Quick customplugin

    why "customplugin" and not just "custom?"

    JKSHJ 1 Reply Last reply
    1
    • mzimmersM mzimmers

      @JKSH said in using subdirectories in a CMake project:

      PRIVATE Qt6::Quick customplugin

      why "customplugin" and not just "custom?"

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by JKSH
      #6

      @mzimmers said in using subdirectories in a CMake project:

      why "customplugin" and not just "custom?"

      Because that's the default name generated for the plugin library (e.g. customplugin.lib)

      You can change the name if you want by setting the PLUGIN_TARGET argument (see https://doc.qt.io/qt-6/qt-add-qml-module.html ), but I'm not convinced you should spend that effort.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      mzimmersM 1 Reply Last reply
      2
      • JKSHJ JKSH

        @mzimmers said in using subdirectories in a CMake project:

        why "customplugin" and not just "custom?"

        Because that's the default name generated for the plugin library (e.g. customplugin.lib)

        You can change the name if you want by setting the PLUGIN_TARGET argument (see https://doc.qt.io/qt-6/qt-add-qml-module.html ), but I'm not convinced you should spend that effort.

        mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by JKSH
        #7

        @JKSH OK, but it appears I need to do a little more here. What do I have to do in order to use:

        Item {
           A {}
           B {}
           C {}
        }
        

        In my QML code?

        JKSHJ 1 Reply Last reply
        0
        • mzimmersM mzimmers

          @JKSH OK, but it appears I need to do a little more here. What do I have to do in order to use:

          Item {
             A {}
             B {}
             C {}
          }
          

          In my QML code?

          JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #8

          @mzimmers said in using subdirectories in a CMake project:

          @JKSH OK, but it appears I need to do a little more here. What do I have to do in order to use:

          Item {
             A {}
             B {}
             C {}
          }
          

          In my QML code?

          Your top-level *.qml file should contain import custom (i.e. you import the URI specified in qt_add_qml_module()). I've updated my earlier post to include this now.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          1
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #9

            Thanks...that seems to work. So...is this a true plugin? I'm actually generating an .a file, which surprises me, as this is a Windows project, in my build directory. I notice that you included the "STATIC" keyword in your solution above. So, it this now a static library, meaning I don't need to include it in any package that I would deliver?

            JKSHJ kshegunovK 2 Replies Last reply
            0
            • mzimmersM mzimmers

              Thanks...that seems to work. So...is this a true plugin? I'm actually generating an .a file, which surprises me, as this is a Windows project, in my build directory. I notice that you included the "STATIC" keyword in your solution above. So, it this now a static library, meaning I don't need to include it in any package that I would deliver?

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by JKSH
              #10

              @mzimmers said in using subdirectories in a CMake project:

              Thanks...that seems to work.

              Great!

              So...is this a true plugin?

              Depends on how you define a "true plugin".

              This is built as a standalone library first, and then linked to your main application later. But you usually won't even notice, since it's all done as part of the same build process.

              If you want to read about the fine details, see https://www.qt.io/blog/introduction-to-the-qml-cmake-api

              I'm actually generating an .a file, which surprises me, as this is a Windows project, in my build directory.

              Sounds like you're using MinGW? It uses GCC, so it follows the same conventions as Linux.

              MSVC will generate a .lib file instead.

              I notice that you included the "STATIC" keyword in your solution above. So, it this now a static library, meaning I don't need to include it in any package that I would deliver?

              That's right.

              If you specify "DYNAMIC" instead of "STATIC", you would need to deploy an extra DLL.

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              1
              • mzimmersM mzimmers

                Thanks...that seems to work. So...is this a true plugin? I'm actually generating an .a file, which surprises me, as this is a Windows project, in my build directory. I notice that you included the "STATIC" keyword in your solution above. So, it this now a static library, meaning I don't need to include it in any package that I would deliver?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #11

                @mzimmers said in using subdirectories in a CMake project:

                So...is this a true plugin?

                Yes. If you dig a bit deeper, you'll find the type registration code that's generated by the build chain (I think it was the moc that does it). It's a function stub that's (usually) called automatically for you, however if you're doing weird stuffâ„¢ (as I like to do) then you may need to do manual labor for it to get called.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #12

                  Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added. In this example, we're creating (and linking) a static library, which to my novice mind doesn't seem very much like a plugin.

                  JKSHJ kshegunovK 2 Replies Last reply
                  0
                  • mzimmersM mzimmers

                    Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added. In this example, we're creating (and linking) a static library, which to my novice mind doesn't seem very much like a plugin.

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #13

                    @mzimmers said in using subdirectories in a CMake project:

                    Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added.

                    That's why I said in my previous post: Depends on how you define a "true plugin".

                    This is definitely implemented using the plugin interface, but it doesn't "feel" like a plugin. The host program does load the plugin code at runtime even though even though the plugin library is statically-linked.

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added. In this example, we're creating (and linking) a static library, which to my novice mind doesn't seem very much like a plugin.

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #14

                      @mzimmers said in using subdirectories in a CMake project:

                      Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added. In this example, we're creating (and linking) a static library, which to my novice mind doesn't seem very much like a plugin.

                      To elaborate a bit more. Yes, but that's because you chose to build statically. I believe the recommended way is to stick to dynamic QML modules still. In any case, you can have static plugins, it's not unheard of, it's just somewhat unusual - think Qt's image formats for example. If you build Qt statically these are linked in statically as well (and they need to be initialized separately, in Qt5 times you also did this manually).
                      https://doc.qt.io/qt-6/plugins-howto.html#static-plugins
                      https://doc.qt.io/qt-6/qtplugin.html#Q_IMPORT_PLUGIN

                      Read and abide by the Qt Code of Conduct

                      JKSHJ 1 Reply Last reply
                      0
                      • kshegunovK kshegunov

                        @mzimmers said in using subdirectories in a CMake project:

                        Interesting...I always thought a plug-in was something available separately, that the host program wouldn't even know of until it was added. In this example, we're creating (and linking) a static library, which to my novice mind doesn't seem very much like a plugin.

                        To elaborate a bit more. Yes, but that's because you chose to build statically. I believe the recommended way is to stick to dynamic QML modules still. In any case, you can have static plugins, it's not unheard of, it's just somewhat unusual - think Qt's image formats for example. If you build Qt statically these are linked in statically as well (and they need to be initialized separately, in Qt5 times you also did this manually).
                        https://doc.qt.io/qt-6/plugins-howto.html#static-plugins
                        https://doc.qt.io/qt-6/qtplugin.html#Q_IMPORT_PLUGIN

                        JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #15

                        @kshegunov said in using subdirectories in a CMake project:

                        I believe the recommended way is to stick to dynamic QML modules still.

                        I haven't seen an official recommendation on this. Got a link?

                        Anyway, I recommended a static plugin in this case because @mzimmers's goal is to organize his QML code into subfolders.

                        • Qt 5 way: Manually write a qmldir file and stick the *.qml + qmldir files inside a QRC resource to be embedded into the main app
                        • Qt 6 way: Let qt_add_qml_module() auto-generate a qmldir file and auto-generate a static plugin to be embedded into the main app

                        (There are other ways to use subfolders in the source code; these are my preferences)

                        I would recommend a dynamic plugin if the goal is to create a standalone, reusable module that is to be used by multiple other apps.

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        1
                        • mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #16

                          So, I thought I had this working, but I just tried running my app on an Android emulator, and got an error that one of my custom Components is not a type. Is there a nuance to the build process I'm missing, or should I ask this in the Mobile forum?

                          Thanks...

                          JKSHJ 1 Reply Last reply
                          0
                          • mzimmersM mzimmers

                            So, I thought I had this working, but I just tried running my app on an Android emulator, and got an error that one of my custom Components is not a type. Is there a nuance to the build process I'm missing, or should I ask this in the Mobile forum?

                            Thanks...

                            JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by
                            #17

                            @mzimmers said in (reopened) using subdirectories in a CMake project:

                            got an error that one of my custom Components is not a type

                            You mean it didn't complain that your import was unrecognized, but if complained that your type is unrecognized? That's a bit strange.

                            Posting some sample code would be helpful.

                            I'd expect it to behave the same on both Android and on Desktop; it would be a bit simpler to troubleshoot on a Desktop target.

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            mzimmersM 1 Reply Last reply
                            0
                            • JKSHJ JKSH

                              @mzimmers said in (reopened) using subdirectories in a CMake project:

                              got an error that one of my custom Components is not a type

                              You mean it didn't complain that your import was unrecognized, but if complained that your type is unrecognized? That's a bit strange.

                              Posting some sample code would be helpful.

                              I'd expect it to behave the same on both Android and on Desktop; it would be a bit simpler to troubleshoot on a Desktop target.

                              mzimmersM Offline
                              mzimmersM Offline
                              mzimmers
                              wrote on last edited by
                              #18

                              @JKSH yeah, it works fine for the desktop, just not for Android.

                              What code do you want to see? Here's the Android-specific part of my CMakeLists.txt file:

                              set( ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android CACHE INTERNAL "" )
                              set_property(TARGET appqmltest APPEND PROPERTY
                                      QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
                              )
                              
                              JKSHJ 1 Reply Last reply
                              0
                              • mzimmersM mzimmers

                                @JKSH yeah, it works fine for the desktop, just not for Android.

                                What code do you want to see? Here's the Android-specific part of my CMakeLists.txt file:

                                set( ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android CACHE INTERNAL "" )
                                set_property(TARGET appqmltest APPEND PROPERTY
                                        QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
                                )
                                
                                JKSHJ Offline
                                JKSHJ Offline
                                JKSH
                                Moderators
                                wrote on last edited by JKSH
                                #19

                                @mzimmers said in (reopened) using subdirectories in a CMake project:

                                What code do you want to see?

                                Ideally, a minimal, compilable project (with any sensitive info removed) that works fine on the desktop but doesn't work on Android. Some ways to do this include:

                                • Zip up the project, upload it to a file sharing server and post a link here, OR
                                • Publish your project in a code repository (like GitHub) and post a link here

                                Here's the Android-specific part of my CMakeLists.txt file:

                                set( ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android CACHE INTERNAL "" )
                                set_property(TARGET appqmltest APPEND PROPERTY
                                        QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
                                )
                                

                                While I haven't developed a QML project for Android in a while, this part doesn't look like a problem.

                                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                1 Reply Last reply
                                0
                                • mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #20

                                  https://github.com/mzimmers/demo/blob/main/nga_demo.7z

                                  It's not a minimal example, but the only part that matters (I think) is the "custom" subproject as mentioned in the main CMakeLists.txt.

                                  Thanks...

                                  JKSHJ 1 Reply Last reply
                                  0
                                  • mzimmersM mzimmers

                                    https://github.com/mzimmers/demo/blob/main/nga_demo.7z

                                    It's not a minimal example, but the only part that matters (I think) is the "custom" subproject as mentioned in the main CMakeLists.txt.

                                    Thanks...

                                    JKSHJ Offline
                                    JKSHJ Offline
                                    JKSH
                                    Moderators
                                    wrote on last edited by
                                    #21

                                    @mzimmers said in (reopened) using subdirectories in a CMake project:

                                    https://github.com/mzimmers/demo/blob/main/nga_demo.7z

                                    Ah, ok. It looks like QQmlApplicationEngine doesn't actually try to import modules from the QRC root. Add engine.addImportPath(":/"); before your load main.qml.

                                    It works on the Desktop because the application was loading your custom module from your build folder. Android can't do that. (It will also not work if you deploy the application to a different Desktop PC)

                                    P.S. In the future, please push code directly to GitHub; please don't upload a zip file of your code on GitHub.

                                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                    mzimmersM 1 Reply Last reply
                                    1
                                    • JKSHJ JKSH

                                      @mzimmers said in (reopened) using subdirectories in a CMake project:

                                      https://github.com/mzimmers/demo/blob/main/nga_demo.7z

                                      Ah, ok. It looks like QQmlApplicationEngine doesn't actually try to import modules from the QRC root. Add engine.addImportPath(":/"); before your load main.qml.

                                      It works on the Desktop because the application was loading your custom module from your build folder. Android can't do that. (It will also not work if you deploy the application to a different Desktop PC)

                                      P.S. In the future, please push code directly to GitHub; please don't upload a zip file of your code on GitHub.

                                      mzimmersM Offline
                                      mzimmersM Offline
                                      mzimmers
                                      wrote on last edited by
                                      #22

                                      @JKSH that was it...thanks!

                                      BTW: I pushed the .zip file to the repo because I planned to delete it after the problem was solved (and I've done that now). Sorry if it caused any inconvenience.

                                      1 Reply Last reply
                                      0
                                      • JKSHJ JKSH referenced this topic on

                                      • Login

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