ofsp2026 01_helloWorld
Created time
Mar 28, 2026 05:06 AM
type
Post
status
Published
date
Mar 28, 2026
slug
ofsp2026 01_helloWorld
summary
tags
ofsp2026
OpenFOAM
category
post
icon
password
Place
Last edited time
Mar 28, 2026 09:11 AM
Important
访问 https://aerosand.cc 以获取最近更新。
0. 前言
本文主要讨论如下
理解 C++ 代码的编译原理
理解动态库
编译运行 helloWorld 项目
1. 开始
Tip
对于 OpenFOAM 来说,不管是求解器还是算例,放在任何一个文件夹都可以。放在
$FOAM_RUN 路径下也只是为了方便管理。我们在用户自定义路径下
.../userPath/ 新建 ofsp/ 文件夹,并在其中新建各个子项目的文件夹。终端输入命令,新建总项目文件夹
ofsp即OpenFoam sharing programming的缩写
我们可以将
ofsp 设置为快捷命令,这样子在终端输入 ofsp 后可以直接跳转到项目文件夹下。终端输入命令,打开
bashrc 文件在
bashrc 文件末尾添加以下语句终端输入命令,使快捷命令生效
2. 项目
通过终端新建本文的子项目的文件夹
终端输入命令
通过 vscode 打开项目后,可以使用
ctrl + ~ 唤出 vscode 的终端控制台,快捷进行命令操作。终端输入命令,新建项目下文件并空白保存
终端输入
tree 命令,查看文件树状结构Tip
如果无法使用
tree 命令,请按照终端提示安装 tree 即可我们分别写入代码,内容如下
类的声明
Aerosand.h 如下Tip
这里尽量贴近 OpenFOAM 的代码风格,比如函数名和变量采用驼峰命名,私有成员变量名称尾缀下划线等。
类的定义
Aerosand.cpp 如下主源码
main.cpp 如下虽然我们笼统的把代码到程序的整个过程称为“编译”,实际上,在 Linux 系统下,C++ 程序的“编译”分成四个过程。
Warning
本文后续讨论的终端指令运行路径均留在
ofsp/ofsp_01_helloWorld/ 不变3. 代码编译
3.1. 预处理
预处理 Preprocessing 是编译过程的第一阶段,发生在真实编译(生成目标代码)之前。它由预处理器 Preprocessor 负责处理源代码中以
# 开头的指令,这些指令也被称为预处理指令。比如,
#include 将提示把另一个文件的内容插入到当前位置,#define 将提示把宏定义替换到此处等等。生成。
终端输入命令,执行预处理
其中
- g++ 的
E标识预处理器进行预处理
- g++ 的
o(小写)标识指定生成的文件
在 Linux 系统下生成两个新文件
Aerosand.i
main.i
后缀
.i 表示中间预处理输出文件 intermediate preprocessing output。3.2. 编译
编译 Compile 是编译器 Compiler 把预处理后的源代码(
.i 或 .i 文件)转换成汇编代码(.s 文件)的过程。编译器将会对已经展开(头文件、宏等)的源代码进行语法分析、语义分析、优化等工作,最终生成会变代码。
终端输入命令,执行编译
- g++ 的
S标识指定编译器进行编译(大写S)
在 Linux 系统下生成两个新文件
Aerosand.s
main.s
后缀
.s(小写)表示汇编语言形式的源文件 source code written in assembly。3.3. 汇编
汇编 Assemble 是指汇编器 Assembler 将后缀
.s 表示的汇编语言形式的源文件转换成机器指令 Machine code,输出为目标文件 Object file的过程。汇编器将上一步的文件转换成人类可读的汇编语言,最终生成的与机器平台相关的二进制文件,不能直接运行,需要进一步处理。
终端输入命令,执行汇编
- g++ 的
c(小写)标识指定汇编器进行汇编
在 Linux 系统下生成两个新文件
Aerosand.o
main.o
后缀
.o(小写)表示目标文件 object file。3.4. 链接
链接 Link 是链接器 Linker 把多个目标文件和系统库文件组合成一个完整可执行程序的过程。
目标文件虽然包含机器指令,但仍然不是完整程序,链接器将找到其中函数调用涉及到“外部符号”的引用,生成可执行的二进制文件。
终端输入命令,执行直接链接
在 Linux 系统下最终生成一个可执行的新文件
main.out
这里的后缀
.out 并不重要。在执行链接的指令中,该执行文件不加任何后缀也可以。终端输入
./main.out 命令,运行该程序可以看到程序已经正常运行,得到了正确的结果。
4. 动态库
即使上面已经顺利完成了程序的编译和运行,我们仍然要讨论多一些。
当项目中有大量类的时候,我们希望某些类能固定下来提供某种“方法”,这种“方法”就形成一个可以重复使用的库 Library。由于库本身已经经过了完整的编译流程,当其他项目使用这个库的时候,库本身无需再次“预处理”,“编译”以及“汇编”,仅仅和这个项目链接即可。
因为静态库开销大,浪费空间,更新维护困难,所以 OpenFOAM 大量使用动态库,我们这里也只以动态库为例。
动态库在程序编译时并不链接到目标代码,而仅仅在程序运行时才被链接载入。不同的程序如果调用相同的库,那么内存里只需要一份该动态库的可共享实例,这样就大大减少了空间浪费。此外,因为动态库仅在程序运行时才被链接载入,所以库的单独维护更新也十分方便。
编译器可以对汇编后的
.o 目标文件进行整理形成动态库,在 Linux 系统下生成 .so 文件。终端输入命令,执行生成动态库
- g++ 的
shared标识指定生成动态链接库
- g++ 的
fPIC标识指定创建与地址无关的编译程序,f即 file,PIC即 position independent code
- 动态库文件以
lib开头
在 Linux 系统下生成一个可链接的动态库文件
libAerosand.so
后缀
.so 表示共享目标 shared object。5. 链接动态库
我们并不采用上面的 3.4 节的直接链接方式,而是采用链接动态库的方式编译程序。
终端输入指令,删除上一步的编译结果
终端输入命令,查看原本动态库链接路径,可以发现并不是项目本地路径。
终端输入命令,临时指定动态库路径为当前文件夹
Tip
- 不要担心,临时指定不影响 OpenFOAM 动态库路径的环境配置
- 如果重启计算机,想要再次运行
main程序,必须要再次指定动态库路径
- 无论是把新开发库放在本项目路径下,或是其他任何路径下,任何位置的项目都可以链接使用这个动态库,只要指定正确的链接路径即可。这也是动态库“相对独立”“自由链接”的意义所在
终端输入命令,链接动态库生成可执行文件
- g++ 的
L标识指定的动态库的路径, 使用L.表示动态库在当前路径
- g++ 的
l标识指定的动态库的名称,使用时省略动态库的lib字段
- 如前所述,可执行程序的后缀在这里并不重要
在 Linux 系统下生成一个可执行程序
main
总结整个过程如下
终端输入
./main 命令,运行该程序终端显示内容如下
可以看到程序已经正常运行,得到了正确的结果。
6. 小结
本文完成讨论
理解 C++ 代码的编译原理
理解动态库
编译运行 helloWorld 项目
支持我们
Tip
希望这里的分享可以对坚持、热爱又勇敢的您有所帮助。
如果这里的分享对您有帮助,您的评论或赞助将对本系列以及后续其他系列的更新、勘误、迭代和完善都有很大的意义,这些行动也会为后来的新同学的学习有很大的助益。
赞助打赏时的信息和留言将用于展示和感谢。

Copyright @ 2026 Aerosand
- 课程(文本、图片等):CC BY-NC-SA 4.0
- OpenFOAM 开发代码 :GPL v3
- 其他代码:MIT License
Loading...