2007年11月26日星期一

Makefile知识补充:特殊的宏及详细规则

关于Makefile的详细说明恐得有一本书来介绍,这里仅是有利于我理解vasp的一小部分内容。
特殊的宏:
为简单使用规则,make提供了几个特殊的宏:
 $@
整个当前目标名的值可以由宏“$@”来代替。

 $<
当前的源文件由“$<”来代替。例如,在前面的例子中用到了$(CC) –c $<,其中的“$<”是所有要编译的.c文件。宏“$<”仅在后缀规则或.DEFAULT中有效。

 $*
当前目标的基名由宏“$*”来代替。例如目标的名字是hello.o,则基名就是除去了后缀.o的hello。

以上介绍的特殊宏使用了make自身的规则,用户不可以改变。下表介绍了C中预定义的宏。
用途 宏 默认值
库文档汇编命令 AR ar
ARFLAGS rv
AS as
ASFLAGS
COMPILE.s $(AS) $(ASFLAGS) $(TARGET ARCH)
C编译器命令 CC cc
CFLAGS
CPPFLAGS
COMPILE.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET ARCH) –c
LINK.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET ARCH)
链接编辑器命令 LD ld
LDFLAGS
rm命令 RM rm
后缀列表 SUFFIXES .o .c .c~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .mod .mod~ .sym
.def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ .cps .cps~


另附详细规则
GNU make中文手册 ver - 3.8
翻译整理:徐海兵

2004-09-11


关于本书

本文瑾献给所有热爱Linux的程序员!本文档版权所有,禁止用于任何商业行为。

本文比较完整的讲述GNU make工具,涵盖GNU make的用法、语法。同时重点讨论如何为一个工程编写Makefile。作为一个Linux程序员,make工具的使用以及编写Makefile是必需的。系统、详细讲述make的中文资料比较少,出于对广大中文Linuxer的支持,本人在工作之余,花了18个多月时间完成对“info make”的翻译整理,完成这个中文版的书册。本书并不是一个语言的翻译版本,其中对GNU make的一些语法和用法根据我个人的工作经验进行了一些详细分析和说明,也加入了一些个人的观点和实践总结。本书的所有的例子都可以在支持V3.8版本的GNU make的系统中正确执行。

由于个人水平限制,本文在一些地方存在描述不准确之处。恳请大家在阅读过程中,提出您宝贵的意见,也是对我个人的帮助。我的个人电子邮箱地址:xhbdahai@126.com。非常愿意和大家交流!共同学习。

阅读本书之前,应该对GNU的工具链和Linux的常用工具有一定了解。诸如:gcc、as、ar、ld、yacc等。在书写Makefile时,需要能够理解一些shell脚本程序。这些工具是维护一个工程的基础工具。如果对这些工具的使用不是很熟悉,可参考相关资料。

阅读本文的几点建议:

1. 如果之前你对GNU make没有了解、而当前也不想深入的学习GNU make的读者。你只需要阅读本文各章前半部分的基础知识。

2. 如果你已经对GNU make比较熟悉,可能你更需要关心此版本的一些特点、新增的功能和存在的不兼容。

3. 之前你对GNU make没有多少概念、或者刚开始接触,本身又想成为一个Linux下的专业程序员,那么建议:完整学习本文的各个章节,包括了基础知识和高级用法、技巧。它会为你以后在Linux下的工程开发、工程管理提供非常有用的帮助。

4. 此中文文档当前版本v1.3,本文的所有勘误和最新版本可在主页 http://xhbdahai.cublog.cn 上获取!!



谢谢!



徐海兵 2005-12-31

目 录

第一章:概述

1.1 概述

1.2 准备知识

第二章:GNU make 介绍

2.1 Makefile简介

2.2 Makefile规则介绍

2.3 简单的示例

2.4 make如何工作

2.5 指定变量

2.6 自动推导规则

2.7 另类风格的makefile

2.8 清除工作目录过程文件

第三章:Makefile 总述

3.1 Makefile的内容

3.2 makefile文件的命名

3.3 包含其它makefile文件

3.4 变量 MAKEFILES

3.5 变量 MAKEFILE_LIST

3.6 其他特殊变量

3.7 makefile文件的重建

3.8 重载另外一个makefile

3.9 make如何解析makefile文件

3.9.1 变量取值

3.9.2 条件语句

3.9.3 规则的定义

3.10 总结

第四章:Makefile的规则

4.1 一个例子

4.2 规则语法

4.3 依赖的类型

4.4 文件名使用通配符

4.4.1 统配符使用举例

4.4.2 通配符存在的缺陷

4.4.3 函数wildcard

4.5 目录搜寻

4.5.1 一般搜索(变量VPATH)

4.5.2 选择性搜索(关键字vpath)

4.5.3 目录搜索的机制

4.5.4 命令行和搜索目录

4.5.5 隐含规则和搜索目录

4.5.6 库文件和搜索目录

4.6 Makefile伪目标

4.7 强制目标(没有命令或依赖的规则)

4.8 空目标文件

4.9 Makefile的特殊目标

4.10 多目标

4.11 多规则目标

4.12 静态模式

4.12.1 静态模式规则的语法

4.12.2 静态模式和隐含规则

4.13 双冒号规则

4.14 自动产生依赖

第五章:规则的命令

5.1 命令回显

5.2 命令的执行

5.3 并发执行命令

5.4 命令执行的错误

5.5 中断make的执行

5.6 make的递归执行

5.6.1 变量MAKE

5.6.2 变量和递归

5.6.3 命令行选项和递归

5.6.4 -w选项

5.7 定义命令包

5.8 空命令

第六章:Makefile中的变量

6.1 变量的引用

6.2 两种变量定义(赋值 )

6.2.1 递归展开式变量

6.2.2 直接展开式变量

6.2.3 如何定义一个空格

6.2.4 “?=”操作符

6.3 变量的高级用法

6.3.1 变量的替换引用

6.3.2 变量的套嵌引用

6.4 变量取值

6.5 如何设置变量

6.6 追加变量值

6.7 override 指示符

6.8 多行定义

6.9 系统环境变量

6.10 目标指定变量

6.11 模式指定变量

第七章:Makefile的条件执行

7.1 一个例子

7.2 条件判断的基本语法

7.2.1 关键字“ifeq”

7.2.2 关键字“ifneq”

7.2.3 关键字“ifdef”

7.2.4 关键字“ifndef”

7.3 标记测试的条件语句

第八章:make的内嵌函数

8.1 函数的调用语法

8.2 文本处理函数

8.2.1 $(subst FROM,TO,TEXT)

8.2.2 $(patsubst PATTERN,REPLACEMENT,TEXT)

8.2.3 $(strip STRINT)

8.2.4 $(findstring FIND,IN)

8.2.5 $(filter PATTERN…,TEXT)

8.2.6 $(filter-out PATTERN...,TEXT)

8.2.7 $(sort LIST)

8.2.8 $(word N,TEXT)

8.2.9 $(wordlist S,E,TEXT)

8.2.10 $(words TEXT)

8.2.11 $(firstword NAMES…)

8.3 文件名处理函数

8.3.1 $(dir NAMES…)

8.3.2 $(notdir NAMES…)

8.3.3 $(suffix NAMES…)

8.3.4 $(basename NAMES…)

8.3.5 $(addsuffix SUFFIX,NAMES…)

8.3.6 $(addprefix PREFIX,NAMES…)

8.3.7 $(join LIST1,LIST2)

8.3.8 $(wildcard PATTERN)

8.4 foreach 函数

8.5 if 函数

8.6 call函数

8.7 value函数

8.8 eval函数

8.9 origin函数

8.10 shell函数

8.11 make的控制函数

8.11.1 $(error TEXT…)

8.11.2 $(warning TEXT…)

第九章:执行make

9.1 指定makefile文件

9.2 指定终极目标

9.3 替代命令的执行

9.4 防止特定文件重建

9.5 替换变量定义

9.6 使用make进行编译测试

9.7 make的命令行选项

第十章:make的隐含规则

10.1 隐含规则的使用

10.2 make的隐含规则一览

10.3 隐含变量

10.3.1 代表命令的变量

10.3.2 命令参数的变量

10.4 make隐含规则链

10.5 模式规则

10.5.1 模式规则介绍

10.5.2 模式规则示例

10.5.3 自动化变量

10.5.4 模式的匹配

10.5.5 万用规则

10.5.6 重建内嵌隐含规则

10.6 缺省规则

10.7 后缀规则

10.8 隐含规则搜索算法

第十一章:使用make更新静态库文件

11.1 库成员作为目标

11.2 静态库的更新

11.2.1 更新静态库的符号索引表

11.3 make静态库的注意事项

11.4 静态库的后缀规则

第十二章 : GNU make的特点

12.1 源自System v的特点

12.2 源自其他版本的特点

12.3 GNU make自身的特点

第十三章 和其它版本的兼容

第十四章 Makefile的约定

14.1 基本的约定

14.2 规则命令行的约定

14.3 代表命令变量

14.4 安装目录变量

14.5 Makefile的标准目标名

14.6 安装命令分类

第十五章 make的常见错误信息

 

附录:关键字索引

1. GNU make可识别的指示 符

2. GNU make函数

3. GNU make的自动化变量

4. GNU make环境变量

后序


目录

第一章 概述
http://bbs.linuxsky.net/thread-2459-1-1.html

第二章: GNU make 介绍
http://bbs.linuxsky.net/thread-2460-1-1.html

第三章:Makefile 总述
http://bbs.linuxsky.net/thread-2461-1-1.html

第四章:Makefile的规则
http://bbs.linuxsky.net/thread-2462-1-1.html

第五章:规则的命令
http://bbs.linuxsky.net/thread-2463-1-1.html

第六章:Makefile中的变量
http://bbs.linuxsky.net/thread-2464-1-1.html

第七章:Makefile的条件执行
http://bbs.linuxsky.net/thread-2465-1-1.html

第八章:make的内嵌函数
http://bbs.linuxsky.net/thread-2466-1-1.html

第九章:执行make
http://bbs.linuxsky.net/thread-2467-1-1.html

第十章:make的隐含规则
http://bbs.linuxsky.net/thread-2468-1-1.html

第十一章:使用make更新静态库文件
http://bbs.linuxsky.net/thread-2469-1-1.html

第十二章 : GNU make的特点
http://bbs.linuxsky.net/thread-2470-1-1.html

第十三章 和其它版本的兼容
http://bbs.linuxsky.net/thread-2471-1-1.html

第十四章 Makefile的约定
http://bbs.linuxsky.net/thread-2472-1-1.html

第十五章 make的常见错误信息
http://bbs.linuxsky.net/thread-2473-1-1.html

附录:关键字索引
http://bbs.linuxsky.net/thread-2474-1-1.html

2007年11月25日星期日

了解Makefile

首先打算从Makefile入手来了解整个程序的结构,然后再去各个分析。
vasp自身带了一些makefile,考虑了多种可能的机型。相对于我们实验室的cluster,我选用了使用pgi的f90编译器对AMD的Opteron系统优化的makefile。下面摘录我找的关于makefile的一些说明知识。

Linux/Unix环境下的Make和Makefile详解
作者:Pathetique
摘自:http://www.gbunix.com/htmldata/2005_01/1/3/article_1145_1.html

  无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。因此,有效的利用make和makefile工具可以大大提高项目开发的效率。同时掌握make和makefile之后,您也不会再面对着Linux下的应用软件手足无措了。

  但令人遗憾的是,在许多讲述Linux应用的书籍上都没有详细介绍这个功能强大但又非常复杂的编译工具。在这里我就向大家详细介绍一下make及其描述文件makefile。

  Makefile文件

  Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

  在 UNIX 系统中,习惯使用 Makefile 作为 makfile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:

  $ make -f Makefile.debug

  例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生成,这三个文件还分别包含自己的头文件a.h 、b.h和c.h。通常情况下,C编译器将会输出三个目标文件filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即在filea.c和fileb.c里都有这样的声明:

  #include "defs"

  那么下面的文档就描述了这些文件之间的相互联系:

  ---------------------------------------------------------
  #It is a example for describing makefile
  prog : filea.o fileb.o filec.o
  cc filea.o fileb.o filec.o -LS -o prog
  filea.o : filea.c a.h defs
  cc -c filea.c
  fileb.o : fileb.c b.h defs
  cc -c fileb.c
  filec.o : filec.c c.h
  cc -c filec.c
  ----------------------------------------------------------

  这个描述文档就是一个简单的makefile文件。

  从上面的例子注意到,第一个字符为 # 的行为注释行。第一个非注释行指定prog由三个目标文件filea.o、fileb.o和filec.o链接生成。第三行描述了如何从prog所依赖的文件建立可执行文件。接下来的4、6、8行分别指定三个目标文件,以及它们所依赖的.c和.h文件以及defs文件。而5、7、9行则指定了如何从目标所依赖的文件建立目标。

  当filea.c或a.h文件在编译之后又被修改,则 make 工具可自动重新编译filea.o,如果在前后两次编译之间,filea.C 和a.h 均没有被修改,而且test.o还存在的话,就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make 工具可避免许多不必要的编译工作。当然,利用Shell脚本也可以达到自动编译的效果,但是,Shell 脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而 make 工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。

  Makefile文件作为一种描述文档一般需要包含以下内容:

  ◆ 宏定义
  ◆ 源文件之间的相互依赖关系
  ◆ 可执行的命令

  Makefile中允许使用简单的宏指代源文件及其相关编译信息,在Linux中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。

  下面都是有效的宏引用:

  $(CFLAGS)
  $2
  $Z
  $(Z)

  其中最后两个引用是完全一致的。

  需要注意的是一些宏的预定义变量,在Unix系统中,"$*、$@、$?和$<"四个特殊宏的值在执行命令的过程中会发生相应的变化,而在GNU make中则定义了更多的预定义变量。关于预定义变量的详细内容,宏定义的使用可以使我们脱离那些冗长乏味的编译选项,为编写makefile文件带来很大的方便。

  ---------------------------------------------------------
  # Define a macro for the object files
  OBJECTS= filea.o fileb.o filec.o
  # Define a macro for the library file
  LIBES= -LS
  # use macros rewrite makefile
  prog: $(OBJECTS)
  cc $(OBJECTS) $(LIBES) -o prog
  ……
  ---------------------------------------------------------

  此时如果执行不带参数的make命令,将连接三个目标文件和库文件LS;但是如果在make命令后带有新的宏定义:

  make "LIBES= -LL -LS"

  则命令行后面的宏定义将覆盖makefile文件中的宏定义。若LL也是库文件,此时make命令将连接三个目标文件以及两个库文件LS和LL。

  在Unix系统中没有对常量NULL作出明确的定义,因此我们要定义NULL字符串时要使用下述宏定义:

  STRINGNAME=

  Make命令

  在make命令后不仅可以出现宏定义,还可以跟其他命令行参数,这些参数指定了需要编译的目标文件。其标准形式为:

  target1 [target2 …]:[:][dependent1 …][;commands][#…]
  [(tab) commands][#…]

  方括号中间的部分表示可选项。Targets和dependents当中可以包含字符、数字、句点和"/"符号。除了引用,commands中不能含有"#",也不允许换行。

  在通常的情况下命令行参数中只含有一个":",此时command序列通常和makefile文件中某些定义文件间依赖关系的描述行有关。如果与目标相关连的那些描述行指定了相关的command序列,那么就执行这些相关的command命令,即使在分号和(tab)后面的aommand字段甚至有可能是NULL。如果那些与目标相关连的行没有指定command,那么将调用系统默认的目标文件生成规则。

  如果命令行参数中含有两个冒号"::",则此时的command序列也许会和makefile中所有描述文件依赖关系的行有关。此时将执行那些与目标相关连的描述行所指向的相关命令。同时还将执行build-in规则。

  如果在执行command命令时返回了一个非"0"的出错信号,例如makefile文件中出现了错误的目标文件名或者出现了以连字符打头的命令字符串,make操作一般会就此终止,但如果make后带有"-i"参数,则make将忽略此类出错信号。

  Make命本身可带有四种参数:标志、宏定义、描述文件名和目标文件名。其标准形式为:

  Make [flags] [macro definitions] [targets]

  Unix系统下标志位flags选项及其含义为:

  -f file  指定file文件为描述文件,如果file参数为"-"符,那么描述文件指向标准输入。如果没有"-f"参数,则系统将默认当前目录下名为makefile或者名为Makefile的文件为描述文件。在Linux中, GNU make 工具在当前工作目录中按照GNUmakefile、makefile、Makefile的顺序搜索 makefile文件。
  -i   忽略命令执行返回的出错信息。
  -s   沉默模式,在执行之前不输出相应的命令行信息。
  -r   禁止使用build-in规则。
  -n   非执行模式,输出所有执行命令,但并不执行。
  -t   更新目标文件。
  -q   make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息。
  -p   输出所有宏定义和目标文件描述。
  -d   Debug模式,输出有关文件和检测时间的详细信息。

  Linux下make标志位的常用选项与Unix系统中稍有不同,下面我们只列出了不同部分:

  -c dir   在读取 makefile 之前改变到指定的目录dir。
  -I dir   当包含其他 makefile文件时,利用该选项指定搜索目录。
  -h   help文挡,显示所有的make选项。
  -w   在处理 makefile 之前和之后,都显示工作目录。

  通过命令行参数中的target ,可指定make要编译的目标,并且允许同时定义编译多个目标,操作时按照从左向右的顺序依次编译target选项中指定的目标文件。如果命令行中没有指定目标,则系统默认target指向描述文件中第一个目标文件。

  通常,makefile 中还定义有 clean 目标,可用来清除编译过程中的中间文件,例如:

  clean:
  rm -f *.o

  运行 make clean 时,将执行 rm -f *.o 命令,最终删除所有编译过程中产生的所有中间文件。

  隐含规则

  在make 工具中包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。Unix系统通常支持一种基于文件扩展名即文件名后缀的隐含规则。这种后缀规则定义了如何将一个具有特定文件名后缀的文件(例如.c文件),转换成为具有另一种文件名后缀的文件(例如.o文件):

  .c:.o
  $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  系统中默认的常用文件扩展名及其含义为:
  .o  目标文件
  .c  C源文件
  .f  FORTRAN源文件
  .s  汇编源文件
  .y  Yacc-C源语法
  .l  Lex源语法

  在早期的Unix系统系统中还支持Yacc-C源语法和Lex源语法。在编译过程中,系统会首先在makefile文件中寻找与目标文件相关的.C文件,如果还有与之相依赖的.y和.l文件,则首先将其转换为.c文件后再编译生成相应的.o文件;如果没有与目标相关的.c文件而只有相关的.y文件,则系统将直接编译.y文件。

  而GNU make 除了支持后缀规则外还支持另一种类型的隐含规则--模式规则。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 % 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 file.c 文件转换为 file.o 文件:

  %.c:%.o
  $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  #EXAMPLE#

  下面将给出一个较为全面的示例来对makefile文件和make命令的执行进行进一步的说明,其中make命令不仅涉及到了C源文件还包括了Yacc语法。本例选自"Unix Programmer's Manual 7th Edition, Volume 2A" Page 283-284

下面是描述文件的具体内容:

  ---------------------------------------------------------
  #Description file for the Make command
  #Send to print
  P=und -3 | opr -r2
  #The source files that are needed by object files
  FILES= Makefile version.c defs main.c donamc.c misc.c file.c \
  dosys.c gram.y lex.c gcos.c
  #The definitions of object files
  OBJECTS= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o
  LIBES= -LS
  LINT= lnit -p
  CFLAGS= -O
  make: $(OBJECTS)
  cc $(CFLAGS) $(OBJECTS) $(LIBES) -o make
  size make
  $(OBJECTS): defs
  gram.o: lex.c
  cleanup:
  -rm *.o gram.c
  install:
  @size make /usr/bin/make
  cp make /usr/bin/make ; rm make
  #print recently changed files
  print: $(FILES)
  pr $? | $P
  touch print
  test:
  make -dp | grep -v TIME>1zap
  /usr/bin/make -dp | grep -v TIME>2zap
  diff 1zap 2zap
  rm 1zap 2zap
  lint: dosys.c donamc.c file.c main.c misc.c version.c gram.c
  $(LINT) dosys.c donamc.c file.c main.c misc.c version.c \
  gram.c
  rm gram.c
  arch:
  ar uv /sys/source/s2/make.a $(FILES)
  ----------------------------------------------------------

  通常在描述文件中应象上面一样定义要求输出将要执行的命令。在执行了make命令之后,输出结果为:

  $ make
  cc -c version.c
  cc -c main.c
  cc -c donamc.c
  cc -c misc.c
  cc -c file.c
  cc -c dosys.c
  yacc gram.y
  mv y.tab.c gram.c
  cc -c gram.c
  cc version.o main.o donamc.o misc.o file.o dosys.o gram.o \
  -LS -o make
  13188+3348+3044=19580b=046174b

  最后的数字信息是执行"@size make"命令的输出结果。之所以只有输出结果而没有相应的命令行,是因为"@size make"命令以"@"起始,这个符号禁止打印输出它所在的命令行。

  描述文件中的最后几条命令行在维护编译信息方面非常有用。其中"print"命令行的作用是打印输出在执行过上次"make print"命令后所有改动过的文件名称。系统使用一个名为print的0字节文件来确定执行print命令的具体时间,而宏$?则指向那些在print文件改动过之后进行修改的文件的文件名。如果想要指定执行print命令后,将输出结果送入某个指定的文件,那么就可修改P的宏定义:

  make print "P= cat>zap"

  在Linux中大多数软件提供的是源代码,而不是现成的可执行文件,这就要求用户根据自己系统的实际情况和自身的需要来配置、编译源程序后,软件才能使用。只有掌握了make工具,才能让我们真正享受到到Linux这个自由软件世界的带给我们无穷乐趣。

关于这个博客

自己使用vasp已经有两年了,但是扪心自问,对于vasp到底真正了解多少,却觉得脑袋空空。
对于密度泛函理论(DFT)只了解了大概,但是对于细节则模糊不清。对于使用vasp进行计算,关于参数的设置也是模糊不清,往深处问的话就会发现自己一无所知。
真正做学问的人是不应该让这种情况发生的,因此我决定从DFT理论的实现,细节的地方深入的了解,这样才会对自己做的研究有信心。
从现在,从建这个博客起,我要记录在深入学习vasp的过程中遇到的各种问题以及自己的理解。
vasp的源码很多,包含好几十上百个模块,还有各个数学库的调用以及并行编程,因此要学的东西太多,我会从基本的开始。