The CMake situation in frameworks

Stephen Kelly steveire at gmail.com
Fri Nov 25 01:24:55 UTC 2011


Hi,

Alex and I had a discussion this evening on some issues around CMake 
features in upcoming CMake versions that we want to use in frameworks, and 
some of the remaining issues around CMake and frameworks in general.

To bring people up to speed on some other relevant stuff and what we 
discussed:

== Qt5 will install CMake Config files ==

Instead of creating a FindQt5.cmake in CMake and maintaining a fork of it in 
KDE for quick access to new features, Qt5 will install CMake config files 
and macros. They will be maintained there by myself (via KDAB) and possibly 
Clinton Stimpson, who maintained FindQt4.cmake in CMake. 

The Qt5 plan is modularity, so some variables like QT_VERSION_MINOR may not 
have any meaning anymore, replaced by Qt5Core_VERSION_MINOR and 
Qt5Declarative_VERSION_MINOR, which may be different. The impact of this 
will have to be found out later. 

Even though Qt5 Config files will exist KDE can still not use them by 
providing a FindQt5.cmake, or it can provide a FindQt5.cmake which 
internally does use the config file (by doing something like 
find_package(Qt5 NOMODULE)) and add 'KDE stuff' on top, whatever that might 
be. For more see:

http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/2090

I hope to get the patch merged into Qt soon so that remaining issues can be 
fixed.

== New CMake features making parts of KDE macros obsolete ==

=== Automoc ===

Alex's work on getting automoc features into CMake and bugfixed continues. 
The automoc features in CMake make the automoc4 tool obsolete, so there will 
be no need for an automoc5 tool. The preferred way to use the CMake automoc 
integration will be to not include a moc file at all. That is, don't use:

#include "foo.moc"

or 

#include "moc_foo.cpp"

CMake will create the moc files anyway for those based on the existence of 
the Q_OBJECT macro. You don't need to worry about compilation being slow 
because of compiling each moc file separately either. The moc files which 
are created without being included will be compiled into one compilation 
unit per target.

There are still reasons to include moc files, such as for example including 
the result of moc'ing a private header. In that case 

#include "moc_foo_p.cpp"

should be used instead of 

#include "foo_p.moc"

The difference is that from the point of view of qmake, moc_*.cpp files are 
supposed to be the result of moc'ing .h files, and *.moc files are supposed 
to be the result of moc'ing .cpp files. Although the automoc4 tool allowed 
either, The CMake automoc feature will prefer the Qt/QMake convention.

=== Link interface libraries ===

In some places in KDE you might see code like:

target_link_libraries(foo 
    ${QT_QTCORE_LIBRARIES} 
    ${QT_QTGUI_LIBRARIES} 
    ${QT_QTSCRIPT_LIBRARIES}
    ${QT_QTSQL_LIBRARIES}
)
target_link_libraries(foo 
    LINK_INTERFACE_LIBRARIES
    ${QT_QTCORE_LIBRARIES}
    ${QT_QTGUI_LIBRARIES}
)

The LINK_INTERFACE_LIBRARIES version is special in CMake, and together the 
two calls communicate that anything that links to foo must also link to 
QtCore and QtGui, and foo itself links to QtScript and QtSql, but things 
linking to foo don't need to link to QtScript or QtSql as a result of 
linking to foo (because no symbols from QtScript appear in the ABI of foo).

In CMake 2.8.7, the more compact version can be used and will be preferred:

target_link_libraries(foo 
    ${QT_QTSCRIPT_LIBRARIES}
  LINK_PUBLIC
    ${QT_QTCORE_LIBRARIES}
)

== Library, executable, plugin and test wrapper macros ==

The kde4_add_library macro wraps the CMake add_library function with the 
features of automoc, enable_final, defining symbols for export headers, and 
setting the LINK_INTERFACE_LIBRARIES to empty.

CMake 2.8.7 will provide built in features to provide all of those features 
obsolete with the exception of enable_final, which may not work properly 
anymore (when using CMake built in automoc support), and was not considered 
very important during the last few kde-buildsystem meetings.

kde4_add_executable also does automoc, adding WIN32 or MACOSX_BUNDLE flags 
to the add_executable, enable_final, tests handling, linking to QtMain and 
adding uac manifest files on windows. It will probably not be possible to 
add upstream (or otherwise external) equivalents of all of the features of 
this macro. The automoc is already upstream and enable_final will go from 
the macro and only be able to exist as a CMake builtin if anywhere. The 
linking to QtMain can I suspect be done in the Qt CMake config files. I 
suspect that the WIN32 and MACOSX_BUNDLE flags can be added there too. I 
don't know about the manifest and tests stuff. Perhaps we can put that stuff 
into ECM.

There are several other kde wrappers such as kde4_add_unit_test 
kde4_add_kdeinit_executable etc. I have not evaluated what parts of any 
other macros are obsolete, or can be upstreamed. If anyone else wants to 
look into that with goals of modularity in mind, feel free

== Module specific macros ==

There are other macros such as kde4_create_handbook(), kde4_install_icons(), 
kde4_create_manpage() (and others) which KDE needs and which need to be 
installed from somewhere. One option is to install kde4_install_icons from 
the same place that KIconEngine is installed from (KGuiSomething?), 
kde4_create_manpage from the place where the doctools are, etc. That is, 
keep the macros together with the modules they relate to.

I support that idea, and I *think* Alex does too. What do others think?

== Multiarch ==

The way libraries get installed and found is changing. Instead of just lib/ 
or lib64/ they might be in lib/i386-linux-gnu/ or lib/arm-linux-gnueabi/. We 
need to evaluate how that impacts KDE and KDE developers (who just want to 
use ${KDE_LIB_INSTALL_DIR} or so and not care about it).

== Communicating build parameters between modules ==

Some people don't want to set custom parameters for certain install 
directories and have those locations picked up by other depending modules. 
Eg, if a custom value is set for LIB_INSTALL_DIR in kdelibs and KDEPIM is 
built against that version of kdelibs, KDEPIM should use the same value for 
LIB_INSTALL_DIR. This is provided by the _set_fancy macro currently. There 
may be better ways to do this, such as specifying the values in the config 
files for frameworks, or installing a CMakeCache.txt. Needs more 
investigation.



Thanks,

Steve.




More information about the Kde-buildsystem mailing list