SDK multiple build steps, qmake and cmake

I’ve just gotten great advice in a sailfish context for how to use the subdirs templates for dependancy building. This is great if you controll all the code. For the example I’m working on, where the entire library could actually be put in a single file and header, that’s ok. But not if you want to collaborate.

So, I want to use a library which the author supplies with cmake build files. But I’d prefer to use qmake (someone will probably hate me for saying that :slight_smile: I just find qmake in the Sailfish SDK context to be clean to work with managing with .spec and .pro files alone. On the other hand, the future of QT (sometime in the evolution of 6) is pointing at cmake anyway. Soooo.

What should I do, attempt to come up with a recipe for mixing build steps (must be doable)? Switch everything as some Sailfish devs have done to cmake?

My preference would be to use separate build steps, be able to include submodules from other projects via git that use cmake, but stick to ‘straight’ qmake for the sailfish apps. I’m probably thinking in the wrong direction.

The source, using the primitive subdirs approach is here (only a skeleton thus far):

What I’d like to do is use a build step instead that includes the cmake here:

Option 1

In specific cases, it is possible to use qmake’s $$system() function and QMAKE_EXTRA_TARGETS variable to invoke cmake/make on a subproject. But this does not work well e.g. when the subproject needs to be fully built before qmake can be run for the superproject or when you want to open the project as a whole under Qt Creator (subproject’s files would not be listed in project tree).

Option 2

Most convenient is to unify on the build system. In your case you can

  1. switch to CMake for the superproject as you mentioned or
  2. add qmake support either
    2a) directly to the subproject or
    2b) maintained on the superproject side.

Option 3

In more complex cases with build systems not matching/integrating well, it may be better to keep projects built and packaged separately. They can be opened all at once under a single Qt Creator session and project dependencies can be configured so that Qt Creator builds them all in the right order.

See Installing custom libraries into SDK targets - #3 by martyone to learn how to make packages build from a subproject available as superproject build time dependencies.

With this approach, in order to meet the Jolla Harbour restrictions on shipping shared libraries, you can repackage subproject’s libraries (and other files) under the superproject by copying them from the system locations with commands added to the %install section of the superproject’s RPM .spec file:

BuildRequires: foobar
...
%install
%qmake5_install
install -D -m 755 --target-directory %{buildroot}%{_datadir}/%{name}/lib/ \
    /usr/lib/libFooBar.so.1.2.3
1 Like

I’m thinking of doing this with simple, additional make files (a single .pro will do in some cases). So, leave the cmake files as they are, and simply add the subdir project. In my demo case, the build works, but I frankly don’t understand why :slight_smile:

Maybe the library (which I can see being built properly into the build root) is being included in the harbour binary as a static lib, inline? In any case the lib builds, the app builds and an rpm is built. That rpm doesn’t include the lib as a separate file.

The build produces two directories with the app (which doesn’t complain about missing libs) and the library. The .so files are properly created. Is it possible to run an install step like:

install -D -m 755 --target-directory %{buildroot}%{_datadir}/%{name}/lib/ \
    %{whereever it literally is}/libsynth/libsynth.so

???

And thanks for the great advice. Seems to be a habit?

PS. With the python libs in other projects (the c parts), It was simple to just use something like:

equals(QT_ARCH, arm64): {
python.files = lib/arm64/*
}

python.path = “/usr/share/harbour-simplecrop/lib”
INSTALLS += python

Why haven’t I tried that?!

EDIT. I just noticed that the naming is silly. the output that’s bein produced is liblibsynth… fixed that with TARGET in the library build .pro.

Ok so now I have successful builds of the library and app with the subdir template and the inclusion of the built libsynth.so.1.0.0 into the app’s lib directory.

But I still haven’t set rpath properly (I’m still only loading the header file and haven’t actually tried to USE the library) so I’m expecting some trouble.

It’s going to take some work (I need to create some QT slots/interfaces to bridge QML and the library)…

Unless you’ve got a specific reason not to do it, it may be easier to just build libsynth as a static library, and embed it in the executable.

Yeah, it’s a good candidate for static. But I’m trying to learn to deal with libraries in general since I’m supporting software (python + c) where the libraries need to remain shared.

The option for a small library without dependancies is definately martyone’s Option 2-2 … adding qmake support next to cmake is trivial if it’s relatively self-contained.

I need to make a how-to page once I have something to show. I just have compiling, linking and rpm generation so far :wink: Usually it’s the other way around …

An additional note is that I’m also trying to consider collaboration. If you add an external submodule it becomes tricky when project’s become larger. But I guess you can just fork and do pull it it’s of use. Thnakfully I like small self-conainted projects :slight_smile:

Sigh. How do I intentionally get a static library compiled in ? It’s a keyword variable?

It does ‘just work now’. I have a running example (which will crash !) that uses the library I’m just not sure if it isn’t already static AND copied into /usr/share/${name}/lib :slight_smile:

UPDATE: Actually, it works. It crashed when started from the sdk with qml debugging. Starting from the deice, the sound generation startup works on start and then the normal app->exec() main takes over. Yipee.

UPDATE2: Well, it is static in the binary. The rpm validator tells me it fails to link :slight_smile: So I’m half way there although for this example, static is just fine.