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

Your Pascal build works on one machine and dies on another, and the only difference is a config file you forgot existed. This guide compiles a program with the installed Free Pascal Compiler (fpc), keeps generated files in a build directory, and shows 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.

The local FPC 3.2.2 manpage is a quick reference, and it warns that the larger compiler manuals can carry newer detail. When a project depends on a particular package build, trust the command output on your host.

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 reports version 3.2.2 and targets Linux on x86_64. The package version carries a Debian or Ubuntu packaging suffix, which helps when you compare diagnostics between machines.

Checkpoint

Stop if command -v fpc resolves to an unexpected installation. A different compiler earlier in PATH can make a correct project look broken.

2. Compile into a build directory

Give FPC your Pascal source file. These options affect generated files, not the source:

  • -FE sets the executable and unit output path.
  • -FU places compiled units in a separate directory.
  • -o gives a program a precise executable name.
$ 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 line count and elapsed time vary. A successful compile normally leaves the executable at build/hello and unit files under build/units. You do not need sudo when the project sits 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

Checkpoint

The output is whatever your program prints. Status 0 says this run returned successfully; it does not test every code path.

3. Make warnings and detail visible

The installed configuration turns on some defaults, so state your diagnostic intent when investigating a build. The -v option takes letters you can combine: i for general information, w warnings, n notes, h hints, and u the names of files the compiler opened.

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

Tip

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

4. Find the configuration file

FPC reads a configuration file before it processes the rest of the command line. On Linux the documented search covers:

  • The current directory.
  • ~/.fpc.cfg.
  • A directory named by PPC_CONFIG_PATH.
  • The compiler's installation path.
  • /etc, last.

That 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 syntax accepts compiler options, comments beginning with #, and conditional directives such as #IFDEF, #ELSE and #ENDIF. It can define symbols with #DEFINE and include another file with #INCLUDE. Keep project-specific choices in a project file, not in a package-managed file under /etc.

5. Add a project configuration

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, so a one-off command can override a project default. The trap is that a setting hidden in a config file can be the real reason a build differs from a plain invocation. When debugging, use -vu and compare the exact commands.

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 like this means missing compiler paths, not a Pascal syntax error. Remove -n for the ordinary build, or supply a complete project configuration. Do not copy random unit paths from another host.

6. Add checks only while diagnosing

FPC can generate runtime checks for input/output, integer overflow, range and stack with -Ci, -Co, -Cr and -Ct. They suit a debug build but can change runtime behaviour and performance. Keep them in a named debug configuration, and do not assume 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 start with checks and debugging on and optimisation modest, then test the release command separately.

Warning

Never read a clean checked build as proof that untested input is safe.

Some switches change linking rather than compilation:

  • -Cn (also -E) omits linking, so there is no runnable executable.
  • -Xst requests static linking.
  • -Xs strips symbols according to the installed configuration.

Use these 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, so 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:

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

Replace the old executable only after checking the new program. With a temporary output name, recovery is simply to leave the old file in place and remove the new one with your normal file-management command.

Recovery

Do not use a broad recursive deletion in a project directory just to clear compiler output. Confirm the exact paths first.

Done means

  • Compiler confirmed. fpc -iV reports the expected 3.2.2.
  • Clean build location. The program builds without elevated privileges into a dedicated build directory.
  • Run checked. The executable runs and you checked its exit status.
  • Config known. You know whether the build used /etc/fpc.cfg, a project file, or -n.
  • Switches deliberate. Diagnostic, debug and linking switches are chosen, not inherited by accident.
  • Last good build safe. A failed replacement build cannot silently overwrite the last working executable.