[Qt5-feedback] What is the Qt view of targets, and is it the same as QtSDKs ?

BRM bm_witness at yahoo.com
Wed Jun 15 21:03:47 CEST 2011


----- Original Message ----

> From: Attila Csipa <qt at csipa.in.rs>
> On Wednesday 15 June 2011 16:32:01 you wrote:
> > > number of targets,  but we do not target all possible combinations).
> > I have to  quite disagree. The #if Q_OS stuff compliments the build system
> > and is  quite required.
> 
> It will certainly have to be kept for compatibility  reasons and is certainly 
> convenient for oneliners... BUT (always this but  :). Is it *enough* ? (I'm not 
>
> trying to remove Q_OS and friends, I'm trying  to find an alternative). This 
> tendency is not new, first was the  introduction of scopes in the (q)make 
> system. But we can take it further -  Q_OS or scoping won't really help with 
> resource files (unless you are  willing to maintain several copies), QML files, 
>
> packaging requirements,  platform policies, per distribution optimizations, etc 
>
> (coincidentally, this  is also the reason why Linux distributions don't patch 
> with putting things  into #ifdefs as that would limit the options wrt to 
> language, they just  patch the upstream resources, whether that be c++ or 
> python, resource file  or code). 
> 
> The bottom line is that the basic idea of Qt was to hide away  platform related 
>
> ifdeffing. On the desktop, this worked (and still does)  pretty well, since you 
>
> only had three major platforms, Linux, Mac, Windows,  and Qt never tried to 
> produce distribution-ready output. Unfortunately,  given the number of QtSDK 
> targets nowadays (platforms, distros, devices,  your pick) and type of 
> resources being used, the classic scope {} and #ifdef  to me has the feeling of 
>
> just not cutting it any more.

#ifdef's have their place. Just like GOTO's have their place.
The key is to know when to use them and when not to.

If you end up with massive depths of #ifdef's then you likely have a problem in 
your design/implementation. The original version of my log system had that 
issue, and I redesigned it to solve the issue - using an abstract class to 
define the interface, and then had specific implementations derived from that 
abstract class to meet the different platforms. Where initially the #ifdef's 
were scattered all over the header and implementation files, the new version 
only had a few - in a single implementation file at that. The new design 
drastically reduced their use, improved the readability, and made it very clear 
what each one did. But it goes back to correct use.

Distros mainly focus on aspects that apply to everyone. Qt (and KDE btw) have to 
think of multiple platforms, including providing those platform specific bits 
that the distros (who mainly use Linux or Embedded Linux which are essentially 
the same) don't have to (at least as much).
 
> > As with  any tool, it can - of course - be misused; but it has very
> > appropriate  and valid uses that are not possible using other methods.
> 
> While depending  on the actual case I would agree about convenience, I find 
>"not 
>
> possible  using other methods" a bit too strong of a wording :) Can you share 
> an  example using #ifdef Q_OS_* that say, an integrated .diff approach couldn't 
>
> solve (not saying .diff is the best thing since sliced bread, just using it  as 
>
> an alternative technology example that is familiar to a lot of people)  ?

See the example I provided. In that specific case, the header files are loaded 
at compile time by the pre-processor to provide the correct definitions for 
accessing the various platform dependent objects.
Yes, Qt is built to remove the platform, but there are times when that is not 
possible as with the example I provided - the Win32 interfaces are only 
available on Windows.

Ideally yes, we'd be able to write code that is 100% platform independent, and 
Qt goes a long way to supporting that.
But sometimes you need to interface with platform specific parts - like the 
Windows Event Log - and in those cases you need to have the Q_OS* functionality 
at least in the headers that are included,
but it also has to be complemented by build-time stuff that decides whether or 
not to include the implementation files.

For the example I cited, the Qmake project also has entries in it that add the 
appropriate implementation files that support the platform specific bits so they 
are only built on the corresponding platform.
Something like the following:

*win32* { SOURCES += myLogWin32EventLog.cpp }
else { SOURCES += myLogSysLog.cpp }

(No, that is not an exact quote - just a pseudo version.)

Now generally you are not going to have to deal with it. In fact, in my case 
this is handled internally to the log module I developed - so a user a that 
module will never have to deal with determining which headers to utilize.
This really only applies when you are developing those platform specific bits - 
like supporting the Win32 Service Control Manager in QtService, or MacOSX's 
launchpad, or Linux's systemd; you need to be able to separate out based on 
platforms and to keep it simple. Q_OS* keeps the _headers_ simple; while the 
project file can keep the _build_ simple - the two work in conjunction.

Introducing something like applying patches to header files based on which 
platform you are on is not a solution - that only complicates it as you never 
truly know what your final header file is going to look like. KISS is your 
friend.

Ben



More information about the Qt5-feedback mailing list