Sign in Join
FPDoc Onlineexperiment

File searching

Before you start compiling a program or a series of units, it is important to know where the compiler looks for its source files and other files. In this section we discuss this, and we indicate how to influence this.

Remark: The use of slashes (/) and backslashes (\) as directory separators is irrelevant, the compiler will convert to whatever character is used on the current operating system. Examples will be given using slashes, since this avoids problems on Unixsystems (such as Linux).

Command line files

The file that you specify on the command line, such as in

fpc foo.pp

will be looked for ONLY in the current directory. If you specify a directory in the filename, then the compiler will look in that directory:

fpc subdir/foo.pp

will look for foo.pp in the subdirectory subdir of the current directory.

Under case sensitive file systems (such as Linuxand Unix), the name of this file is case sensitive; under other operating systems (such as DOS, , OS/2) this is not the case.

Unit files

When you compile a unit or program that needs other units, the compiler will look for compiled versions of these units in the following way:

  1. It will look in the current directory.

  2. It will look in the directory where the source file resides.

  3. It will look in the directory where the compiler binary is.

  4. It will look in all the directories specified in the unit search path.

You can add a directory to the unit search path with the () option. Every occurrence of one of these options will insert a directory to the unit search path. i.e. the last path on the command line will be searched first.

The compiler adds several paths to the unit search path:

  1. The contents of the environment variable XXUNITS, where XX must be replaced with one of the supported targets: GO32V2, LINUX,WIN32, OS2, BEOS, FREEBSD, SUNOS, DARWIN (the actual list depends on the available targets).

  2. The standard unit directory. This directory is determined from the FPCDIR environment variable. If this variable is not set, then it is defaulted to the following:

    • On Linux:

        /usr/local/lib/fpc/FPCVERSION
      or
        /usr/lib/fpc/FPCVERSION

      whichever is found first.

    • On other OSes: the compiler binary directory, with ’../’ appended to it, if it exists. For instance, on Windows, this would mean

      C:\FPC\2.6\units\i386-win32

      This is assuming the compiler was installed in the directory

      C:\FPC\2.6

    After this directory is determined, the following paths are added to the search path:

    1. FPCDIR/units/FPCTARGET

    2. FPCDIR/units/FPCTARGET/rtl

    Here target must be replaced by the name of the target you are compiling for: this is a combination of CPU and OS, so for instance

    /usr/local/lib/fpc/2.6/units/i386-linux/

    or, when cross-compiling

    /usr/local/lib/fpc/2.6/units/i386-win32/

The -Fu option accepts a single * wildcard, which will be replaced by all directories found on that location, but not the location itself. For example, given the directories

rtl/units/i386-linux
fcl/units/i386-linux
packages/base
packages/extra

the command

fpc -Fu"*/units/i386-linux"

will have the same effect as

fpc -Furtl/units/i386-linux -Fufcl/units/i386-linux

since both the rtl and fcl directories contain further units/i386-linux subdirectories. The packages directory will not be added, since it doesn’t contain a units/i386-linux subdirectory.

The following command

fpc -Fu"units/i386-linux/*"

will match any directory below the units/i386-linux directory, but will not match the units/i386-linux directory itself, so you should add it manually if you want the compiler to look for files in this directory as well:

fpc -Fu"units/i386-linux" -Fu"units/i386-linux/*"

Note that (for optimization) the compiler will drop any non-existing paths from the search path, i.e. the existence of the path (after wildcard and environment variable expansion) will be tested.

You can see what paths the compiler will search by giving the compiler the -vu option.

Note that unit file paths specified in a config file will be added at the end, while paths specified on the command-line are added at the beginning.

Imagine the following command-line:

fpc -n -Fu/home @cfg  -Fu/usr foo.pp

Where the file cfg has the following contents:

-Fu/etc

This will result in the following search path

Using unit path: /home/
Using unit path: /usr/
Using unit path: /etc/
Using unit path: /data/FPC/installed/3.1.1/

Reverting the order of the files on the command-line :

fpc -n -Fu/usr @cfg  -Fu/home foo.pp

Results in

Using unit path: /usr/
Using unit path: /home/
Using unit path: /etc/
Using unit path: /data/FPC/installed/3.1.1/

Moving the position of @cfg will not change the path:

fpc -n @cfg -Fu/home  -Fu/usr foo.pp

Results in

Using unit path: /home/
Using unit path: /usr/
Using unit path: /etc/
Using unit path: /data/FPC/installed/3.1.1/

On systems where filenames are case sensitive (such as Unixand Linux), the compiler will :

  1. Search for the original file name, i.e. preserves case.

  2. Search for the filename all lowercased.

  3. Search for the filename all uppercased.

This is necessary, since Pascal is case-independent, and the statements Uses Unit1; or uses unit1; should have the same effect.

It will do this first with the extension .ppu (the compiled unit), .pp and then with the extension .pas.

For instance, suppose that the file foo.pp needs the unit bar. Then the command

fpc -Fu.. -Fuunits foo.pp

will tell the compiler to look for the unit bar in the following places:

  1. In the current directory.

  2. In the directory where the compiler binary is (not under Linux).

  3. In the parent directory of the current directory.

  4. In the subdirectory units of the current directory

  5. In the standard unit directory.

Also, unit names that are longer than 8 characters will first be looked for with their full length. If the unit is not found with this name, the name will be truncated to 8 characters, and the compiler will look again in the same directories, but with the truncated name.

If the compiler finds the unit it needs, it will look for the source file of this unit in the same directory where it found the unit. If it finds the source of the unit, then it will compare the file times. If the source file was modified more recent than the unit file, the compiler will attempt to recompile the unit with this source file.

If the compiler doesn’t find a compiled version of the unit, or when the -B option is specified, then the compiler will look in the same manner for the unit source file, and attempt to recompile it.

It is recommended to set the unit search path in the configuration file fpc.cfg. If you do this, you don’t need to specify the unit search path on the command line every time you want to compile something.

Include files

If you include a file in your source with the {$I filename} directive, the compiler will look for it in the following places:

  1. It will look in the path specified in the include file name.

  2. It will look in the directory where the current source file is.

  3. it will look in all directories specified in the include file search path.

You can add files to the include file search path with the or options.

As an example, consider the following include statement in a file units/foo.pp:

{$i ../bar.inc}

Then the following command :

fpc -Iincfiles units/foo.pp

will cause the compiler to look in the following directories for bar.inc:

  1. The parent directory of the current directory.

  2. The units subdirectory of the current directory.

  3. The incfiles subdirectory of the current directory.

Object files

When you link to object files (using the {$L file.o} directive, the compiler will look for this file in the same way as it looks for include files:

  1. It will look in the path specified in the object file name.

  2. It will look in the directory where the current source file is.

  3. It will look in all directories specified in the object file search path.

You can add files to the object file search path with the option.

Configuration file

Not all options must be given on the compiler command line. The compiler can use a configuration file which can contain the same options as on the command line. There can be only one command-line option on each line in the configuration file.

Unless you specify the option, the compiler will look for a configuration file fpc.cfg in the following places:

  • Under Unix(such as Linux)

    1. The current directory.

    2. Your home directory, it looks for .fpc.cfg.

    3. The directory specified in the environment variable PPC_CONFIG_PATH.

    4. in the etc directory above the compiler directory.
      For instance, if the compiler is in /usr/local/bin, it will look in /usr/local/etc.
      See below for some additional information about this point.

    5. The directory /etc.

  • Under all other OSes:

    1. The current directory.

    2. If it is set, the directory specified in the environment variable PPC_CONFIG_PATH.

    3. The directory where the compiler is.

Remark: Note that the compiler directory is determined by the location of the actual compiler binary. This has 2 consequences:

  1. The default installation on unix places this under /usr/local/lib/fpc, or /usr/lib/fpc. It places several symlinks in /usr/local/bin or /usr/bin. These symlinks are not considered when looking for the configuration file(s), so the places to look for the configuration file are /usr/local/lib/fpc/etc, or /usr/lib/fpc/etc.

  2. The fpc command is not the actual compiler binary. The fpc command selects the actual compiler binary based on e.g. the CPU target. The actual compiler binary is called ppcXYZ.

  3. The actual installation directory may vary: /usr/local/bin may be /usr/bin, depending on the packager.

About long filenames

Free Pascalcan handle long filenames on all platforms, except DOS. On Windows, it will use support for long filenames if it is available (which is not always the case on older versions of Windows).

If no support for long filenames is present, it will truncate unit names to 8 characters.

It is not recommended to put units in directories that contain spaces in their names, since the external GNU linker doesn’t understand such filenames.

An experiment, built from development snapshots. Not the official Free Pascal or Lazarus documentation.