Printing money for the climate

Yes. Let’s print lot’ s of Euros for the purpose of enhancing technologies related to Climate.

Because we need to increase the Euro’ s inflation. We should stop investing in government bonds for the same purpose (saving the Greek socialist government). We need to invest in our shared European military too (replacing NATO). Those should increase our Euro inflation. Investing in climate related technologies will likely increase our Euro inflation. Which we still need. Urgently.

We however need to violently stop increasing Euro inflation by investing in EU government debt. We need to start investing in the real things the young people in the European Union want.

What do we need to invest European money in (in order of priority):

  • Propaganda (RT is fine, but, we probably want to control it ourselves instead)
  • Military (a European DARPA). We really need our own EU military research. Space. Rocket science. Weapons research. Because this will improve research and technology in and of civilian space. Whether civilians like this or not. Besides, we might some day need it against an invading force (rather unlikely, but still).
  • Climate technologies. It’s clear that civilians want this. Let’s do it, then.
  • Infrastructure (roads, borders, schools, swimming pools in villages)
  • Social security (Look at Leuven’s academic hospital. This is fantastic. More of this, please)
  • Lawmaking about new technologies (social media, privacy in a digital age, genetic engineering of seeds and others, chemicals, farming, medical, and many more)



Beste NV-A,

Beste NV-A,

Als je uw propaganda honden niet in de hand hebt, ben je ongeschikt als regeringspartij. Als je die campagne bewust lanceerde, ben je racistisch en onbeschoft. Die is gericht tegen mensen. Heeft niets te maken met oplossingen bieden. Wel met haat en angst.

In beide gevallen hoor je niet in de Belgische regering.

Vertrek dus maar.

Dit was er over.

Het leven van een autist die ook maar goed probeert te doen

Daarnet, aan de kassa van een winkel stond er een mevrouw met een kleed. Aan haar kleed hing achteraan een breed lint vanaf haar hals tot aan haar billen.

Dus ik zeg: “Mevrouw, mevrouw, er hangt een lint los aan je kleed”

Antwoord zij: “Mmnjnee dat is zo”, “mmaar toch lief dat je het zegt”.

Dus nu ben ik stuk. Hartverscheurend was die tweede m telkens. Ocharme dat menske.

En toch zag dat kleed er stuk uit vanachter. Dat lint hing er ook niet deftig aan.

Vrouwen en hun rare ideeën qua kleren..

Doing It Right examples on autotools, qmake, cmake and meson


I finished my earlier work on build environment examples. Illustrating how to do versioning on shared object files right with autotools, qmake, cmake and meson. You can find it here.

The DIR examples are examples for various build environments on how to create a good project structure that will build libraries that are versioned with libtool or have versioning that is equivalent to what libtool would deliver, have a pkg-config file and have a so called API version in the library’s name.

What is right?

Information on this can be found in the autotools mythbuster docs, the libtool docs on versioning and freeBSD’s chapter on shared libraries. I tried to ensure that what is written here works with all of the build environments in the examples., what is what?

You’ll notice that a library called ‘package’ will in your LIBDIR often be called something like

We call the 4.3 part the APIVERSION, and the 2.1.0 part the VERSION (the ABI version).

I will explain these examples using semantic versioning as APIVERSION and either libtool’s current:revision:age or a semantic versioning alternative as field for VERSION (like in FreeBSD and for build environments where compatibility with libtool’s -version-info feature ain’t a requirement).

Noting that with libtool’s -version-info feature the values that you fill in for current, age and revision will not necessarily be identical to what ends up as suffix of the soname in LIBDIR. The formula to form the filename’s suffix is, for libtool, “(current – age).age.revision”. This means that for soname, you would need current=3, revision=0 and age=1.

The VERSION part

In case you want compatibility with or use libtool’s -version-info feature, the document libtool/version.html on states:

The rules of thumb, when dealing with these values are:

  • Increase the current value whenever an interface has been added, removed or changed.
  • Always increase the revision value.
  • Increase the age value only if the changes made to the ABI are backward compatible.

The libtool’s -version-info feature‘s updating-version-info part of libtool’s docs states:

  1. Start with version information of ‘0:0:0’ for each libtool library.
  2. Update the version information only immediately before a public release of your software. More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster.
  3. If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
  4. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
  5. If any interfaces have been added since the last public release, then increment age.
  6. If any interfaces have been removed or changed since the last public release, then set age to 0.

When you don’t care about compatibility with libtool’s -version-info feature, then you can take the following simplified rules for VERSION:

  • SOVERSION = Major version
  • Major version: increase it if you break ABI compatibility
  • Minor version: increase it if you add ABI compatible features
  • Patch version: increase it for bug fix releases.

Examples when these simplified rules are or can be applicable is in build environments like cmake, meson and qmake. When you use autotools you will be using libtool and then they ain’t applicable.


For the API version I will use the rules from You can also use the semver rules for your package’s version:

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards-compatible manner, and
  3. PATCH version when you make backwards-compatible bug fixes.

When you have an API, that API can change over time. You typically want to version those API changes so that the users of your library can adopt to newer versions of the API while at the same time other users still use older versions of your API. For this we can follow section 4.3. called “multiple libraries versions” of the autotools mythbuster documentation. It states:

In this situation, the best option is to append part of the library’s version information to the library’s name, which is exemplified by Glib’s > soname. To do so, the declaration in the has to be like this:


libtest_1_0_la_LDFLAGS = -version-info 0:0:0

The pkg-config file

Many people use many build environments (autotools, qmake, cmake, meson, you name it). Nowadays almost all of those build environments support pkg-config out of the box. Both for generating the file as for consuming the file for getting information about dependencies.

I consider it a necessity to ship with a useful and correct pkg-config .pc file. The filename should be /usr/lib/pkgconfig/package-APIVERSION.pc for soname In our example that means /usr/lib/pkgconfig/package-4.3.pc. We’d use the command pkg-config package-4.3 –cflags –libs, for example.

Examples are GLib’s pkg-config file, located at /usr/lib/pkgconfig/glib-2.0.pc

The include path

I consider it a necessity to ship API headers in a per API-version different location (like for example GLib’s, at /usr/include/glib-2.0). This means that your API version number must be part of the include-path.

For example using earlier mentioned API-version 4.3, /usr/include/package-4.3 for /usr/lib/ having /usr/lib/pkg-config/package-4.3.pc

What will the linker typically link with?

The linker will for -lpackage-4.3 typically link with /usr/lib/ or with – age). Noting that the part that is calculated as (current – age) in this example is often, for example in cmake and meson, referred to as the SOVERSION. With SOVERSION the soname template in LIBDIR is

What is wrong?

Not doing any versioning

Without versioning you can’t make any API or ABI changes that wont break all your users’ code in a way that could be managable for them. If you do decide not to do any versioning, then at least also don’t put anything behind the .so part of your so’s filename. That way, at least you wont break things in spectacular ways.

Coming up with your own versioning scheme

Knowing it better than the rest of the world will in spectacular ways make everything you do break with what the entire rest of the world does. You shouldn’t congratulate yourself with that. The only thing that can be said about it is that it probably makes little sense, and that others will probably start ignoring your work. Your mileage may vary. Keep in mind that without a correct SOVERSION, certain things will simply not work correct.

In case of libtool: using your package’s (semver) release numbering for current, revision, age

This is similarly wrong to ‘Coming up with your own versioning scheme’.

The Libtool documentation on updating version info is clear about this:

Never try to set the interface numbers so that they correspond to the release number of your package. This is an abuse that only fosters misunderstanding of the purpose of library versions.

This basically means that once you are using libtool, also use libtool’s versioning rules.

Refusing or forgetting to increase the current and/or SOVERSION on breaking ABI changes

The current part of the VERSION (current, revision and age) minus age, or, SOVERSION is/are the most significant field(s). The current and age are usually involved in forming the so called SOVERSION, which in turn is used by the linker to know with which ABI version to link. That makes it … damn important.

Some people think ‘all this is just too complicated for me’, ‘I will just refuse to do anything and always release using the same version numbers’. That goes spectacularly wrong whenever you made ABI incompatible changes. It’s similarly wrong to ‘Coming up with your own versioning scheme’.

That way, all programs that link with your shared library can after your shared library gets updated easily crash, can corrupt data and might or might not work.

By updating the current and age, or, SOVERSION you will basically trigger people who manage packages and their tooling to rebuild programs that link with your shared library. You actually want that the moment you made breaking ABI changes in a newer version of it.

When you don’t want to care about libtool’s -version-info feature, then there is also a set of more simple to follow rules. Those rules are for VERSION:

  • SOVERSION = Major version (with these simplified set of rules, no subtracting of current with age is needed)
  • Major version: increase it if you break ABI compatibility
  • Minor version: increase it if you add ABI compatible features
  • Patch version: increase it for bug fix releases.

What isn’t wrong?

Not using libtool (but nonetheless doing ABI versioning right)

GNU libtool was made to make certain things more easy. Nowadays many popular build environments also make things more easy. Meanwhile has GNU libtool been around for a long time. And its versioning rules, commonly known as the current:revision:age field as parameter for -verison-info, got widely adopted.

What GNU libtool did was, however, not really a standard. It’s is one interpretation of how to do it. And a rather complicated one, at that.

Please let it be crystal clear that not using libtool does not mean that you can do ABI versioning wrong. Because very often people seem to think that they can, and think they’ll still get out safely while doing ABI versioning completely wrong. This is not the case.

Not having a APIVERSION at all

It isn’t wrong not to have an APIVERSION in the soname. It however means that you promise to not ever break API. Because the moment you break API, you disallow your users to stay on the old API for a little longer. They might both have programs that use the old and that use the new API. Now what?

When you have an APIVERSION then you can allow the introduction of a new version of the API while simultaneously the old API remains available on a user’s system.

Using a different naming-scheme for APIVERSION

I used the MAJOR.MINOR version numbers from semver to form the APIVERSION. I did this because only the MAJOR and the MINOR are technically involved in API changes (unless you are doing semantic versioning wrong – in which case see ‘Coming up with your own versioning scheme’).

Some projects only use MAJOR. Examples are Qt which puts the MAJOR number behind the Qt part. For example (so that’s “Qt” + MAJOR + Module). The GLib world, however, uses “g” + Module + “-” + MAJOR + “.0″ as they have releases like 2.2, 2.3, 2.4 that are all called I guess they figured that maybe someday in their 2.x series, they could use that MINOR field?

DBus seems to be using a similar thing to GLib, but then without the MINOR suffix: For their GLib integration they also use it as

Who is right, who is wrong? It doesn’t matter too much for your APIVERSION naming scheme. As long as there is a way to differentiate the API in a) the include path, b) the pkg-config filename and c) the library that will be linked with (the -l parameter during linking/compiling). Maybe someday a standard will be defined? Let’s hope so.

Differences in interpretation per platform


FreeBSD’s Shared Libraries of Chapter 5. Source Tree Guidelines and Policies states:

The three principles of shared library building are:

  1. Start from 1.0
  2. If there is a change that is backwards compatible, bump minor number (note that ELF systems ignore the minor number)
  3. If there is an incompatible change, bump major number

For instance, added functions and bugfixes result in the minor version number being bumped, while deleted functions, changed function call syntax, etc. will force the major version number to change.

I think that when using libtool on a FreeBSD (when you use autotools), that the platform will provide a variant of libtool’s scripts that will convert earlier mentioned current, revision and age rules to FreeBSD’s. The same goes for the VERSION variable in cmake and qmake. Meaning that with those tree build environments, you can just use the rules for GNU libtool’s -version-info.

I could be wrong on this, but I did find mailing list E-mails from ~ 2011 stating that this SNAFU is dealt with. Besides, the *BSD porters otherwise know what to do and you could of course always ask them about it.

Note that FreeBSD’s rules are or seem to be compatible with the rules for VERSION when you don’t want to care about libtool’s -version-info compatibility. However, when you are porting from a libtoolized project, then of course you don’t want to let newer releases break against releases that have already happened.

Modern Linux distributions

Nowadays you sometimes see things like /usr/lib/$ARCH/ linking to /lib/$ARCH/ I have no idea how this mechanism works. I suppose this is being done by packagers of various Linux distributions? I also don’t know if there is a standard for this.

I will update the examples and this document the moment I know more and/or if upstream developers need to worry about it. I think that using GNUInstallDirs in cmake, for example, makes everything go right. I have not found much for this in qmake, meson seems to be doing this by default and in autotools you always use platform variables for such paths.

As usual, I hope standards will be made and that the build environment and packaging community gets to their senses and stops leaving this into the hands of developers. I especially think about qmake, which seems to not have much at all to state that standardized installation paths must be used (not even a proper way to define a prefix).

Questions that I can imagine already exist

Why is there there a difference between APIVERSION and VERSION?

The API version is the version of your programmable interfaces. This means the version of your header files (if your programming language has such header files), the version of your pkgconfig file, the version of your documentation. The API is what software developers need to utilize your library.

The ABI version can definitely be different and it is what programs that are compiled and installable need to utilize your library.

An API breaks when recompiling the program without any changes, that consumes a, is not going to succeed at compile time. The API got broken the moment any possible way package’s API was used, wont compile. Yes, any way. It means that a should be started.

An ABI breaks when without recompiling the program, replacing a with a or a (or later) as is not going to succeed at runtime. For example because it would crash, or because the results would be wrong (in any way). It implies that shouldn’t be overwritten, but should be started.

For example when you change the parameter of a function in C to be a floating point from a integer (and/or the other way around), then that’s an ABI change but not neccesarily an API change.

What is this SOVERSION about?

In most projects that got ported from an environment that uses GNU libtool (for example autotools) to for example cmake or meson, and in the rare cases that they did anything at all in a qmake based project, I saw people converting the current, revision and age parameters that they passed to the -version-info option of libtool to a string concatenated together using (current – age), age, revision as VERSION, and (current – age) as SOVERSION.

I wanted to use the exact same rules for versioning for all these examples, including autotools and GNU libtool. When you don’t have to (or want to) care about libtool’s set of (for some people, needlessly complicated) -version-info rules, then it should be fine using just SOVERSION and VERSION using these rules:

  • SOVERSION = Major version
  • Major version: increase it if you break ABI compatibility
  • Minor version: increase it if you add ABI compatible features
  • Patch version: increase it for bug fix releases.

I, however, also sometimes saw variations that are incomprehensible with little explanation and magic foo invented on the spot. Those variations are probably wrong.

In the example I made it so that in the root build file of the project you can change the numbers and calculation for the numbers. However. Do follow the rules for those correctly, as this versioning is about ABI compatibility. Doing this wrong can make things blow up in spectacular ways.

The examples

qmake in the qmake-example

Note that the VERSION variable must be filled in as “(current – age).age.revision” for qmake (to get 2.1.0 at the end, you need VERSION=2.1.0 when current=3, revision=0 and age=1)

To try this example out, go to the qmake-example directory and type

$ cd qmake-example
$ mkdir=_test
$ qmake PREFIX=$PWD/_test
$ make
$ make install

This should give you this:

$ find _test/
├── include
│   └── qmake-example-4.3
│       └── qmake-example.h
└── lib
    ├── ->
    ├── ->
    ├── ->
    └── pkgconfig
        └── qmake-example-4.3.pc

When you now use pkg-config, you get a nice CFLAGS and LIBS line back (I’m replacing the current path with $PWD in the output each time):

$ export PKG_CONFIG_PATH=$PWD/_test/lib/pkgconfig
$ pkg-config qmake-example-4.3 --cflags
$ pkg-config qmake-example-4.3 --libs
-L$PWD/_test/lib -lqmake-example-4.3

And it means that you can do things like this now (and people who know about pkg-config will now be happy to know that they can use your library in their own favorite build environment).

$ export LD_LIBRARY_PATH=$PWD/_test/lib
$ echo -en "#include <qmake-example.h>\nmain() {} " > test.cpp
$ g++ -fPIC test.cpp -o test.o `pkg-config qmake-example-4.3 --libs --cflags`

You can see that it got linked to, where that 2 at the end is (current – age).

$ ldd test.o (0xb77b0000) => $PWD/_test/lib/ (0xb77a6000) => /usr/lib/i386-linux-gnu/ (0xb75f5000) => /lib/i386-linux-gnu/ (0xb759e000) => /lib/i386-linux-gnu/ (0xb7580000) => /lib/i386-linux-gnu/ (0xb73c9000)
    /lib/ (0xb77b2000)

cmake in the cmake-example

Note that the VERSION property on your library target must be filled in with “(current – age).age.revision” for cmake (to get 2.1.0 at the end, you need VERSION=2.1.0 when current=3, revision=0 and age=1. Note that in cmake you must also fill in the SOVERSION property as (current – age), so SOVERSION=2 when current=3 and age=1).

To try this example out, go to the cmake-example directory and do

$ cd cmake-example
$ mkdir _test
-- Configuring done
-- Generating done
-- Build files have been written to: .
$ make
[ 50%] Building CXX object src/libs/cmake-example/CMakeFiles/cmake-example.dir/cmake-example.cpp.o
[100%] Linking CXX shared library
[100%] Built target cmake-example
$ make install
[100%] Built target cmake-example
Install the project...
-- Install configuration: ""
-- Installing: $PWD/_test/lib/
-- Up-to-date: $PWD/_test/lib/
-- Up-to-date: $PWD/_test/lib/
-- Up-to-date: $PWD/_test/include/cmake-example-4.3/cmake-example.h
-- Up-to-date: $PWD/_test/lib/pkgconfig/cmake-example-4.3.pc

This should give you this:

$ tree _test/
├── include
│   └── cmake-example-4.3
│       └── cmake-example.h
└── lib
    ├── ->
    ├── ->
    └── pkgconfig
        └── cmake-example-4.3.pc

When you now use pkg-config, you get a nice CFLAGS and LIBS line back (I’m replacing the current path with $PWD in the output each time):

$ pkg-config cmake-example-4.3 --cflags
$ pkg-config cmake-example-4.3 --libs
-L$PWD/_test/lib -lcmake-example-4.3

And it means that you can do things like this now (and people who know about pkg-config will now be happy to know that they can use your library in their own favorite build environment):

$ echo -en "#include <cmake-example.h>\nmain() {} " > test.cpp
$ g++ -fPIC test.cpp -o test.o `pkg-config cmake-example-4.3 --libs --cflags`

You can see that it got linked to, where that 2 at the end is the SOVERSION. This is (current – age).

$ ldd test.o (0xb7729000) => $PWD/_test/lib/ (0xb771f000) => /usr/lib/i386-linux-gnu/ (0xb756e000) => /lib/i386-linux-gnu/ (0xb7517000) => /lib/i386-linux-gnu/ (0xb74f9000) => /lib/i386-linux-gnu/ (0xb7342000)
    /lib/ (0xb772b000)

autotools in the autotools-example

Note that you pass -version-info current:revision:age directly with autotools. The libtool will translate that to (current – age).age.revision to form the so’s filename (to get 2.1.0 at the end, you need current=3, revision=0, age=1).

To try this example out, go to the autotools-example directory and do

$ cd autotools-example
$ mkdir _test
$ libtoolize
$ aclocal
$ autoheader
$ autoconf
$ automake --add-missing
$ ./configure --prefix=$PWD/_test
$ make
$ make install

This should give you this:

$ tree _test/
├── include
│   └── autotools-example-4.3
│       └── autotools-example.h
└── lib
    ├── libautotools-example-4.3.a
    ├── ->
    ├── ->
    └── pkgconfig
        └── autotools-example-4.3.pc

When you now use pkg-config, you get a nice CFLAGS and LIBS line back (I’m replacing the current path with $PWD in the output each time):

$ export PKG_CONFIG_PATH=$PWD/_test/lib/pkgconfig
$ pkg-config autotools-example-4.3 --cflags
$ pkg-config autotools-example-4.3 --libs
-L$PWD/_test/lib -lautotools-example-4.3

And it means that you can do things like this now (and people who know about pkg-config will now be happy to know that they can use your library in their own favorite build environment):

$ echo -en "#include <autotools-example.h>\nmain() {} " > test.cpp
$ export LD_LIBRARY_PATH=$PWD/_test/lib
$ g++ -fPIC test.cpp -o test.o `pkg-config autotools-example-4.3 --libs --cflags`

You can see that it got linked to, where that 2 at the end is (current – age).

$ ldd test.o (0xb778d000) => $PWD/_test/lib/ (0xb7783000) => /usr/lib/i386-linux-gnu/ (0xb75d2000) => /lib/i386-linux-gnu/ (0xb757b000) => /lib/i386-linux-gnu/ (0xb755d000) => /lib/i386-linux-gnu/ (0xb73a6000)
    /lib/ (0xb778f000)

meson in the meson-example

Note that the version property on your library target must be filled in with “(current – age).age.revision” for meson (to get 2.1.0 at the end, you need version=2.1.0 when current=3, revision=0 and age=1. Note that in meson you must also fill in the soversion property as (current – age), so soversion=2 when current=3 and age=1).

To try this example out, go to the meson-example directory and do

$ cd meson-example
$ mkdir -p _build/_test
$ cd _build
$ meson .. --prefix=$PWD/_test
$ ninja
$ ninja install

This should give you this:

$ tree _test/
├── include
│   └── meson-example-4.3
│       └── meson-example.h
└── lib
    └── i386-linux-gnu
        ├── ->
        ├── ->
        └── pkgconfig
            └── meson-example-4.3.pc

When you now use pkg-config, you get a nice CFLAGS and LIBS line back (I’m replacing the current path with $PWD in the output each time):

$ export PKG_CONFIG_PATH=$PWD/_test/lib/i386-linux-gnu/pkgconfig
$ pkg-config meson-example-4.3 --cflags
$ pkg-config meson-example-4.3 --libs
-L$PWD/_test/lib -lmeson-example-4.3

And it means that you can do things like this now (and people who know about pkg-config will now be happy to know that they can use your library in their own favorite build environment):

$ echo -en "#include <meson-example.h>\nmain() {} " > test.cpp
$ export LD_LIBRARY_PATH=$PWD/_test/lib/i386-linux-gnu
$ g++ -fPIC test.cpp -o test.o `pkg-config meson-example-4.3 --libs --cflags`

You can see that it got linked to, where that 2 at the end is the soversion. This is (current – age).

$ ldd test.o (0xb772e000) => $PWD/_test/lib/i386-linux-gnu/ (0xb7724000) => /usr/lib/i386-linux-gnu/ (0xb7573000) => /lib/i386-linux-gnu/ (0xb751c000) => /lib/i386-linux-gnu/ (0xb74fe000) => /lib/i386-linux-gnu/ (0xb7347000)
    /lib/ (0xb7730000)

Scheiding der machten

Dien Francken, heeft die als staatsecretaris niet de eed gezworen op onze Belgische grondwet?

Want beweren dat zijn hypothetische aannamens boven een beslissing van het gerecht staan, gaat tegen één van de wetten van onze grondwet in. Namelijk de scheiding der machten. Iemand die in functie is, gezworen heeft op die grondwet en daar totaal tegen in gaat begaat meineed en is strafbaar.

Een staatssecretarisch die zijn eed niet kan houden en die geen respect heeft voor de Belgische grondwet kan wat mij betreft niet aanblijven. Hoe populair hij door zijn populistische zever ook is.

The upcoming NATO top

I said it before, we shouldn’t finance the US’s war-industry any longer. It’s not a reliable partner.

I’m sticking to my guns on this one,

Let’s build ourselves a European army, utilizing European technology. Build, engineered and manufactured by Europeans.

We engineers are ready. Let us do it.

Let’s create Europe’s own military branch

Merkel and Macron should use everything in their economic power to invest in our own European Military.

For example whenever the ECB must pump money in the EU-system, it could do that by increased spending on European military.

This would be a great way to increase the EURO inflation to match the ‘below but near two percent annual inflation’ target.

However. The EU budget for military should not go to NATO. Right now it should go to EU’s own national armies. NATO is more or less the United State’s military influence in Europe. We’ve seen last G7 that we can’t rely on the United States’ help.

Therefor, it should use exclusively European suppliers for military hardware. We don’t want to spend EUROs outside of our EU system. Let the money circulate within our EU economy. This implies no F-35 for Belgium. Instead, for example the Eurofighter Typhoon. The fact that Belgium can’t deliver the United States’s nuclear weapons without their F-35, means that the United States should take their nuclear bombs back. There is no democratic legitimacy to keep them in Belgium anyway.

It’s also time to create a pillar similar to the European Union: a military branch of the EU.

Already are Belgium and The Netherlands sharing military marine and air force resources. Let’s extend this principle to other EU countries.

PGP voor militaire zaken, nee?

Wordt het eens geen tijd dat ons centrum voor cybersecurity overheidsdiensten zoals het Belgisch leger oplegt om steeds a.d.h.v. met bv. PGP (minimaal) getekende (en hopelijk ook geëncrypteerde) E-mails te communiceren? Ja ja. We kunnen ze zelfs encrypteren. Hightech at Belgium. Stel je dat maar eens voor. Waanzin!

Stel je voor. Men zou zowel de E-mail (de content, het bericht zelf) kunnen verifiëren, als de afzender als dat men tijdens de transit én opslag van het bericht de inhoud zou kunnen encrypteren. Bij een eventueel “onafhankelijk” onderzoek zouden we (wiskundige) garanties hebben dat één en ander nu exact is zoals hoe het toen verstuurd werd.

Allemaal zaken die erg handig zouden geweest zijn in de saga over de E-mails over of onze F-16 vliegtuigen langer kunnen vliegen of niet.

Bij de ICT diensten van de oppositiepartijen zou men dan een opleiding van een halfuurtje kunnen krijgen over hoe ze met PGP in de hand één en ander cryptografisch kunnen verifiëren.

ps. Ik weet ook wel dat, in het wereldje waar het over gaat, nu net het feit dat bepaalde zaken achteraf niet meer te achterhalen zijn als waardevolle feature gezien wordt.

Wij hebben in Leuven de beste cryptografen van de wereld zitten. Maar ons Belgisch leger kan dit niet implementeren voor hun E-mails?

To be able to think, you have to risk being offensive

I mean, look at the conversation we’re having right now. You’re certainly willing to risk offending me in the pursuit of truth. Why should you have the right to do that? It’s been rather uncomfortable.

— Jordan Peterson, 2018

Verkoop met verlies

Vandaag wil ik de aandacht op een Belgische wet over het verkopen met verlies. Ons land verbiedt, bij wet, elke handelaar een goed met verlies te verkopen. Dat is de regel, in ons België.

Die regel heeft (terecht) uitzonderingen. De definitie van de uitzondering wil zeggen dat ze niet de regel zijn: de verkoop met verlies is in België slechts per uitzondering toegestaan:

  • naar aanleiding van soldenverkoop of uitverkoop;
  • met als doel de goederen die vatbaar zijn voor snel bederf van de hand te doen als hun bewaring niet meer kan worden verzekerd;
  • ten gevolge externe omstandigheden;
  • goederen die technisch voorbijgestreefd zijn of beschadigd zijn;
  • de noodzakelijkheid van concurrentie.

Ik vermoed dat onze wet bestaat om oneerlijke concurrentie te bestrijden. Een handelaar kan dus niet een bepaald product (bv. een game console) tegen verlies verkopen om zo marktdominantie te verkrijgen voor een ander product uit zijn gamma (bv. games), bv. met als doel concurrenten uit de markt te weren.

Volgens mij is het daarom zo dat, moest een game console -producent met verlies een console verkopen, dit illegaal is in België.

Laten we aannemen dat game console producenten, die actief zijn in (de verkoop in) België, de Belgische wet volgen. Dan volgt dat ze hun game consoles niet tegen verlies verkopen. Ze maken dus winst. Moesten ze dat niet doen dan moeten ze voldoen aan uitzonderlijke voorwaarden, in de (eerder vermelde) Belgische wet, die hen toelaat wel verlies te maken. In alle andere gevallen zouden ze in de ontwettigheid verkeren. Dat is de Belgische wet.

Dat maakt dat de aanschaf van zo’n game console, als Belgisch consument, betekent dat de producent -en verkoper een zekere winst hebben gemaakt door mijn aankoop. Er is dus geen sprake van verlies. Tenzij de producent -of verkoper in België betrokken is bij onwettige zaken.

Laten we aannemen dat we op zo’n console, na aanschaf, een andere software willen draaien. Dan kan de producent/verkoper dus niet beweren dat zijn winst gemaakt wordt door zaken die naderhand verkocht zouden worden (a.d.h.v. bv. originele software).

Hun winst is met andere woorden al gemaakt. Op de game console zelf. Indien niet, dan zou de producent of verkoper in onwettigheid verkeren (in België). Daarvan nemen we aan dat dit zo niet verlopen is. Want anders zou men het goed niet mogen verkopen. Het goed is wel verkocht. Volgens Belgische wetgeving (toch?).

Indien niet, dan is de producent -en of verkoper verantwoordelijk. In geen geval de consument.

RE: Bye Facebook

Wim made a stir in the land of the web. Good for Wim that he rid himself of the shackles of social media.

But how will we bring a generation of people, who are now more or less addicted to social media, to a new platform? And what should that platform look like?

I’m not a anthropologist, but I believe human nature of organizing around new concepts and techniques is that we, humans, start central and monolithic. Then we fine-tune it. We figure out that the central organization and monolithic implementation of it becomes a limiting factor. Then we decentralize it.

The next step for all those existing and potential so-called ‘online services’ is to become fully decentralized.

Every family or home should have its own IMAP and SMTP server. Should that be JMAP instead? Probably. But that ain’t the point. The fact that every family or home will have its own, is. For chat, XMPP’s s2s is like SMTP. Postfix is an implementation of SMTP like ejabberd is for XMPP’s s2s. We have Cyrus, Dovecot and others for IMAP, which is the c2s of course. And soon we’ll probably have JMAP, too. Addressability? IPv6.

Why not something like this for social media? For the next online appliance, too? Augmented reality worlds can be negotiated in a distributed fashion. Why must Second Life necessarily be centralized? Surely we can run Linden Lab’s server software, locally.

Simple, because money is not interested in anything non-centralized. Not yet.

In the other news, the Internet stopped working truly well ever since money became its driving factor.

ps. The surest way to corrupt a youth is to instruct him to hold in higher esteem those who think alike than those who think different. Quote by Friedrich Nietzsche.

Asynchronous undoable and redoable APIs

Combining QFuture with QUndoCommand made a lot of sense for us. The undo and the redo methods of the QUndoCommand can also be asynchronous, of course. We wanted to use QFuture without involving threads, because our asynchronosity is done through a process and IPC, and not a thread. It’s the design mistake of QtConcurrent‘s run method, in my opinion. That meant using QFutureInterface instead (which is undocumented, but luckily public – so it’ll remain with us until at least Qt’s 6.y.z releases).

So how do we make a QUndoCommand that has a undo, and that has a redo method that returns a asynchronous QFuture<ResultType>?

We just did that, today. I’m very satisfied with the resulting API and design. It might have helped if QUndoStack would be a QUndoStack<T> and QUndoCommand would have been a QUndoCommand<T> with undo and redo’s return type being T. Just an idea for the Qt 6.y.z developers.

Duck typing

Imagine you have a duck. Imagine you have a wall. Now imagine you throw the duck with a lot of force against a wall. Duck typing means that the duck hitting the wall quacks like a duck would.

ps. Replace wall with API and duck with ugly stupid script written by an idiot. You can leave quacks.

Binaries in git, release numbering, Git-Flow and Scrum at the CIA

Funny how even the software developers at the CIA have problems with idiots who want to put binaries in git. They also know about Git-Flow, my preferred git branching workflow. I kind of wonder how come, if they know about Git-Flow, we see so few leaked NSA and CIA tools with correct semver versioning. Sometimes it’s somewhat okayish, like you can see here. But v1.0-RC3 is not really semver if you see how they got there here. To start with, your alpha versions start with 0.0.x. So where are all those versions under 0.0.x that happened before release candidate 3? 1.0, 1.1-beta, 1.0-phase2, 1.0-beta1-, 1.0-beta-7. WTF guys. That’s not a good versioning scheme. Just call it 0.0.1, 0.0.2, 0.1.0, 0.1.1, 0.1.2 for the betas. And when the thing sees first usage, start calling it 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, 1.2.0 etc. What’s wrong with that? And how are all these words like alha-1, beta-2, phase2, etc any better? Maybe just fire your release maintainer! Admittedly for that 2.0.x series they at least tried to get it right.

The point is that packaging tools can be configured to let other packages depend on these version numbers. In x.y.z the x number has implications on API incompatibility whereas the y number can be used for compatible feature additions.

I can imagine that different malwares, exploits, rootkits, intrusion tools they develop would pose incompatibilities with each other, and that for example the NSA and CIA want to share libraries and link without having to recompile or repackage. So versioning to indicate ABI and API compatibility wouldn’t be a bad idea. Let’s hope in the next round of massive leaks we see them having learned good software development processes and practices.

They are doing Scrum sprints and do retrospectives, though. That’s not so bad.

Beste VRT, over PGP

PGP, Pretty Good Privacy, is niet enkel te koop op Het Internet; het is zowel gratis als dat het open source is. Dat wil zeggen dat iedereen op deze planeet de broncode van PGP kan downloaden, compileren en aanpassen en dat iedereen het op een telefoon kan zetten.

Velen gebruiken dan ook zulke encryptiesoftware voor allerlei redenen. Vaak zonder dat ze het door hebben (https websites, de diensten van je bank, online aankopen, Whatsapp berichten, en zo verder). Soms hebben ze het wel door (dat zijn dan vaak techneuten).

Enkelingen doen dat om hun communicatie over criminele plannen te versleutelen. Maar velen anderen doen dat om hun bedrijfsgegevens, privacy, persoonlijke data en zo verder te beveiligen. Er zouden ook overheden zijn, naar het schijnt, zoals de onze, bijvoorbeeld, die het veelvuldig gebruiken. Volgens geruchten gebruiken alle militairen het. Ik ben er van overtuigd dat jullie werkgever, de VRT, het ook heel veel gebruikt en zelfs oplegt. Een beetje serieus journalist gebruikt het tegenwoordig ook voor, laat ik hopen, alles.

PGP is niet illegaal. Het versleutelen van berichten is niet illegaal. Dat de politie het daarom niet meer kan lezen, is op zichzelf niet illegaal. Er staat in onze Belgische wetgeving helemaal niets over het illegaal zijn van het versleutelen van berichten. Er staat in onze Belgische wetgeving helemaal niets over het illegaal zijn van bv. software zoals PGP.

Versleutelen van berichten bestaat ook al eeuwen. Nee, millennia. Misschien zelfs wel al tienduizenden jaren. Kinderen doen het en leren het. Misschien niet op al te professionele manier. Maar sommige kinderlijk eenvoudige encryptietechnieken zijn theoretisch onkraakbaar. Zoals bv. de one time pad

Sterker nog, onze Belgische universiteiten staan over de hele wereld bekend om haar wiskundigen die zich met cryptografie bezig houden. De wereldwijd belangrijkste encryptiestandaard, Rijndael, werd door Leuvense studenten ontwikkeld. Die PGP software gebruikt die encryptiestandaard, ook. Het staat tegenwoordig bekend als de Advanced Encryption Standard, AES, en wordt oa. militair vrijwel overal ingezet.

Dat een aantal mensen van het gerecht en de politie het lastig vinden dat een aantal criminelen gebruik maken van software zoals PGP, betekent op geen enkele manier dat het gebruik van en het voorzien van telefoons met PGP, op zichzelf, illegaal is. Helemaal niet. Het is dus vrij onnozel om in jullie journaal te laten uitschijnen als zou dat wel het geval zijn. Dat is het niet. Zeker in extreme tijden zoals nu is het gevaarlijk wanneer de media zoiets doet uitschijnen. Straks maakt men de gewone burger weer bang over allerlei dingen, en dan gaat de politiek domme eisen stellen zoals het verbieden van encryptie.

Het versleutelen van berichten is een erg belangrijk onderdeel, in de technologie, om die technologie veilig en betrouwbaar te laten werken. Het ontbreken van de mogelijkheid om berichten en gegevens te versleutelen zou werkelijk catastrofale gevolgen hebben.

Het zou ook geen enkele crimineel weerhouden toch één en ander te encrypteren. Encryptie verbieden zou letterlijk alleen maar de onschuldige burger schaden. De crimineel zou er net voordeel uit halen; de crimineel wordt het daardoor plots veel eenvoudiger gemaakt om bij onschuldige burgers (die geen encryptie meer kunnen gebruiken) digitaal in te breken.

Denk in deze extreme tijden goed na wat je in jullie mediakanaal, het nationale nieuws, doet uitschijnen. Als techneut vind ik het bijzonder onverantwoordelijk van jullie. OOK en vooral wanneer de bedoeling was om het nieuws zo dom mogelijk te brengen. Alsof onze burgers het niet zouden aankunnen om correct geïnformeerd te worden over deze materie.

Scrum is (best done) like a soccer team

As a freelancer I saw many companies, many situations and worked with many Project Managers, Product Owners, Scrum Masters and god knows what names the HR department came up with.

What is most important, in my experience, is that the people leading the team try to focus the people in the group on as few common goals as possible during one sprint. The more stories or goals the team has to finish, the more individualism and the fewer things will get done (with done being defined by your definition of done).

Differently put you should try to make your team work like how a soccer team plays. You try to make three, four or five goals per sprint. But you do this as a team.

Example: When a story isn’t finished at the end of the sprint; it’s the team’s fault. Not the fault of the one guy that worked on it. The team has to find a solution. If it’s always the same guy being lazy, that’s not the project’s or the team’s results. You or HR deals with that guy later. Doing so is outside of Scrum’s scope. It’s not for your retrospective discussion. But do sanction the team for not delivering.

Another example is not to put too much stories on the task board and yet to keep stories as small and/or well defined as possible. Too much stories or too large stories will result in every individual picking a different story (or subtask of the larger story) to be responsible for. At the end of the sprint none of these will be really finished. And the developers in the team won’t care about the other features being developed during the sprint. So they will dislike having to review other people’s features. They’ll have difficulty finding a reviewer. They won’t communicate with each other. They’ll become careless and dispassionate.

Your planning caused that. That makes you a bad team player. The coach is part of the team.