Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-83774

Versionless CMake config files and targets create an incompatible dialect

    XMLWordPrintable

Details

    • All
    • fcceae605a3dc4ec4bb501cca8b290f7e1d2936b (qt/qtbase/5.15)

    Description

      A well behaved library using Qt6 and creating cmake config file packages might have an effect like this:

      # Make my life and my users life easier by making Qt version use unambiguous. 
      # We have to use an ugly variable to save the existing state:
      set(Grantlee6_existingState ${QT_NO_CREATE_VERSIONLESS_TARGETS})
      set(QT_NO_CREATE_VERSIONLESS_TARGETS OFF)
      find_dependency(Qt6Core REQUIRED)
      # Unset this so that it doesn't leak
      set(QT_NO_CREATE_VERSIONLESS_TARGETS ${Grantlee6_existingState})
      unset(Grantlee6_existingState
      
      add_library(Grantlee6::Templates SHARED IMPORTED)
      set_property(TARGET Grantlee6::Templates PROPERTY 
          INTERFACE_LINK_LIBRARIES Qt6::Core
      )
      

      Now, when someone tries to use my library and tries to use versionless targets, it does not work:

      # Finds Qt6Core and defines versioned Qt6::Core but does not define versionless Qt::Core
      find_package(Grantlee6)
      # Has no effect because it has already been found (does not create versionless Qt::Core): 
      find_package(Qt6Core)
      
      add_executable(myexe main.cpp)
      # Fails:
      target_link_libraries(myexe Qt::Core)
      

      However reordering makes it do what the user expected in this case:

      # Finds Qt6Core and defines versioned Qt6::Core and versionless Qt::Core
      find_package(Qt6Core)
      # The internal find_package(Qt6Core) has no effect because it is already found:
      find_package(Grantlee6)
      
      add_executable(myexe main.cpp)
      # Works:
      target_link_libraries(myexe Qt::Core)
      

      This is bad. The workingness or not of find_package() calls should not be order dependent. This gets even worse when using multiple libraries which use Qt:

      # Contains find_package(Qt6Core) but prevents versionless targets:
      find_package(Foo)
      # The find_package(Qt6Core) in BarConfig.cmake has no effect, but Bar::Core uses versionless Qt::Core in its INTERFACE_LINK_LIBRARIES.
      # This will lead to failure at generate time.
      find_package(Bar)
      

      In the above case, the user needs to put an additional find_package(Qt6Core) before those two find_package calls.

      # Only needed to solve dialect problem in the Qt cmake files:
      find_package(Qt6Core)
      
      find_package(Foo)
      find_package(Bar)
      

      These versionless targets mean that there are now two dialects of Qt in the buildsystem.

      They are incompatible and that will create problems.

      The decision to introduce them should be reversed.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-83774
          # Subject Branch Project Status CR V

          Activity

            People

              qtbuildsystem Qt Build System Team
              steveire Stephen Kelly (Personal)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes