When creating units for different target operating systems, you can:
-use an IfDef inside one unified unit
-use include files for different operating systems, along with
separate directories for each OS (/Linux/, /Win32/ /BSD/)
-use a separate unit all together, without includes.. using a different directory
for a different unit. (/source/Linux/, /source/Win32/ /source/BSD/)
The advantages of IfDefs exist generally in smaller situations. The problem with ifdefs is that they become harder to maintain, and bloat the code up a bit in smaller units, and a lot in larger units.
After thinking about it for a while, I feel that includes and separate directories are best. Although one unified unit means that code is easier to glimpse at using today's editors, generally editors can always and do always improve. For example editors in the future will offer "virtual viewing" of source code units (all include files shown in one editor box, instead of them showing as separate files).
The problem with include files is that they are harder to read or search information on, since you have a bunch of source code inside different files (versus having it all in one unit). But with editors improving.. a virtual view of a file will solve this problem. Include files will appear as just one big file, if the user specifies
the editor to view it as so. That is, if editor's become smarter, and handle virtual
viewing (and generally we can see this trend.. as Lazarus IDE already can do a CTRL-CLICK and go directly to the include file).
So although the ctrl-click feature is nice, an even better solution in the future
will be to have a CTRL-CLICK feature, plus a virtual viewing feature.. so that when
you CTRL-CLICK with your mouse over top a declaration, the editor takes you to a
virtual view of several include files unified together appearing as one unit on the
screen. This way, include files will just purely be separate files on the hard drive,
but on the screen they appear to be unified as one large source file.
How to use separate directories with freepascal, to sort out different units for a different Target OS:
Utilize the $(TargetOS) macro
1. Let's say you created a unit called "MiscUtils5", and you want to make it work
with both Linux and Win32.. but there are some differences in the source code
between operating systems. You can create 2 separate MiscUtils5 units. Create
one in a "Linux" directory, and one in a "Win32" directory. The people who use
your unit can specify in their "search directory" the search path along with a
$(TargetOS) macro.
2. When they compile on linux, they would put this in their search directory in the
compiler options:
/somedir/source/$(TargetOS)/
And on win32 they would put this in their search directory:
c:\somedir\source\$(TargetOS)\
The $target macro automatically finds the correct unit, if you have placed your
units into separate directories, and told your users to put this $(TargetOS) macro in
their search directory in compiler options.
It is important the people using the unit are familiar with the $target macro.
Every freepascal user should learn about this if they do not already know about it.
Direct them to a page explaining what the target macro is (or this one) if they
have troubles. Delphi users may be used to the IfDef way of doing things, but best
long term solution for managing code seems to be using include files or separate
units, especially when managing 3 or more operating systems.
To use an analogy:
Imagine how much bloat would be in your help files if you had 5 different
languages: french, english, spanish, german, and chinese? Creating a
separate help file for each language is a better solution.
The same problem exists with automatic source code documentation tools. I find fpdoc is a better solution than something like pasdoc or KOL/MCK's way of embedding help directly inside the source code. When it comes time to make major changes to the unit, or when it comes time to quickly scan through the source code looking for functions, the embedded help gets in the way. And so do IFDEF's. It's better to have help documented external from the source code, especially if you can let your editor take you directly to the help file relating to the declaration your mouse is over (CTRL-F1).
|