Sunday, January 15, 2017

The new Ubuntu SDK, part 3

[Update: Changed links to source code from https://launchpad.net/qtcreator-plugin-ubuntu and https://launchpad.net/ubuntu-sdk-tools to 
https://code.launchpad.net/~ubuntu-sdk-team/.... which is where the current tools probably live.]
Ubuntu SDK IDE offers custom project templates. Either CMake or qmake based.
I wonder how does the C++ compilation with CMake work in the Ubuntu SDK, so let's explore the "QML App with C++ plugin (cmake)" template. The source code for it can be seen in the qtcreator-plugin-ubuntu package. It includes all the parts required for a click package, wrapped in CMake:


It also includes support for QML and some sample code to have a QML application with some C++ code.

The interesting things about the CMake configuration are:
  • the special CMake variable UBUNTU_MANIFEST_PATH:
    # Do not remove this line, its required for the correct functionality of the Ubuntu-SDK
    set(UBUNTU_MANIFEST_PATH "manifest.json.in" CACHE INTERNAL "Tells QtCreator location and name of the manifest file")
    And indeed, this is used by the qtcreator-plugin-ubuntu to detect that this is an Ubuntu-specific project and it triggers special behavior down the lane.
  • there are some variables in the top-level CMakeLists.txt that are then substituted in the *.in templates to produce the final manifest and desktop files
  • everything is installed to / (and DESTDIR is used to direct it into the actual install directory)
It's possible to adapt the CMakeLists.txt. In fact it can be adapted to so that it builds a standalone C++ application (no QML, or even no Qt).
One should not remove the UBUNTU_MANIFEST_PATH variable. When not present, Ubuntu SDK IDE handles it like Qt Creator does. This means there's no click package being build and it's not possible to deploy and debug on the target device. The same is true for the manifest: The project must contain either manifest.json or manifest.json.in. When it's not there, you again get the non-Ubuntu project behavior.
Also notice that the run step (in Ubuntu SDK: "Projects" in the left bar, pick one kit and select "Run" there) for the Ubuntu projects is magical. It's not possible to add the Ubuntu-specific launch option to a non-Ubuntu project (a project configured without the UBUNTU_MANIFEST_PATH), and for Ubuntu project it's automatically added.

There are some more idiosyncrasies of qtcreator-plugin-ubuntu:
  • The Ubuntu-specific run option (which handles also running and debugging on the target device) is added to Ubuntu projects automagicaly. It creates one run entry for each 'hook' (entry in the manifest file, in "hooks").
  • If the CMakeLists.txt specifies any executables (added via add_executable CMake command), these are added to the run configuration too, as a non-Ubuntu run entries. These can't be used on the Ubuntu target, so they are quite useless. Feel free to delete them after you import such a project into the Ubuntu SDK IDE.
  • CMake is run with CMAKE_CXX_COMPILER set to gcc (i.e. not g++). This means that if you try to link a C++ application you end up with an error like:
    .../arm-linux-gnueabihf/bin/ld: CMakeFiles/native-test.dir/native-test.cpp.o: undefined reference to symbol '_Znwj@@GLIBCXX_3.4'
    /var/lib/lxd/containers/device-armhf/rootfs/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: error adding symbols: DSO missing from command line
    collect2: error: ld returned 1 exit status
    

    The solution (I'm not so sure it's the right way, but well...) is to add stdc++ to the list of required libraries for the target, e.g. target_link_libraries(YourTarget stdc++)

No comments:

Post a Comment