Home / Alt manpages / fpc-3.2.2(1)

  • fpc-3.2.2(1)
  • User command
  • linux

Compile a Pascal Program Reliably with FPC 3.2.2

You will compile a Pascal program with the installed Free Pascal Compiler, keep generated files in a build directory, and check which configuration and target the compiler used. Allow about 15 minutes for a first build, including one small diagnostic test. The examples target the installed amd64 Linux package, fp-compiler-3.2.2, version 3.2.2+dfsg-32.

This guide uses the local FPC 3.2.2 manpages. The manpage is a quick reference and warns that the larger compiler manuals can contain newer detail, so treat the command output on your host as the final authority when a project depends on a particular package build.

1. Check the compiler before building

Start without changing files. The short information switches report the compiler version, operating system, processor, target operating system and target processor:

$ command -v fpc
/usr/bin/fpc
$ fpc -iV
3.2.2
$ fpc -iSO
linux
$ fpc -iSP
x86_64
$ dpkg-query -W -f='${Package} ${Version}\n' fp-compiler-3.2.2
fp-compiler-3.2.2 3.2.2+dfsg-32

On this installation, the compiler identifies itself as version 3.2.2 and targets Linux on x86_64. The package version includes a Debian or Ubuntu packaging suffix, which is useful when comparing diagnostics between machines.

Checkpoint: do not continue if command -v fpc resolves to an unexpected installation. A different compiler earlier in PATH can make a correct project appear broken.

2. Compile into a separate build directory

Give FPC your Pascal source file. The -FE option sets the executable and unit output path, -FU places compiled units in a separate directory, and -o gives a program a precise executable name. These options affect generated files, not the source.

$ mkdir -p build/units
$ fpc -FEbuild -FUbuild/units -ohello src/hello.pas
Free Pascal Compiler version 3.2.2+dfsg-32 [2024/01/05]
Target OS: Linux for x86-64
Compiling src/hello.pas
Linking build/hello
... lines compiled, ... sec

Replace src/hello.pas with your source path. The exact line count and elapsed time vary. A successful compile normally leaves the executable at build/hello and unit files under build/units. The command does not need sudo when the project is in a directory you can write.

Run the result and check its status:

$ ./build/hello
Hello from Pascal
$ printf 'exit status: %s\n' "$?"
exit status: 0

The output is determined by your program. Status 0 tells you that this invocation returned successfully; it is not a test of every code path.

3. Make warnings and useful detail visible

The installed configuration enables some defaults, so make diagnostic intent explicit when investigating a build. The -v option takes letters that can be combined. i shows general information, w warnings, n notes, h hints, and u the names of files opened by the compiler.

$ fpc -viwnh -FEbuild -FUbuild/units -ohello src/hello.pas
... compiler information, warnings, notes and hints ...

Use -vu when a unit or include file cannot be found. It can reveal the search path that your normal command hides. The -l option prints a version line at the top, while -h prints the option list and exits. Avoid starting with -va unless you need every diagnostic category: its output can obscure the first real error.

4. Understand the configuration file

FPC reads a configuration file before it processes the remaining command-line options. On Linux, the documented search includes the current directory, ~/.fpc.cfg, a directory named by PPC_CONFIG_PATH, the compiler's installation path and finally /etc. This is why the same command can behave differently in a project directory or under another account.

Inspect the active system configuration without editing it:

$ readlink -f /etc/fpc.cfg
/etc/fpc.cfg
$ sed -n '1,80p' /etc/fpc.cfg

The configuration syntax accepts compiler options, comments beginning with #, and conditional directives such as #IFDEF, #ELSE and #ENDIF. It can also define symbols with #DEFINE and include another file with #INCLUDE. Keep project-specific choices in a project file rather than modifying a package-managed file under /etc.

5. Use a project configuration deliberately

The manpage documents @FILE as a way to read a second configuration file. It is an at-sign followed by the filename, not a -@ option. For a harmless check, create a file such as project.fpc.cfg containing:

# Project-only compiler settings
-Fu./lib
#IFDEF DEBUG
  -gl
#ENDIF

Then invoke the compiler with that file before the source file:

$ fpc @project.fpc.cfg -FEbuild -FUbuild/units -ohello src/hello.pas

Command-line options are still processed after the configuration file. That lets a one-off command override a project default, but it also creates a distraction trap: a setting hidden in a configuration file can be the real reason a build differs from a plain invocation. Use -vu and compare the exact command when debugging.

To test whether the system configuration is supplying required unit paths, use -n, which tells FPC not to read any configuration file:

$ fpc -n -FEbuild -FUbuild/units -ohello src/hello.pas
Fatal: Can't find unit system used by Hello
Fatal: Compilation aborted

The program name and wording can differ. A failure such as this indicates missing compiler paths, not a Pascal syntax error. Remove -n for the ordinary build, or provide a complete project configuration. Do not copy random unit paths from another host.

6. Add checks only while diagnosing

FPC can generate runtime checks including input/output, integer overflow, range and stack checks with -Ci, -Co, -Cr and -Ct. These are useful for a debug build but can change runtime behaviour and performance. Keep them in a named debug configuration and do not assume that a release build has the same checks.

For debugger work, -g adds debugging information and -gw requests DWARF information. The -O options change optimisation, so begin with checks and debugging enabled and optimisation modest, then test the release command separately. Never interpret a clean checked build as proof that untested input is safe.

Some switches change linking rather than compilation. -Cn, also available as -E, omits linking and leaves no runnable executable. -Xst requests static linking, while -Xs strips symbols according to the installed configuration. Use those deliberately and inspect the output with file build/hello or ldd build/hello where appropriate. Static linking can expose missing libraries and licensing or update assumptions; it is not a routine fix for a failed build.

7. Recover from a bad build

Compilation can leave an executable or unit files from an earlier attempt. If the source changes but the output does not, compile to a new name first and compare it:

$ fpc -FEbuild -FUbuild/units -ohello.new src/hello.pas
$ file build/hello.new
$ ./build/hello.new

Only after checking the new program should you replace the old executable. If you used a temporary output name, the recovery action is simply to leave the old file in place and remove the new one with your normal file-management command. Do not use a broad recursive deletion in a project directory just to clear compiler output. Confirm the exact paths first.

Done means

  • fpc -iV reports the expected 3.2.2 compiler.
  • The program builds without elevated privileges into a dedicated build directory.
  • The executable runs and its exit status is checked.
  • You know whether the build used /etc/fpc.cfg, a project file, or -n.
  • Diagnostic, debug and linking switches are deliberate rather than inherited by accident.
  • A failed replacement build cannot silently overwrite the last working executable.