Free Pascal is designed to be cross-platform. This means that the basic RTL units are usable on all
platforms, and the compiler behaves the same on all platforms (as far as possible). The
Object Pascal language is the same on all platforms. Nevertheless, FPC comes with a lot
of units that are not portable, but provide access to all possibilities that a platform
provides.
The following are some guidelines to consider when writing portable code:
- Avoid system-specific units. The system unit, the objects and classes units and the
SysUtils unit are guaranteed to work on all systems. So is the DOS unit, but that is
deprecated.
- Avoid direct hardware access. Limited, console-like hardware access is available for
most platforms in the Video, Mouse and Keyboard units.
- Do not use hard-coded filename conventions. See below for more information on this.
- Make no assumptions on the internal representation of types. Various processors store
information in different ways (’endianness’).
- If system-specific functionality is needed, it is best to separate this out in a single unit.
Porting efforts will then be limited to re-implementing this unit for the new platform.
- Don’t use assembler, unless you have to. Assembler is processor specific. Some
instructions will not work even on the same processor family.
- Do not assume that pointers and integers have the same size. They do on an Intel 32-bit
processor, but not necessarily on other processors. The PtrInt type is an alias for the
integer type that has the same size as a pointer. SizeInt is used for all size-related
issues.
The system unit contains some constants which describe file access on a system:
-
AllFilesMask
- a file mask that will return all files in a directory. This is * on Unix-like
platforms, and *.* on dos and windows like platforms.
-
LineEnding
- A character or string which describes the end-of-line marker used on the
current platform. Commonly, this is one of #10, #13#10 or #13.
-
LFNSupport
- A boolean that indicates whether the system supports long filenames (i.e. is
not limited to MS-DOS 8.3 filenames).
-
DirectorySeparator
- The character which acts as a separator between directory parts of a
path.
-
DriveSeparator
- For systems that support drive letters, this is the character that is used
to separate the drive indication from the path.
-
PathSeparator
- The character used to separate items in a list (notably, a PATH).
-
maxExitCode
- The maximum value for a process exitcode.
-
MaxPathLen
- The maximum length of a filename, including a path.
-
FileNameCaseSensitive
- A boolean that indicates whether filenames are handled case
sensitively.
-
FileNameCasePreserving
- A boolean that indicates whether case in filenames is preserved
on creation or rename.
-
UnusedHandle
- A value used to indicate an unused/invalid file handle.
-
StdInputHandle
- The value of the standard input file handle. This is not always 0 (zero),
as is commonly the case on Unices.
-
StdOutputHandle
- The value of the standard output file handle. This is not always 1, as
is commonly the case on Unices.
-
StdErrorHandle
- The value of the standard diagnostics output file handle. This is not
always 2, as is commonly the case on Unices.
-
CtrlZMarksEOF
- A boolean that indicates whether the #26 character marks the end of a
file (an old MS-DOS convention).
To ease writing portable filesystem code, the Free Pascal file routines in the system unit and
sysutils unit treat the common directory separator characters (/ and \) as equivalent. That means
that if you use / on a Windows system, it will be transformed to a backslash, and vice
versa.
This feature is controlled by 2 (pre-initialized) variables in the system unit:
-
AllowDirectorySeparators
- A set of characters which, when used in filenames, are treated
as directory separators. They are transformed to the DirectorySeparator character.
-
AllowDriveSeparators
- A set of characters which, when used in filenames, are treated as
drive separator characters. They are transformed to the DriveSeparator character.