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

推荐订阅源

T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
MongoDB | Blog
MongoDB | Blog
U
Unit 42
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
P
Privacy International News Feed
L
LINUX DO - 最新话题
博客园_首页
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
C
Cisco Blogs
博客园 - 【当耐特】
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
罗磊的独立博客
MyScale Blog
MyScale Blog
Last Week in AI
Last Week in AI
A
About on SuperTechFans
G
GRAHAM CLULEY
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
D
DataBreaches.Net
The Hacker News
The Hacker News
Spread Privacy
Spread Privacy
AWS News Blog
AWS News Blog
I
InfoQ
T
The Exploit Database - CXSecurity.com
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 叶小钗
Project Zero
Project Zero

博客园 - 秋·风

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)  评论()    收藏  举报