[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