在Lazarus交流群中看见有人提出有关判断CPU架构问题,我把官方文档的链接发了过去。为了方便在未来更多使用Free Pascal的中文开发者使用,故撰写这篇文章用于整理资料。

官方文档请参见:Compiler defines during compilation

Free Pascal中提供了很多编译期间的符号,可以在编译时进行判断,来让程序在不同平台上表现出不同的行为。

系统环境 链接到标题

架构 链接到标题

Free Pascal还定义了一些符号来判断处理器的架构。例如,如果目标处理器是x86_64,那么会定义CPUX86_64

   {$IFDEF CPUX86_64}
   // 这里的代码只在x86_64架构上执行
   {$ENDIF}

表格 G.2: 使用 FPC 编译时可能的 CPU 定义

定义 定义时机
CPU86 Free Pascal 目标是 Intel 80x86 或兼容的 (16 和 32 位)
CPU87 Free Pascal 目标是 Intel 80x86 或兼容的 (16 和 32 位)
CPU386 Free Pascal 目标是 Intel 80386 或更高版本
CPUI386 Free Pascal 目标是 Intel 80386 或更高版本
CPU68K Free Pascal 目标是 Motorola 680x0 或兼容的
CPUM68K Free Pascal 目标是 Motorola 680x0 或兼容的
CPUM68020 Free Pascal 目标是 Motorola 68020 或更高版本
CPU68 Free Pascal 目标是 Motorola 680x0 或兼容的
CPUSPARC32 Free Pascal 目标是 SPARC v7 或兼容的
CPUSPARC Free Pascal 目标是 SPARC v7 或兼容的
CPUALPHA Free Pascal 目标是 Alpha AXP 或兼容的
CPUPOWERPC Free Pascal 目标是 32 位或 64 位的 PowerPC 或兼容的
CPUPOWERPC32 Free Pascal 目标是 32 位的 PowerPC 或兼容的
CPUPOWERPC64 Free Pascal 目标是 64 位的 PowerPC 或兼容的
CPUX86_64 Free Pascal 目标是 AMD64 或 Intel 64 位处理器
CPUAMD64 Free Pascal 目标是 AMD64 或 Intel 64 位处理器
CPUX64 Free Pascal 目标是 AMD64 或 Intel 64 位处理器
CPUIA64 Free Pascal 目标是 Intel Itanium 64 位处理器
CPUARM Free Pascal 目标是 ARM 32 位处理器
CPUAVR Free Pascal 目标是 AVR 16 位处理器
CPU16 Free Pascal 目标是 16 位 CPU
CPU32 Free Pascal 目标是 32 位 CPU
CPU64 Free Pascal 目标是 64 位 CPU
CPUI8086 表示 16 位 x86 目标 (i8086)

操作系统 链接到标题

Free Pascal也定义了一些符号来判断目标操作系统。例如,如果目标操作系统是Windows,那么会定义MSWINDOWS

   {$IFDEF MSWINDOWS}
   // 这里的代码只在Windows操作系统上执行
   {$ENDIF}

表格 G.4: 使用目标操作系统编译时可能的定义

目标操作系统 定义
AIX AIX, UNIX
Amiga AMIGA
Android ANDROID
linux LINUX, UNIX
freebsd FREEBSD, BSD, UNIX, DRAGONFLY
netbsd NETBSD, BSD, UNIX
openbsd OPENBSD, BSD, UNIX
sunos SUNOS, SOLARIS, UNIX
go32v2 GO32V2, DPMI
MS-DOS 16 bit real mode MSDOS (2.7.1 及更高版本)
Haiku HAIKU
os2 OS2
NETWARE NETWARE, NETWLIBC
Nintendo DS NDS
emx OS2, EMX
Solaris SOLARIS
WII WII
Windows (native NT) NATIVENT
Windows (16-bit) WIN16
Windows (all) WINDOWS
Windows 32-bit WIN32, MSWINDOWS
Windows 64-bit WIN64, MSWINDOWS
Windows (winCE) WINCE, UNDER_CE, FPC_OS_UNICODE
Classic Amiga AMIGA
Atari TOS ATARI
Classic Macintosh MACOS
PalmOS PALMOS
BeOS BEOS, UNIX
QNX RTP QNX, UNIX
Mac OS X BSD, DARWIN, UNIX, IPHONESYM

编译器信息 链接到标题

表格 G.1: 使用 FPC 编译时可能的定义

定义 描述
FPC_LINK_DYNAMIC 当输出将动态链接时定义。这是在使用 -XD 编译器开关时定义的。
FPC_LINK_STATIC 当输出将静态链接时定义。这是默认模式。
FPC_LINK_SMART 当输出将进行智能链接时定义。这是在使用 -XX 编译器开关时定义的。
FPC_PROFILE 当向程序添加分析代码时定义。这是在使用 -pg 编译器开关时定义的。
FPC_CROSSCOMPILING 当目标 OS/CPU 与源 OS/CPU 不同时定义。
FPC 总是为 Free Pascal 定义。
VER2 总是为 Free Pascal 版本 2.x.x 定义。
VER2_0 总是为 Free Pascal 版本 2.0.x 定义。
VER2_2 总是为 Free Pascal 版本 2.2.x 定义。
VER3 总是为 Free Pascal 版本 3.x.x 定义。
VER3_0 总是为 Free Pascal 版本 3.0.x 定义。
VER3_2 总是为 Free Pascal 版本 3.2.x 定义。
FPC_VERSION 包含来自 FPC 的主版本号。
FPC_RELEASE 包含来自 FPC 的次版本号。
FPC_PATCH 包含来自 FPC 的版本号的第三部分。
FPC_FULLVERSION 包含来自 FPC 的整个版本号作为单个数字,可用于比较。对于 FPC 2.2.4,它将包含 20204。
ENDIAN_LITTLE 当 Free Pascal 目标是小端处理器(80x86、Alpha、ARM)时定义。
ENDIAN_BIG 当 Free Pascal 目标是大端处理器(680x0、PowerPC、SPARC、MIPS)时定义。
FPC_DELPHI Free Pascal 处于 Delphi 模式,要么使用编译器开关 -MDelphi,要么使用 $MODE DELPHI 指令。
FPC_OBJFPC Free Pascal 处于 OBJFPC 模式,要么使用编译器开关 -Mobjfpc,要么使用 $MODE OBJFPC 指令。
FPC_TP Free Pascal 处于 Turbo Pascal 模式,要么使用编译器开关 -Mtp,要么使用 $MODE TP 指令。
FPC_MACPAS Free Pascal 处于 Mac Pascal 模式,要么使用编译器开关 -Mmacpas,要么使用 $MODE MACPAS 指令。

调试模式 链接到标题

在 Free Pascal 中,{$IFOPT} 指令可以用于检查特定编译器开关的状态。如果该开关处于指定状态,则会编译其后的文本。如果该开关不处于指定状态,则编译会在对应的 {$ELSE}{$ENDIF} 指令后继续。

例如,如果你想检查是否处于调试模式,可以使用以下代码:

{$IFOPT D+}
  writeln('调试模式已激活');
{$ENDIF}

在上述代码中,如果编译器的调试模式开关(D+)已打开,那么 writeln('调试模式已激活'); 这行代码就会被编译。否则,这行代码会被忽略。

此外,你还可以在代码的开始部分添加以下代码,以便在 IDE 的调试模式下自动定义 DEBUG:

{$IFOPT D+}
  {$DEFINE DEBUG}
{$ENDIF}

这样,当你从 IDE 中以调试模式运行应用程序时,DEBUG 就会被定义。你可以在代码的其他部分使用 {$IFDEF DEBUG} 来检查 DEBUG 是否已被定义。例如:

{$IFDEF DEBUG}
  writeln('DEBUG 已定义');
{$ENDIF}

在上述代码中,如果 DEBUG 已被定义,那么 writeln('DEBUG 已定义'); 这行代码就会被编译。否则,这行代码会被忽略。这样,你就可以根据是否定义了 DEBUG 来决定是否编译某些代码,从而实现在调试模式下执行特定的代码。