fpc/lazarus可用的宏
在 Pascal 代码里“可用”的宏,分为三类:
-
- FPC 编译器预定义的 条件编译符号 / 宏(如
FPC、FPC_FULLVERSION、CPU386、UNIX、WIN32等) - FPC 的 “宏系统”(
{$MACRO ON}+{$define NAME:=VALUE}),这是用户自定义的宏freepascal.org。 - Lazarus/LCL 提供的 版本常量(如
lcl_version、lcl_fullversion)以及运行时 widgetset 信息,它们本质是常量/变量,不是条件编译宏
- FPC 编译器预定义的 条件编译符号 / 宏(如
一、FPC 预定义条件编译符号(最常用)
这些符号是编译器自己定义的,用在 {$IFDEF} / {$IF} 等条件编译里。
1.1 编译器版本 / 模式相关
定义在 Programmer’s Manual 附录 G 及宏章节中:
FPC– 总是定义,表示当前是 Free Pascal 编译器。FPC_FULLVERSION– 整型版本号,如 3.2.2 对应30202,可直接比较:
{$IF FPC_FULLVERSION >= 30202} // 需要 FPC 3.2.2+ {$IFEND}
FPC_VERSION– 主版本号(整数),如3。FPC_RELEASE– 次版本号,如2。FPC_PATCH– 补丁号,如2。VER2/VER2_0/VER2_2/VER3/VER3_0/VER3_2– 分别对 2.x / 2.0.x / 2.2.x / 3.x / 3.0.x / 3.2.x 定义。FPC_DELPHI/FPC_OBJFPC/FPC_TP/FPC_MACPAS– 表示当前编译模式(Delphi / objfpc / TP / MacPas)。
这些在代码里可以这样用:
{$IFDEF FPC} // Free Pascal 专用代码 {$ENDIF} {$IF FPC_FULLVERSION >= 30202} // 依赖较新 FPC 特性的代码 {$IFEND}
1.2 CPU / 架构相关符号
附录 G 的 “Possible CPU defines when compiling using FPC”:
常用:
CPU86/CPU87/CPU386/CPUI386– x86 / 80386+ 目标。CPUX86_64/CPUAMD64/CPUX64– AMD64 / Intel 64 目标。CPUARM/CPUAARCH64– ARM 32 / 64 位目标。CPU16/CPU32/CPU64– 目标 CPU 字长。
示例:
{$IFDEF CPU386} // 32-bit x86 特定代码 {$ENDIF} {$IFDEF CPUX86_64} // 64-bit x86-64 特定代码 {$ENDIF}
1.3 操作系统相关符号
附录 G 的 “Possible defines when compiling using target OS”:
常用:
UNIX– 所有类 Unix 目标。LINUX– Linux 目标。FREEBSD/NETBSD/OPENBSD/BSD– 各 BSD 变体。DARWIN– macOS / iOS 目标。WIN32/WIN64/MSWINDOWS– Windows 32/64 位。ANDROID– Android 目标。WINCE/UNDER_CE– Windows CE。MACOS– classic Mac OS(非 macOS)。
示例:
{$IFDEF MSWINDOWS} // Windows 专用代码 {$ENDIF} {$IFDEF UNIX} // Unix/Linux/macOS 通用代码 {$ENDIF}
1.4 字节序 / 链接 / 特性等
ENDIAN_LITTLE/ENDIAN_BIG– 目标是小端 / 大端 CPU。FPC_LINK_DYNAMIC/FPC_LINK_STATIC/FPC_LINK_SMART– 动态/静态/智能链接。FPC_CROSSCOMPILING– 正在交叉编译。FPC_HAS_FEATURE_*– 一堆特性宏,例如:FPC_HAS_FEATURE_EXCEPTIONSFPC_HAS_FEATURE_THREADINGFPC_HAS_FEATURE_ANSISTRINGS- 等等。
这些属于“编译器内部特性描述”,一般很少在应用层直接用。
二、FPC 宏系统({$MACRO ON})
FPC 还支持更“像 C 预处理器”的宏系统:需要显式打开,然后可以定义“带值”的宏。
2.1 打开宏支持
{$MACRO ON} // 或者命令行 -Sm
之后,宏才会被当成“替换宏”,而不仅是条件符号。
2.2 定义与使用宏
{$MACRO ON} {$define DEBUG_TAG:='[DEBUG]'} {$define MAX_LINES:=100} begin WriteLn(DEBUG_TAG, ' MaxLines=', MAX_LINES); end.
这里:
{$define ident:=expr}定义宏,ident在后续源码中会被替换成expr。- 替换是递归的,所以要避免死循环;新版编译器会报警。
2.3 预定义宏(宏模式下的)
在 {$MACRO ON} 状态下,FPC 预定义了几个带值的宏:
FPC_FULLVERSION– 整型版本号。FPC_VERSION/FPC_RELEASE/FPC_PATCH– 版本的各部分。
注意:
这些 和上面条件符号同名,但本质是“宏常量”,可以在表达式里直接用:
{$MACRO ON} const CompiledWithFPC = 'Compiled with FPC ' + IntToStr(FPC_FULLVERSION);
三、Lazarus / LCL 相关“宏”(其实是常量/变量)
在 Lazarus 工程里,还有两类信息常被当成“宏”:
3.1 LCL 版本常量
在单元 LCLVersion 中定义:
const lcl_version = laz_version; // 例如 '3.0.0.3' lcl_fullversion = laz_fullversion; // 例如 3030003
在代码中:
uses LCLVersion; begin WriteLn('LCL version: ', lcl_version); WriteLn('LCL full version: ', lcl_fullversion); end.
也可以在条件编译里用(需要 uses LCLVersion):
uses LCLVersion; {$IF lcl_fullversion >= 3000000} // 需要 LCL 3.0+ {$IFEND}
注意:
这是 常量,不是预处理器宏,所以 {$IF} 里要用“表达式”形式,不能用 {$IFDEF}。
3.2 Widgetset 信息(运行时,不是宏)
当前使用的 LCL widgetset(gtk2 / gtk3 / qt / win32 / carbon 等)是 运行时信息,通过 WidgetSet.LCLPlatform 获取:
uses InterfaceBase; // 这里声明了 WidgetSet function LCLWidgetsetName: string; begin case WidgetSet.LCLPlatform of lpGtk2: Result := 'gtk2'; lpGtk3: Result := 'gtk3'; lpWin32: Result := 'win32'; lpQt: Result := 'qt'; // 还有 lpCarbon, lpQt5 等,取决于版本 else Result := 'unknown'; end; end;
这是 运行时查询,不是编译期宏。如果需要在不同 widgetset 下执行不同代码,一般要么:
- 通过工程模板/ 包条件编译不同的单元;
- 或者在运行时用
WidgetSet.LCLPlatform判断。
四、IDE 宏 vs 代码宏(别混淆)
你之前问的 $(ProjFile)、$Project(TitleNew) 等属于 IDE 宏,用在:
- 编译器选项里的路径 / 参数;
- 外部工具命令行;
- 项目标题模板等。
它们由 IDE 在“调用编译器之前”展开,不会进入 Pascal 源码。
而这一篇里说的:
{$IFDEF FPC}/{$IF FPC_FULLVERSION >= ...}– 是 编译器预定义符号 / 宏;{$MACRO ON}+{$define NAME:=VALUE}– 是 用户自定义宏;lcl_version/lcl_fullversion– 是 LCL 提供的常量;WidgetSet.LCLPlatform– 是 运行时变量。
五、一个综合示例
program MacroDemo; {$mode objfpc}{$H+} {$MACRO ON} uses SysUtils, LCLVersion, InterfaceBase; {$define APP_NAME:='MacroDemo'} begin WriteLn(APP_NAME, ' info:'); // FPC 版本 WriteLn(' FPC_FULLVERSION: ', FPC_FULLVERSION); {$IF FPC_FULLVERSION >= 30202} WriteLn(' (compiled with FPC 3.2.2+)'); {$IFEND} // CPU / OS {$IFDEF CPU386} WriteLn(' CPU: 386+ (32-bit x86)'); {$ENDIF} {$IFDEF CPUX86_64} WriteLn(' CPU: x86_64'); {$ENDIF} {$IFDEF MSWINDOWS} WriteLn(' OS: Windows'); {$ENDIF} {$IFDEF UNIX} WriteLn(' OS: Unix-like'); {$ENDIF} // LCL 版本 WriteLn(' LCL version: ', lcl_version); WriteLn(' LCL full version: ', lcl_fullversion); // Widgetset(运行时) WriteLn(' LCL widgetset: ', Ord(WidgetSet.LCLPlatform)); end.

浙公网安备 33010602011771号