Problem using Vc with CMake 3.0 and kf5
Alex Merry
alex.merry at kde.org
Mon May 25 11:50:35 BST 2015
On Saturday 23 May 2015 11:51:55 Boudewijn Rempt wrote:
> Sorry for the extensive cross-posting in advance, please when replying, do
> a reply-all.
>
> Just so everyone is on the same page: Vc is a template library that makes
> it easy to build vectorized code using a single source file. Krita uses Vc
> to optimize blending colors, creating masks and much more. Krita uses the
> most recent Vc release, 0.7.4:
> http://code.compeng.uni-frankfurt.de/news/27
>
> We're currently porting Krita to Qt5 and KF5 and the way KF5 and Vc handle
> include directories is a big roadblock for us:
> https://git.reviewboard.kde.org/r/123179/ .
>
> In a nutshell: Vc builds many different object files from single cpp file.
> It does this by creating a custom command for each target vectorization
> extension. To do that, it needs to access the contents of
> INCLUDE_DIRECTORIES, like this (in VcMacros.cmake:
> http://code.compeng.uni-frankfurt.de/projects/vc/repository/entry/cmake/VcMa
> cros.cmake?rev=0.7)
>
> get_directory_property(_inc INCLUDE_DIRECTORIES)
> foreach(_i ${_inc})
> list(APPEND _flags "-I${_i}")
> endforeach()
>
> In the end the command is generated like this:
>
> add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_out}
> COMMAND ${CMAKE_CXX_COMPILER} ${_flags} ${_extra_flags}
> -DVC_IMPL=${_impl}
> ${_outfile_flag}${_out}
> ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
> MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
> IMPLICIT_DEPENDS CXX
> ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
> COMMENT "Building CXX object ${_out}"
> WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
> VERBATIM
> )
> KF5 uses cmake generator expressions to derive the include
> directories from the target_link_libraries lines. This means that when we
> try to build our per-extensions object files we get this:
>
>
>
> [ 0%] Building CXX object
> KoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o
> cd /home/boud/kde/build/calligra/libs/pigment && /usr/bin/c++
> -std=c++0x -fno-exceptions -Wall -Wextra -Wcast-align -Wchar-subscripts
> -Wformat-security -Wno-long-long -Wpointer-arith -Wundef
> -Wnon-virtual-dtor -Woverloaded-virtual -Werror=return-type
> -D__GNUC_UBUNTU_VERSION__=0xf040a -Wabi -fabi-version=0 -ffp-contract=fast
> -mtune=core2 -fPIC -I/home/boud/kde/src/calligra/interfaces
> -I/home/boud/kde/build/calligra -I/home/boud/kde/src/calligra
> -I/home/boud/kde/src/calligra/libs/version
> -I/home/boud/kde/build/calligra/libs/version
> -I/home/boud/kde/src/calligra/libs/koplugin
> -I/home/boud/kde/src/calligra/libs/version
> -I/home/boud/kde/build/calligra/libs/version
> -I/home/boud/kde/src/calligra/libs/pigment
> -I/home/boud/kde/src/calligra/libs/pigment/compositeops
> -I/home/boud/kde/src/calligra/libs/pigment/resources -I/usr/include
> -I/usr/include -I/usr/include/OpenEXR -I/usr/include -mavx -DVC_IMPL=AVX
> -c -oKoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o
> /home/boud/kde/src/calligra/libs/pigment/compositeops/KoOptimizedCompositeOp
> FactoryPerArch.cpp
>
> /home/boud/kde/src/calligra/libs/pigment/compositeops/KoOptimizedCompositeOp
> FactoryPerArch.cpp:22:19: fatal error: QString: No such file or directory
> #include <QString>
> ^
> compilation terminated.
> libs/pigment/CMakeFiles/pigmentcms.dir/build.make:72: recipe for
> target 'libs/pigment/KoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o'
> failed
>
> On other words, INCLUDE_DIRECTORIES is empty, there's no Qt5, no Kf5 to be
> found.
>
> If we manually set include directories like this:
>
> if (HAVE_VC)
> message(".>>>>>>>>>>>>" ${KDE4_INCLUDES})
> include_directories(${KDE4_INCLUDES} ${Qt5Core_INCLUDE_DIRS}
> ${Qt5Gui_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${PIGMENT_INCLUDES}
> ${Boost_INCLUDE_DIR}) endif()
>
> We end up with the entire include line for the contents of KDE4_INCLUDES
> ($<TARGET_PROPERTY:KF5::KDELibs4Support,INTERFACE_INCLUDE_DIRECTORIES>)
> expanded to a string with quotes around it:
>
> [ 0%] Building CXX object
> KoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o
> cd /home/boud/kde/build/calligra/libs/pigment && /usr/bin/c++
> -std=c++0x -fno-exceptions -Wall -Wextra -Wcast-align -Wchar-subscripts
> -Wformat-security -Wno-long-long -Wpointer-arith -Wundef
> -Wnon-virtual-dtor -Woverloaded-virtual -Werror=return-type
> -D__GNUC_UBUNTU_VERSION__=0xf040a -Wabi -fabi-version=0 -ffp-contract=fast
> -mtune=core2 -fPIC -I/home/boud/kde/src/calligra/interfaces
> -I/home/boud/kde/build/calligra -I/home/boud/kde/src/calligra
> -I/home/boud/kde/src/calligra/libs/version
> -I/home/boud/kde/build/calligra/libs/version
> "-I/usr/include/KF5/KDELibs4Support;/usr/include/KF5/KDELibs4Support/KDE;/us
> r/include/KF5;/usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-g
> nu/qt5/QtWidgets;/usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linu
> x-gnu/qt5/QtGui;/usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux
> -gnu/qt5/QtCore;/usr/lib/x86_64-linux-gnu/qt5//mkspecs/linux-g++-64;/usr/inc
> lude/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtDBus;/usr/inc
> lude/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtPrintSupport;
> /usr/include/KF5/KCoreAddons;/usr/include/KF5;/usr/include/KF5/KCrash;/usr/i
> nclude/KF5;/usr/include/KF5/KWidgetsAddons;/usr/include/KF5;/usr/include/KF5
> /KConfigCore;/usr/include/KF5;/usr/include/KF5/KConfigWidgets;/usr/include/K
> F5;/usr/include/KF5/KCodecs;/usr/include/KF5;/usr/include/KF5/KConfigGui;/us
> r/include/KF5;/usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-g
> nu/qt5/QtXml;/usr/include/KF5/KAuth;/usr/include/KF5;/usr/include/KF5/KIOCor
> e;
> /usr/include/KF5;/usr/include/KF5/KService;/usr/include/KF5;/usr/include/KF
> 5/KIOFileWidgets;/usr/include/KF5;/usr/include/KF5/KIOWidgets;/usr/include/K
> F5;/usr/include/KF5/KJobWidgets;/usr/include/KF5;/usr/include/x86_64-linux-g
> nu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtNetwork;/usr/include/KF5/KComple
> tion;/usr/include/KF5;/usr/include/KF5/KBookmarks;/usr/include/KF5;/usr/incl
> ude/KF5/KItemViews;/usr/include/KF5;/usr/include/KF5/KXmlGui;/usr/include/KF
> 5;/usr/include/KF5/Solid;/usr/include/KF5;/usr/include/KF5/KI18n;/usr/includ
> e/KF5;/usr/include/KF5/KNotifications;/usr/include/KF5;/usr/include/KF5/KIco
> nThemes;/usr/include/KF5;/usr/include/KF5/KWindowSystem;/usr/include;/usr/in
> clude;/usr/include/KF5;/usr/include/KF5;/usr/include/KF5/KGuiAddons;/usr/inc
> lude/KF5;/usr/include/KF5/KUnitConversion;/usr/include/KF5;/usr/include/KF5/
> KTextWidgets;/usr/include/KF5;/usr/include/KF5/SonnetUi;/usr/include/KF5;/us
> r/include/KF5/KParts;/usr/include/KF5" -I/usr/include/x86_64-linux-gnu/qt5
> -I/usr/include/x86_64-linux-gnu/qt5/QtCore
> -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64
> -I/usr/include/x86_64-linux-gnu/qt5
> -I/usr/include/x86_64-linux-gnu/qt5/QtGui
> -I/usr/include/x86_64-linux-gnu/qt5/QtCore
> -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64
> -I/usr/include/x86_64-linux-gnu/qt5
> -I/usr/include/x86_64-linux-gnu/qt5/QtXml
> -I/usr/include/x86_64-linux-gnu/qt5/QtCore
> -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64
> -I/home/boud/kde/src/calligra/libs/koplugin
> -I/home/boud/kde/src/calligra/libs/version
> -I/home/boud/kde/build/calligra/libs/version
> -I/home/boud/kde/src/calligra/libs/pigment
> -I/home/boud/kde/src/calligra/libs/pigment/compositeops
> -I/home/boud/kde/src/calligra/libs/pigment/resources -I/usr/include
> -I/usr/include -I/usr/include/OpenEXR -I/usr/include -mavx -DVC_IMPL=AVX
> -c -oKoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o
> /home/boud/kde/src/calligra/libs/pigment/compositeops/KoOptimizedCompositeOp
> FactoryPerArch.cpp In file included from
> /home/boud/kde/src/calligra/libs/pigment/DebugPigment.h:23:0,
> from
> /home/boud/kde/src/calligra/libs/pigment/compositeops/KoOptimizedCompositeOp
> FactoryPerArch.cpp:23:
> /home/boud/kde/src/calligra/libs/pigment/pigment_export.h:24:23: fatal
> error: kdemacros.h: No such file or directory
> #include <kdemacros.h>
> ^
> compilation terminated.
> libs/pigment/CMakeFiles/pigmentcms.dir/build.make:72: recipe for
> target 'libs/pigment/KoOptimizedCompositeOpFactoryPerArch_AVX.cpp.o'
> failed
>
>
> And that's where I'm totally stuck. It seems the cmake 3.0/kf5/e-c-m (I
> don't know where this system came from) is incompatible with a key libary
> that I have to use. We can't drop using Vc, we cannot move to a newer
> release of Vc and I can't see a way to replicate the functionality of
> vc_compile_for_all_implementations in our own cmake code either, so please
> help!
The issue here is that Vc's macros implicitly assume that all compilation
flags (including include paths) are done at the directory level (with
include_directories() and setting CMAKE_CXX_FLAGS etc), while CMake is moving
towards doing things at the target level (with target_include_directories(),
target_compile_options() and inheritance from targets passed to
target_link_libraries()).
Now, from the interface of the vc_compile_for_all_implementations macro, I'm
guessing that it is run before you've even created the relevant target, let
alone called target_link_libraries() on it. That makes things a bit tricky.
Basically, as far as I can see, you have two options. One is to use the old
CMake style of calling include_directories() all over the place in your CMake
code (eg: include_directories(${Qt5Core_INCLUDE_DIRS}) when you are going to
be linking against Qt5::Core). I'm not sure if we expose the relevant variable
properly in KF5 for that approach, though.
The other is to create a variant of vc_compile_for_all_implementations that
takes a target rather than a variable to receive object files - this should
ideally use generator expressions to extract include directories etc, but I'm
not sure if generator expressions are powerful enough to deal with the compile
flags properly.
Alex
More information about the calligra-devel
mailing list