What Would Be a Pratical Example of Sysroot and Prefix Options for Qt

Qt -sysroot, -prefix, -extprefix and -hostprefix options

Install step targets the directory specified by extprefix which is optional and defaults to sysroot/prefix. Defining extprefix to point some directory in the host should prevent you from polluting your sysroot. hostprefix allows separating host tools like qmake from target binaries. When given, such tools will be installed under the specified directory instead of extprefix.

Using these prefix flags keeps your sysroot clean and separates device binaries and host tools:

export INSTALLPATH=/home/alan/work/qt/qt_5.5.1_arm_cross_compiled
./configure ... -extprefix $INSTALLPATH/binaries -hostprefix $INSTALLPATH/tools

What is a sysroot exactly and how do I create one ?

A sysroot is a directory which is considered to be the root directory for the purpose of locating headers and libraries. So for example if your build toolchain wants to find /usr/include/foo.h but you are cross-compiling and the appropriate foo.h is in /my/other/place/usr/include/foo.h, you would use /my/other/place as your sysroot.

DESTDIR vs prefix options in a build system?

Yes, there's a very important difference... in some environments.

The prefix is intended to be the location where the package will be installed (or appear to be installed) after everything is finalized. For example, if there are hardcoded paths in the package anywhere they would be based on the prefix path (of course, we all hope packages avoid hardcoded paths for many reasons).

DESTDIR allows people to actually install the content somewhere other than the actual prefix: the DESTDIR is prepended to all prefix values so that the install location has exactly the same directory structure/layout as the final location, but rooted somewhere other than /.

This can be useful for all sorts of reasons. One example are facilities like GNU stow which allow multiple instances to be installed at the same time and easily controlled. Other examples are creating package files using RPM or DEB: after the package is installed you want it unpacked at root, but in order to create the package you need it installed at some other location.

And other people use it for their own reasons: basically it all boils down to DESTDIR is used to create a "staging area" for the installation, without actually installing into the final location.

Etc.

configure question: What would be the most appropriate place to install example programs for a library?

you can use the /your_prefix_installation_path/share/your_package_name folder to do it. Which is the general folder to put the documentation/example in.

To do it:

For instance, the following snippet how to install your file into ‘$(datadir)/your_package_name’.

 yourexampledir = $(datadir)/your_package_name/
yourexample_DATA = your file here

QtBlueTooth not functional on Linux

OK, finally I've managed to solve the issue. Qt has some feature test functions when you build it by source. If you don't have some development packages installed on the host, the test will fail and the function won't work properly. In this case qt will use dummy backend instead, so the example apps can still compile OK and run, but without any practical usage.

Speaking of the qt bluetooth, the required dev-packages are libbluetooth-dev bluetooth blueman bluez libusb-dev libdbus-1-dev bluez-hcidump bluez-tools (I've list more installs than needed, just in case), make sure install all these on the host BEFORE make.

After I've done all the prepare work, I run the configure script to generate the Makefile for Qt. This is the configure script I use:

#!/bin/sh
./configure \
-v \
-prefix /opt/qt-5.7.0 \
-release \
-opensource \
-xplatform linux-arm-gnueabi-g++ \ # yes, I need to cross-compile
-qt-sql-sqlite \
-qt-zlib \
-qt-pcre \
-no-opengl \
-no-sse2 \
-no-openssl \
-qt-freetype \
-nomake examples \
-nomake tests \
-no-separate-debug-info \
-no-qml-debug \
-pkg-config \
-confirm-license

After running the configure script, you'll get a qmake executable under yourQtSourcePath/qtbase/bin/, then you can test your qtbluetooth function by execute:

qtSourcePath/qtbase/bin/qmake qtSourcePath/qtconnectivity/qtconnectivity.pro   

If you see something like:

Checking for bluez... yes
Checking for bluez_le... yes
Checking for linux_crypto_api... yes

then you are good to go, just make && make install for the whole Qt source, qt bluetooth can work properly now.

EDIT:

If by any means you can't pass the bluetooth test (It's very possible when you need to cross-compile, like my case), I've figured out a workaround. You still have to install all the required dev-packages before make, this time in order to pass the bluetooth function test, you can use your system built-in qmake (apt-get install qt5-qmake, NOT the qmake you generated by running configure script) to work with qtconnectivity.pro. This way, you can pass the bluetooth function test and generate a Makefile for qtconnectivity module.

Modify the Makefile, change the QMAKE parameter. In my case, this is the result:

- QMAKE = /usr/lib/x86_64-linux-gnu/qt5/bin/qmake
+ QMAKE = /opt/qt-everywhere-opensource-src-5.7.0/qtbase/bin/qmake

Then, you can cross-compile the whole Qt source by make && make install.

I've test the workaround, the example app (heartRate server) can work properly now. The annoying message "qt.bluetooth: Dummy backend running. Qt Bluetooth module is non-functional" is gone :)

Learning Python and using dictionaries

defaultdict is not dict (it's a subclass, and may do too much of the work for you to help you learn via this exercise), so here's a simple way to do it with plain dict:

dv = list()
# arbitrary sequence of numbers
seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2]

# dictionary counting number of occurances
seqDic = { }

for i in seq:
if i in seqDic:
seqDic[i] += 1
else:
dv.append(i)
seqDic[i] = 1

this simple approach works particularly well here because you need the if i in seqDic test anyway for the purpose of building dv as well as seqDic. Otherwise, simpler would be:

for i in seq:
seqDic[i] = 1 + seqDic.get(i, 0)

using the handy method get of dict, which returns the second argument if the first is not a key in the dictionary. If you like this idea, here's a solution that also builds dv:

for i in seq:
seqDic[i] = 1 + seqDic.get(i, 0)
if seqDic[i] == 1: dv.append(i)

Edit: If you don't case about the order of items in dv (rather than wanting dv to be in the same order as the first occurrence of item in seq), then just using (after the simple version of the loop)

dv = seqDic.keys()

also works (in Python 2, where .keys returns a list), and so does

dv = list(seqDic)

which is fine in both Python 2 and Python 3. Under the same hypothesis (that you don't care about the order of items in dv) there are also other good solutions, such as

seqDic = dict.fromkeys(seq, 0)
for i in seq: seqDic[i] += 1
dv = list(seqDic)

here, we first use the fromkeys class method of dictionaries to build a new dict which already has 0 as the value corresponding to each key, so we can then just increment each entry without such precautions as .get or membership checks.



Related Topics



Leave a reply



Submit