Solved Qt project (mix of libs and apps) configuration nightmare (targetting Desktop, Android, and others).
-
Hello everyone,
I am struggling to get a very simple thing going. I imagined what I'm trying to achieve would be part of the things Qt would strive to solve, but google searches have made me believe that may not be the case. I'm trying to build the following project structure:
- projectgroup
- lib1
- lib2 (depends on lib1)
- lib3 (depends on lib1 and lib2)
- app (depends on lib1 and lib2 and lib3)
This builds fine on Windows 10 using both MVSC or MINGW. I was surprised I had to tell the projects where to look for the libs, and that the dependency chain defined in the .pro file could not solve that for me. But for Windows at least, the workaround is simple. For Android (building from Windows) it is not.
I could post what I've been trying to do to achieve this build for Android, but that would take up a lot of your time. Instead I'll ask: what is the best practice to achieve such a build? I'm building from Windows for Android. I have all the SDK and NDK setup. I can build the (single project) Qt examples. I can run those examples on Windows and the Android emulator. I haven't found a multi project Qt example yet. The main problem I am running into is that during an android build, the lib2 project cannot find the lib1 binaries of x86, x64, armv7 and armv8 (even though they have been built).
I could potentially hack something together using platform conditions and functions to make it work. But given the amount of logic I have to write just to make it possible to build for Android from Windows, how monstrously large a .pro file would I end up with? I would have to write all those things for building for Android from Linux, building for Android from Mac, building for iOS, building for Raspberry Pi from Windows, building for Raspberry Pi from Linux, building for Raspberry Pi from Mac. Not only that; it's not that straightforward to write the conditions for a directed build. There is only the build platform condition, but not a target platform condition. I would have to concoct some combination of compiler and android architecture conditions to make it all work. So all this has got me thinking: this can't be the way. There must be something I'm overlooking? Otherwise I might as well go back to writing my own makefiles again.
Also, is it me, or do conditions sometimes plainly not work?
win32 { msvc|g++ { CONFIG(release, debug|release): { LIBS += -L$$OUT_PWD/../ralgebra/release/ -lralgebra } CONFIG(debug, debug|release) { LIBS += -L$$OUT_PWD/../ralgebra/debug/ -lralgebra } } clang { LIBS += -L$$OUT_PWD/../ralgebra/ -lralgebra } }
this obviously should not produce this
<...>\Android\Sdk\ndk\21.1.6352462/toolchains/llvm/prebuilt/windows-x86_64/bin/clang++ -target i686-linux-android21 -mstackrealign -fno-limit-debug-info -Wl,--build-id=sha1 -Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl,-soname,librengine_x86.so -o librengine_x86.so @x86\object_script.librengine_x86.so.X86 -L<...>/build-cherry-Clang-x86_64-for-Android-Release/rengine/../ralgebra/release/ -L<...>/build-cherry-Clang-x86_64-for-Android-Release/rengine/../ralgebra/debug/ -L<...>/build-cherry-Clang-x86_64-for-Android-Release/rengine/../ralgebra/ -lralgebra C:/Qt/5.15.0/android/lib/libQt5Network_x86.so C:/Qt/5.15.0/android/lib/libQt5OpenGL_x86.so C:/Qt/5.15.0/android/lib/libQt5Widgets_x86.so C:/Qt/5.15.0/android/lib/libQt5Gui_x86.so C:/Qt/5.15.0/android/lib/libQt5Core_x86.so -lGLESv2 -llog -lz -lm -ldl -lc
All the lib directories from each separate condition have been added to the linker call.
What am I misunderstanding?
- projectgroup
-
Okay never mind, I figured out what I was doing wrong. The opening curly bracket needs to be on the same line as the condition. This is an odd design choice since the language qmake is building around is C++. Lots of C++ developers have a preference for starting a block on the next line.
I also learned that win32/android/mac conditions are about the target platform, not the host platform. Not sure why I was so certain it was the other way around.
Now all that's left is to figure out how an Android build appends the correct ABI postfix to the libraries it is supposed to search for.
-
Right. So I've found the cleanest way to do it. It's actually quite elegant. It would be nice if there was an example that demonstrated this for people who haven't developed with Qt before, but switched mainly due to its ability to build for Android.
win32 { CONFIG(release, debug|release) { LIBS += -L$$OUT_PWD/../ralgebra/release -lralgebra } CONFIG(debug, debug|release) { LIBS += -L$$OUT_PWD/../ralgebra/debug -lralgebra } } android { LIBS += -L$$OUT_PWD/../ralgebra/ -lralgebra_$${ANDROID_TARGET_ARCH} QMAKE_CLEAN += librengine_$${ANDROID_TARGET_ARCH}.so }
Thanks