惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
MongoDB | Blog
MongoDB | Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
aimingoo的专栏
aimingoo的专栏
B
Blog
博客园 - 聂微东
博客园_首页
D
DataBreaches.Net
F
Fortinet All Blogs
小众软件
小众软件
M
MIT News - Artificial intelligence
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
F
Full Disclosure
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 【当耐特】
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
B
Blog RSS Feed
Attack and Defense Labs
Attack and Defense Labs
W
WeLiveSecurity
N
News | PayPal Newsroom
Recent Announcements
Recent Announcements
AI
AI
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
V2EX - 技术
V2EX - 技术
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
Martin Fowler
Martin Fowler
Webroot Blog
Webroot Blog
P
Palo Alto Networks Blog
S
Schneier on Security
Latest news
Latest news

博客园 - 秋·风

修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch64) 编译 Qt 5.15.12 SDK 指南 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus lazarus鸿蒙开发3:编译libLazarusOHOS_Wrapper.so lazarus鸿蒙开发2:编译鸿蒙版本Qt5pas lazarus鸿蒙开发1:编译QT 5.12.12 鸿蒙版 fpc/lazarus for x86_64/aarch64鸿蒙版(绿色版 2026.06.03更新) fastreport报表编辑器在aarch64等非x86_64 CPU第一次打开慢的解决方案 linux/windows双系统可用的打包程序 使用FPC自带的纯 Pascal 实现的 Zlib 替代品——paszlib QFLazarus使用说明 忽略lazarus console in/output窗显示的转义序列 编译fpc遇到的怪事(2026-05-20更新) 取消树莓派的系统双击桌面图标时出现弹窗的选择提示 银河麒麟v11安装lazarus的方法 【小技巧】lazarus的应用设置某个form不在任务栏显示(linux) 用lazarus封装了linux的rsync SimpleXML-for-lazarus fastreport在windows11(lazarus)报表设计时出现的问题 用lazarus编写的deb打包工具 龙芯deepin 25系统使用旧世界软件的方法 SimpleJSON for lazarus 中文转全拼音和首字母 lazarus扩展IDE宏的方法 调整lazarus gtk2编辑控件背景颜色 Lazarus IDE宏列表 【原创控件】PopupMenu和MainMenu自绘单元 【原创控件】PopupMenu自绘 【原创控件】lazarus自定义mainmenu菜单栏(2026-02-26 增加菜单项图标尺寸参数) cudaText存在段落长度超过一定字数时会出现字符重叠的问题 lazarus编写的程序在Ubuntu任务栏/快捷栏不显示设定的图标 lazarus实现拖放文件 在uos使用lazarus调试时遇到的问题 【原创控件】lazarus IDE界面备份和恢复插件(2026-02-07增加恢复默认布局及官方已集成到lazarus) lazarus for arm32编译so链接出错
fpc/lazarus可用的宏
秋·风 · 2026-03-10 · via 博客园 - 秋·风

在 Pascal 代码里“可用”的宏,分为三类:

    • FPC 编译器预定义的 条件编译符号 / 宏(如 FPCFPC_FULLVERSIONCPU386UNIXWIN32 等)
    • FPC 的 “宏系统”({$MACRO ON} + {$define NAME:=VALUE}),这是用户自定义的宏freepascal.org
    • Lazarus/LCL 提供的 版本常量(如 lcl_versionlcl_fullversion)以及运行时 widgetset 信息,它们本质是常量/变量,不是条件编译宏

一、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_EXCEPTIONS
    • FPC_HAS_FEATURE_THREADING
    • FPC_HAS_FEATURE_ANSISTRINGS
    • 等等

这些属于“编译器内部特性描述”,一般很少在应用层直接用。

二、FPC 宏系统({$MACRO ON})

FPC 还支持更“像 C 预处理器”的宏系统:需要显式打开,然后可以定义“带值”的宏

2.1 打开宏支持

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.

posted on 2026-03-10 10:09  秋·风  阅读(100)  评论()    收藏  举报