




















在 Pascal 代码里“可用”的宏,分为三类:
FPC、FPC_FULLVERSION、CPU386、UNIX、WIN32 等){$MACRO ON} + {$define NAME:=VALUE}),这是用户自定义的宏freepascal.org。lcl_version、lcl_fullversion)以及运行时 widgetset 信息,它们本质是常量/变量,不是条件编译宏这些符号是编译器自己定义的,用在 {$IFDEF} / {$IF} 等条件编译里。
定义在 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 还支持更“像 C 预处理器”的宏系统:需要显式打开,然后可以定义“带值”的宏。
{$MACRO ON} {$define DEBUG_TAG:='[DEBUG]'} {$define MAX_LINES:=100} begin WriteLn(DEBUG_TAG, ' MaxLines=', MAX_LINES); end.
这里:
{$define ident:=expr} 定义宏,ident 在后续源码中会被替换成 expr。在 {$MACRO ON} 状态下,FPC 预定义了几个带值的宏:
FPC_FULLVERSION – 整型版本号。FPC_VERSION / FPC_RELEASE / FPC_PATCH – 版本的各部分。注意:
这些 和上面条件符号同名,但本质是“宏常量”,可以在表达式里直接用:
{$MACRO ON} const CompiledWithFPC = 'Compiled with FPC ' + IntToStr(FPC_FULLVERSION);
在 Lazarus 工程里,还有两类信息常被当成“宏”:
在单元 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}。
当前使用的 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 判断。你之前问的 $(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.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。