[Development] Installing Qt5Config.cmake from the Qt repo?

Stephen Kelly stephen.kelly at kdab.com
Wed Nov 2 18:12:58 CET 2011


On Wednesday, November 02, 2011 17:37:44 Thiago Macieira wrote:
> On Wednesday, 2 de November de 2011 16:29:16 Stephen Kelly wrote:
> > > If you link to a Qt module named Foo, you must do:
> > > 	-I$QTDIR/include/QtFoo -DQT_FOO_LIB
> > > 	-L$QTDIR/lib -lQtFoo
> > > 
> > > The -D option has been missing in CMake.
> > 
> > Nope. It's not missing. It's in the UseQt4.cmake file.
> 
> But we agreed that including that file when you have more than one target in
> your CMakeLists.txt is a bad idea. 

Well, we agreed that the issue exists. There are non-perfect solutions, but 
the -D options have not been missing from CMake even though KDE didn't use 
them.

> We need a way to set the includes,
> defines and link libraries per target.
> 
> Also, is the file one per CMake build or is it for each directory?
> 
> To take an example: KDE doesn't use the use-file, which means problems arise
> when compiling tests. If the use-file is the way to do it, then we should
> start doing that for KDE too.
> 
> To be clear: I don't think that's the way.

I agree that something like qt5_add_module is better.

> > > > However, there is currently no way to add target specific
> > > > include
> > > > directories (though it could probably be pushed along
> > > > http://www.cmake.org/pipermail/cmake/2007-June/014386.html)
> > > > 
> > > > But how does this solve any issues with -DAnything?
> > > 
> > > That's why I'm saying "don't use target_link_libraries".
> > 
> > I don't understand what target_link_libraries has to do with
> > -DQT_FOO_LIB, but I'll just assume it's a non-issue.
> 
> It has nothing to do, which is the problem. To link to a Qt module, you need
> to add include dirs, a define and a link library. So I'd rather have one
> command that does it right than have people write boilerplate (and get it
> wrong).

Ok, so what you really wanted to say is "don't use target_link_libraries 
directly. Use a wrapper macro that does that and the other important and 
necessary things". Is that right?

> 
> > > Duplicated work. If you change your code, you need to update two
> > > places: where you add the module and where you tell CMake to search
> > > for it. I'd like the tool to help me.
> > 
> > I don't understand. You don't like having two lines:
> > 
> > find_package(Qt5 COMPONENTS Widgets)
> > ...
> > target_link_libraries(mylib ${Qt5Widgets_LIBRARIES})
> > 
> > but you want it to be one line:
> > 
> > qt5_add_module(mylib Widgets)
> > 
> > ? Is that right? Is that solved by the macro I posted in the other
> > email?
> 
> No. It's still two lines:
> 
> find_packages(Qt5)
> ...
> qt5_add_module(mylib Widgets)
> 
> 
> But the information that I need QtWidgets is in one line only. Imagine a
> more complex project:
> 
> find_packages(Qt5 COMPONENTS Core Gui Widgets XmlPatterns Test)
> ...
> qt5_add_mdoule(mylib Widgets)
> ...
> target_link_libraries(test1 mylib)
> qt5_add_modules(test1 Test)
> ...
> target_link_libraries(test2 mylib)
> qt5_add_mdoules(test2 Test XmlPatterns)
> 
> This is version 1.0. Then I do some more work and I decide to use
> QXmlStreamReader in my second test. Since I don't need QtXmlPatterns
> anymore, I go to the last line, where I added the module, and make it
> require only QtTest.
> 
> Since my system does have QtXmlPatterns, I don't realise that I left the
> XmlPatterns requirement in the find_package line. So now everyone needs to
> install this addon when compiling the tests even if nothing uses it.

Ok. I understand. I believe that is solved by putting the find_package call 
inside the qt5_add_module macro.

> 
> > Yes, I was just correcting your sentence. There is no FindQt5.cmake.
> > There is to be a Qt5Config.cmake. But this issue is not important. Yes,
> > it's an implementation detail that you don't need to care about.
> 
> Something will need to add the macros :-)

You mean a FindQt5.cmake would be needed to add macros? Why can't that be done 
in the config files?

The qt5_add_module macro would be defined in Qt5CoreMacros.cmake, installed 
alongside Qt5CoreConfig.cmake, and Qt5CoreConfig.cmake contains the line:

include(${CMAKE_CURRENT_LIST_DIR}/Qt5CoreMacros.cmake)

Similarly, the qt5_add_dbus_interfaces macro would be defined in 
Qt5DBusMacros.cmake installed alongside Qt5DBusConfig.cmake with a similar 
include.

> 
> > So you want
> > 
> > find_package(Qt5)
> > 
> > if (Qt5Webkit_FOUND)
> > 
> >   # Do something
> > 
> > endif()
> > 
> > instead of
> > 
> > find_package(Qt5 COMPONENTS Webkit)
> > 
> > if (Qt5Webkit_FOUND)
> > 
> >   # Do something
> > 
> > endif()
> > 
> > ? That means that Qt5Config.cmake needs a list of Qt5 modules. I have no
> > problem with that, but Lars indicated he didn't like thatQt5Config.cmake
> > would have knowledge of what Qt5 modules exist I think.
> 
> Which is why a FindQt5.cmake script can find and collect all installed
> addons.

This then introduces the problem of where does FindQt5.cmake get installed 
from? It would have to be in CMake itself. Seems like an odd thing to do just 
for the purpose of keeping a list out of Qt5Config.cmake. I think Lars would 
come around to the idea of simply listing them.

Currently the top of Qt5Config.cmake looks like this:

if (NOT Qt5_FIND_COMPONENTS)
  # By default we look for QtCore and QtGui, just like QMake
  set(Qt5_FIND_COMPONENTS Core Gui)
endif()

So I can just change it to this:

if (NOT Qt5_FIND_COMPONENTS)
  # By default we look all Qt modules
  set(Qt5_FIND_COMPONENTS 
      Core 
      Gui
      Widgets
      Webkit
      # TODO: Add the others
  )
endif()

If the list has to be maintained somewhere, it only makes sense to maintain it 
in Qt.

> 
> But I don't mind having to declare the *optional* packages, the ones that I
> will use conditionals on. What I don't want is to have to do the double-
> booking of the mandatory ones.

By 'mandatory' and 'optional' you mean QtEssentials vs QtAddons?

So you don't want to do this:

find_package(Qt5)

if (Qt5Gui_FOUND)
  # ...
endif()

You want to assume Qt5Gui is always found? That's not always true.

But you don't mind doing this:

find_package(Qt5 Widgets)

if (Qt5Widgets_FOUND)
  # ...
endif()


> 
> > > How does it know which files are my headers? It needs to have a list
> > > somewhere, which needs to be given to the Qt5 macros. It cannot scan
> > > all .h
> > > in the directory because:
> > > 
> > > 1) some files may be somewhere else
> > > 2) some .h may not belong to this target, so their moc outputs
> > > shouldn't be
> > > linked to this target
> > > 3) some .h may not belong to any target at all, just legacy stuff we
> > > kept 4) some headers may not be named *.h
> > 
> > For odd cases you use the same mechanisms you used before cmake 2.8.6:
> > qt4_wrap_cpp, qt4_generate_moc etc.
> 
> Then let's take the opportunity to correct the mistakes.

I agree.

Thanks,

-- 
Stephen Kelly <stephen at kdab.com> | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20111102/dd610e28/attachment.sig>


More information about the Development mailing list