-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.tex
243 lines (206 loc) · 17.7 KB
/
compiler.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
\chapter{编译器}\label{fortran_compiler}
\def\r{\text{\textregistered}}
\begin{table}[!htbp]
\centering
\begin{tabularx}{\textwidth}{|c|X|X|}
\hline
编译器&Ifx (+VS)&Gfortran (+VS Code)\\
\hline
类型&专有软件&自由软件\\
\hline
总空间占用&约 5.2 G&约 780 M\\
\hline
语法支持&略多于 Gfortran, 较宽松&略少于 Ifx, 较严格\\
\hline
自动纠错&无&有\\
\hline
自动补全&无&有\\
\hline
编译提示信息&次于 Gfortran&优于 Ifx\\
\hline
平均运行速度&快于 Gfortran&慢于 Ifx\\
\hline
\hline
本笔记使用版本&
2024.2.0, on Intel${}^\r$ 64, Build 20240602&
13.2.0, 64-posix-seh-rev1, Built by MinGW-Builds\\
\hline
\end{tabularx}
\caption{Ifx (+VS) 与 Gfortran (+VS Code) 的对比}
\end{table}
\section{安装}
\subsection[Intel${}^\r$ Fortran\\Compiler]{Intel${}^\r$ Fortran Compiler (Ifx)}
Windows 系统安装方式如下.
\begin{enumerate}
\item 安装 \href{https://visualstudio.microsoft.com/zh-hans/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false}
{Visual Studio Community 2022}. 安装时可选择语言为中文.
\item ``工作负载'' 选择 ``使用 C++ 的桌面开发''.
\item 安装 \href{https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7feb5647-59dd-420d-8753-345d31e177dc/w_fortran-compiler_p_2024.2.0.424.exe}{Intel${}^\r$ Fortran Compiler}.
\item 找到开始菜单内 Intel oneAPI 2023 文件夹中的 Intel oneAPI command prompt for Intel 64 for Visual Studio 2022 和 Intel oneAPI command prompt for IA32 for Visual Studio 2022, 右键选择 ``更多'' $\rightarrow$ ``打开文件位置'', 可以找这两个东东的快捷方式. 然后右键这两个快捷方式, 选择 ``属性'', 把 ``起始路径'' 改成自己最常访问的路径 (比如桌面的路径), 然后点 ``应用'', 点 ``继续'', 点 ``确定''.\label{to_desktop}
\end{enumerate}
\subsection[GNU Fortran\\Compiler]{GNU Fortran Compiler (Gfortran)}
Windows 系统安装方式如下.\footnote{
以下是直接安装 MinGW-w64 来安装 Gfortran 的, 但如果有 Python, 也许能直接通过 Pip (或 Conda) 来安装 Gfortran (或 MinGW-w64, MSYS2, \dots{})? 我也不知\dots{}
}
\begin{enumerate}
\item 访问 \href{https://github.com/niXman/mingw-builds-binaries/releases}
{MinGW-Builds-binaries releases}, 选择最新的 release 进入.
\item 选带 posix 的; 64 位系统选带 x86\_{}64 的, 32 位系统选带 i686 的; Win 10 及以上选带 ucrt 的, Win 10 以下选带 msvcrt 的. 下载并解压.
\item 把解压出来的名为 \ttt{mingw64} 的文件夹剪切到随便哪个目录. 暂称粘贴到的目录为 \ttt{[dir]}.
\item 在系统环境变量 \ttt{Path} 中加入 \ttt{[dir]\bs{}mingw64\bs{}bin}.比如, 如果刚才粘贴到 \ttt{C:\bs{}Program Files}, 就加入 \ttt{C:\bs{}Program Files\bs{}mingw64\bs{}bin}.
\item 下载 \href{https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user}{Visual Studio Code} 并安装.
\item 打开 Visual Studio Code, 点击左边四个正方形飞出一个的图标, 搜索 C/C++,Modern Fortran 和 Code Runner 并安装.
\item[] 如果已经装了 Python, 装 Modern Fortran 前先用 Pip\footnote{有 Conda 当然用 Conda 啦!} 装 fortls .
\item 按 Ctrl+Shift+P, 然后选择 ``Preferences: Open Settings (JSON)'', 打开名为 \ttt{settings.json} 的 JSON 文件.
\item 在 \ttt{settings.json} 里加入下面这些键值对.\label{add_key_value}
\begin{verbatim}
"code-runner.executorMap": {
"FortranFreeForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}",
"FortranFixedForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}"
},
"code-runner.runInTerminal": true,
"code-runner.saveAllFilesBeforeRun": true
\end{verbatim}
\end{enumerate}
最后第 \ref{add_key_value} 步还需解释, 因为牵涉到 JSON 文件的语法. JSON 文件里的内容应该满足下面的形式.
\begin{verbatim}
{
key_1: value_1,
...
key_n: value_n
}
\end{verbatim}
每一个形如 \ttt{key\_{}i: value\_{}i} 的东东称作一个键值对, 任意两个键值对之间用逗号隔开. 所以, 如果一开始 \ttt{settings.json} 里头空空如也, 则加入键值对后可能长这样.
\begin{verbatim}
{
"code-runner.executorMap": {
"FortranFreeForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}",
"FortranFixedForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}"
},
"code-runner.runInTerminal": true,
"code-runner.saveAllFilesBeforeRun": true
}
\end{verbatim}
如果一开始 \ttt{settings.json} 里长这样,
\begin{verbatim}
{
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 80,
"workbench.colorTheme": "Red"
}
\end{verbatim}
则加入键值对后可能长这样.
\begin{verbatim}
{
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 80,
"workbench.colorTheme": "Red",
"code-runner.executorMap": {
"FortranFreeForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}",
"FortranFixedForm":
"cd $dir; gfortran *.f*; if($?){.\a.exe}"
},
"code-runner.runInTerminal": true,
"code-runner.saveAllFilesBeforeRun": true
}
\end{verbatim}
注意第 4 行最后要多加一个逗号来隔开键值对.
\section{使用}
CLI (Command Line Interface, 命令行界面) 和 GUI (Graphical User Interface, 图形用户界面) 两手都要抓, 两手都要硬. GUI 大家其实老熟了, 平常大家用手机电脑, 只要开机, 见到的就是 GUI. CLI 就是大家看电影里黑客们用的黑框框, 不过现在手机电脑进步了, 框框不一定是黑的, 也可能是红的蓝的之类的.
\subsection{使用 CLI}\label{use_ifx}\label{use_gfortran}
我们首先需要请出 CLI 框框. 用 Ifx 的同学请打开开始菜单内 Intel oneAPI 2023 文件夹中的 Intel oneAPI command prompt for Intel 64 for Visual Studio 2022 (32 位系统请打开 Intel oneAPI command prompt for IA32 for Visual Studio 2022). 用 Gfortran 请打开 Powershell, 可以在电脑桌面或文件夹中按鼠标右键然后点 ``在终端中打开'', 也可以按 Win+R, 输入 ``powershell'' 然后点 ``确定'', 还可以在 Visual Studio Code 中, 点上面 ``Terminal'' 后点 ``New Terminal''.
我们要熟悉 CLI 的运作流程. 首先我们需要在一些文本文档里写 Fortran 代码, 这些文本文档称为源代码文件 (source code file), 其文件后缀名一般是 \ttt{.f90}/\ttt{.for}/\ttt{.f}. 然后我们需要用编译器把每个源代码文件依次变成对应的目标文件 (object file), 这个过程称作编译 (compilation), Ifx 编译出的目标文件后缀名是 \ttt{.obj}, Gfortran 编译出的目标文件后缀名是 \ttt{.o}. 然后我们需要用编译器把所有目标文件合起来变成一个可执行文件 (executable file), 这个过程称作链接 (linking), Windows 系统中链接出的可执行文件后缀名是 \ttt{.exe}, Linux 系统中链接出的可执行文件后缀名一般是 \ttt{.out}. 广义的编译包括编译和链接. 最后我们需要命令电脑照可执行文件干活儿, 这个过程称之为执行 (execution). 示意图如 \ref{execute_run} 所示.
\def\la{\leftarrow}
\def\ra{\rightarrow}
\def\da{\downarrow}
\begin{equation}
\begin{matrix}
& \text{源代码文件}1 & \dots & \text{源代码文件}n \\
\text{编译} & \da & \da & \da \\
& \text{目标文件}1 & \dots & \text{目标文件}n \\
\text{链接} & \da & \da & \da \\
& \ra & \text{可执行文件} & \la \\
\text{运行} & & \da & \\
& & \text{电脑工作} & \\
\end{matrix}.\label{execute_run}
\end{equation}
\begin{center}
编译执行流程示意图
\end{center}
现在俺们通过一个实例来掌握 CLI 的用法! 我们先在任意一个文件夹里新建两个空白文本文档 (默认的文件名应该是 ``\textsf{新建}\ttt{\ }\textsf{文本文档}\ttt{.txt}''), 分别把文件名改为 \ttt{main.f90} 和 \ttt{helloworld.f90} (注意要把拓展名 \ttt{.txt} 也给改掉, 不要改成 \ttt{main.f90.txt} 和 \ttt{helloworld.f90.txt} 哟).
打开 \ttt{main.f90}, 写入下面的内容并保存.
\begin{lstlisting}
program main
implicit none
call helloworld()
end program main
\end{lstlisting}
打开 \ttt{helloworld.f90}, 写入下面的内容并保存.
\begin{lstlisting}
subroutine helloworld()
implicit none
print *, 'Hello, world!'
end subroutine helloworld
\end{lstlisting}
请同学们弄出 CLI 框框. CLI 框框中会出现一些文字, 请同学们观察这些文字的最下面一行里包含的文件夹路径, 这个路径对应的文件夹称为当前工作目录 (current working directory). 如果当前工作目录不是 \ttt{main.f90} 和 \ttt{helloworld.f90} 所在的文件夹, 我们最好 ``\ttt{cd}'' 到 \ttt{main.f90} 和 \ttt{helloworld.f90} 所在的文件夹去, 用 Ifx 的同学需要在框框里输入 ``\ttt{cd /D }\textsf{目录}'' 然后按回车键, 用 Gfortran 的同学需要在框框里输入 ``\ttt{cd }\textsf{目录}'' 然后按回车键. 假设 \ttt{main.f90} 和 \ttt{helloworld.f90} 所在的文件夹是 \ttt{C:\bs{}Users\bs{}GasinAn\bs{}Desktop}, 那么我们输入 \ttt{cd /D C:\bs{}Users\bs{}GasinAn\bs{} Desktop} 或 \ttt{cd C:\bs{}Users\bs{}GasinAn\bs{}Desktop}然后按回车键. 这样CLI 框框中的文字就会有变化, 最下面一行里包含的的文件夹路径变成新的当前工作目录 \ttt{C:\bs{}Users\bs{}GasinAn\bs{}Desktop} 了.
然后俺们要编译, 用 Ifx 的同学需要在框框里输入 ``\ttt{ifx /c }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n}'' 然后按回车键, 用 Gfortran 的同学需要在框框里输入 ``\ttt{gfortran -c }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n}'' 然后按回车键. 所以用 Ifx 的同学需要在框框里输入 \ttt{ifx /c main.f90 helloworld.f90} 然后按回车键, 用 Gfortran 的同学需要在框框里输入 \ttt{gfortran -c main.f90 helloworld.f90} 然后按回车键.
然后俺们要链接, 用 Ifx 的同学需要在框框里输入 ``\ttt{ifx }\textsf{目标文件$\!$1}\ttt{ ... }\textsf{目标文件$\!$n}\ttt{ /o }\textsf{可执行文件}'' 然后按回车键, 用 Gfortran 的同学需要在框框里输入 ``\ttt{gfortran }\textsf{目标文件$\!$1}\ttt{ ... }\textsf{目标文件$\!$n}\ttt{ -o }\textsf{可执行文件}'' 然后按回车键. 所以用 Ifx 的同学可以在框框里输入 \ttt{ifx main.obj helloworld.obj /o a.exe} 然后按回车键, 用 Gfortran 的同学可以在框框里输入 \ttt{gfortran main.o helloworld.o -o a.exe} 然后按回车键, 得到可执行文件 \ttt{a.exe}.
最后我们要执行可执行文件, 需要在框框里输入 ``\textsf{可执行文件}'' 然后按回车键. 所以需要输入 \ttt{a.exe} 然后按回车键, 看到黑框框里蹦出 \ttt{Hello, world!} 就执行成功!
编译和链接的时候我们可以偷懒, 我们可以直接一步进行编译+链接两步, 用 Ifx 的同学需要在框框里输入 ``\ttt{ifx }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n}\ttt{ /o }\textsf{可执行文件}'' 然后按回车键, 用 Gfortran 的同学需要在框框里输入 ``\ttt{gfortran }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n}\ttt{ -o }\textsf{可执行文件}'' 然后按回车键. 所以用 Ifx 的同学可以在框框里输入 \ttt{ifx main.f90 helloworld.f90 /o a.exe} 然后按回车键, 用 Gfortran 的同学可以在框框里输入 \ttt{gfortran main.f90 helloworld.f90 -o a.exe} 然后按回车键, 即可直接得到可执行文件 \ttt{a.exe}. 同学们肯定要问有偷懒的办法干嘛不早说, 其实是因为同学们如果以后要写超大程序, 里面有成千上万个源代码文件, 这时候分两步编译和链接反而省事. 假设我们已经把成千上万个源代码文件编译+链接过一回了, 我们修改了其中一个源代码文件, 希望重新编译和链接, 如果我们再把成千上万个源代码文件一起编译+链接一回, 是会非常花时间的 (可能会花几个小时), 这时我们可以只把那个被修改了的源代码文件编译了, 然后再把成千上万个目标文件链接起来 (链接比编译快多了), 这样我们就能省下大把时间了呢.
以上内容总结如下.
\begin{table}[htbp]
\centering
\begin{tabular}{|p{45pt}|p{275pt}|}
\hline
``\ttt{cd}'' 目录 & \ttt{cd /D }\textsf{目录} \\
\hline
编译 & \ttt{ifx /c }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n} \\
\hline
链接 & \ttt{ifx }\textsf{目标文件$\!$1}\ttt{ ... }\textsf{目标文件$\!$n}\ttt{ /o }\textsf{可执行文件} \\
\hline
编译链接 & \ttt{ifx }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件$\!$n}\ttt{ /o }\textsf{可执行文件} \\
\hline
执行 & \textsf{可执行文件} \\
\hline
\end{tabular}
\caption{Ifx 编译执行命令}
\end{table}
\begin{table}[htbp]
\centering
\begin{tabular}{|p{45pt}|p{275pt}|}
\hline
``\ttt{cd}'' 目录 & \ttt{cd }\textsf{目录} \\
\hline
编译 & \ttt{gfortran -c }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件 $\!$n} \\
\hline
链接 & \ttt{gfortran }\textsf{目标文件$\!$1}\ttt{ ... }\textsf{目标文件$\!$n} \ttt { -o }\textsf{可执行文件} \\
\hline
编译链接 & \ttt{gfortran }\textsf{源代码文件$\!$1}\ttt{ ... }\textsf{源代码文件 $\!$n}\ttt{ -o }\textsf{可执行文件} \\
\hline
执行 & \textsf{可执行文件} \\
\hline
\end{tabular}
\caption{Gfortran 编译执行命令}
\end{table}
我们还可以偷懒. 首先我们可以用 \ttt{.} 表示 ``当前文件夹'', \ttt{..} 表示 ``上一层文件夹''. 所以\ttt{main.f90} 和 \ttt{helloworld.f90} 等价于 \ttt{.\bs{}main.f90} 和 \ttt{.\bs{}helloworld.f90} (虽然没人会自找麻烦这么写), 并且假设我们的当前工作目录是 \ttt{C:\bs{}Users\bs{}GasinAn\bs{}Desktop}, 我们 ``\ttt{cd}'' 到 \ttt{..\bs{}..} 就是 ``\ttt{cd}'' 到 \ttt{C:\bs{}Users}.
然后我们可以用通配符 (wildcard character), \ttt{?} 表示 ``任意一个不是 \ttt{.} 或 \ttt{\bs{}} 的字符'', \ttt{*} 表示 ``零个或任意多个不是 \ttt{.} 或 \ttt{\bs{}} 的字符''. 例如 \ttt{?.f?} 表示开头是一个字符, 中间是 \ttt{.f}, 结尾是一个字符的所有文件和文件夹, \ttt{*.f*} 表示开头是零个或任意多个字符, 中间是 \ttt{.f}, 结尾是零个或任意多个字符的所有文件和文件夹. 因此之前的 \ttt{main.f90 helloworld.f90} 我们都可以直接替换成 \ttt{*.f*}, 省大事了.
最后可以只输入文件或文件夹名称的前面几个字符, 然后按 Tab 键来自动补全文件或文件夹名称. 如果补全出的文件或文件夹不是我们想要的, 我们还可以多次按 Tab 键直到补全出的文件或文件夹是我们想要的. 同学们可输入 \ttt{he} 然后多次按 Tab 键查看效果.
\subsection{使用 GUI}
\subsubsection{Visual Studio (VS)}
打开 Visual Studio, 点 ``创建新项目''.
然后搜索 ``Empty Project'', 找到下面标有 ``Fortran'', ``Windows'', ``控制台'' 的 ``Empty Project'', 选择之, 然后点击 ``下一步''.
然后把 ``项目名称'' 改成 ``HelloWorld'', ``位置'' 选择自己喜欢的文件夹 (比如桌面) 的路径 (下面用 \ttt{[dir]} 表示这个路径), 点击 ``创建''.
然后就出现了编辑界面, 并且 \ttt{[dir]} 内多出了一个名为 \ttt{HelloWorld} 的文件夹.
默认使用的是 Ifort\footnote{Intel${}^\r$ Fortran Compiler Classic, 这玩意儿 Intel${}^\r$ 不想玩儿了, 要用 Ifx 来代替.}. 欲用 Ifx, 右键右边 ``解决方案资源管理器'' 里的 ``Console1 (Ifx)'',点最下面的 ``属性'', 左边选 ``配置属性'' $\rightarrow$ ``General'' (应已自动选上), 点 ``Use Compiler'' 右边的 ``Ifx Intel$\,\r$ Fortran Compiler Classic'', 点最右边的带向下标志的按钮, 改选成``IFX Intel$\,\r$ Fortran Compiler'', 点 ``应用'', 点 ``确定'',看到右边 ``Console1 (Ifx)'' 变成 ``Console1 (IFX)'' 即成功.
64 位系统, 若上面 Debug 后是 x86, 则可能需要将上面 Debug 后的 x86 改成 x64 (如不需要, 也最好改改). 点 x86 右边的向下箭头可以改, 若没有 x64, 可以点 ``配置管理器\dots{}'' 后尝试把 x64 调出来.
右击右边 ``解决方案资源管理器'' 中的 ``Source Files'', 选择 ``添加'' $\rightarrow$ ``现有项\dots{}'', 然后把之前的 \ttt{main.f90} 和 \ttt{helloworld.f90} 添加进来. 然后双击文件名即可打开文件.
点击上面的 ``调试'', 然后点 ``开始执行 (不调试)'', 看到下面框框里蹦出 \ttt{Hello, world!} 就用 Ifx 编译执行成功!
右击右边 ``解决方案资源管理器'' 中的 ``Source Files'', 选择 ``添加'' $\rightarrow$ ``新建项\dots{}'', 可以新建文件, 默认在 \ttt{HelloWorld} 文件夹里的 \ttt{HelloWorld} 文件夹里. 右击任意一个文件的文件名后, 可以点击 ``删除'' 或 ``重命名'' 进行删除或重命名操作.
关掉 Visual Studio, 重新打开, 左边多出了个 HelloWorld.sln, 点它就能回到编辑界面了.
\subsubsection{Visual Studio Code (VS Code)}
用 Visual Studio Code 打开 \ttt{main.f90}\footnote{之后同学们学 \ref{program_unit} 节, 会明白 \ttt{main.f90} 里写的是``主程序'', 所以打开它.}, 然后点右上方的白色三角儿就用 Gfortran 编译执行成功!