linux下程序编译的基本原理[转载链接]
linux, 编译
经常看到有同学发帖求助各种软件编译的问题,在不同平台、不同环境下,编译可能会出现各种各样的状况,看似复杂,其实万变不离其宗,只要了解大概的编译机制,一般来说都可以自己解决。
一、编译器:
编译一个程序之前首先先读一读Readme、Install或者手册上关于安装的部分,确定自己机器上的编译器是否能够用于该程序的编译。
一般c语言gcc、g++编译器即可胜任,有特殊优化需要的会使用icc。
fortran语言有的程序要求使用ifort。
常见错误:
编译命令没有出现在$PATH变量中,这个是安装问题,一般用rpm包或从源安装不会有问题,Intel的编译器需要把bin中的配置变量的脚本在profile文件中自动执行。
libstdc++库的问题,有些软件使用的是5,而不是现在的6,这时需要安装compat-libstdc++-296和compat-libstdc++-33两个包。
有时需要用mpicc或mpicxx或mpif77之类的来编译,实际上它们也是调用现有的编译命令,只不过加上了自己的一些头文件和库。
改变编译器的使用一般通过改变环境变量来完成,不同的mpi实现有所不同,可以google一下。
二、编译:
编译是把程序源文件编译成目标文件,也就是把c、cpp、f等文件编译成o文件。
这一步对应的个关键环境变量是:CC(c的编译命令),FC(f的编译命令),CCFLAGS(c的编译参数),FCFLAGS(f的编译参数等)
这一步只要求程序中的每个函数有明确声明就可以通过,不知道什么是声明反正就理解为头文件需要能够被找到即可。
常见错误:
找不到头文件,这时需要自己确定头文件位置,把 -I[头文件路径] 参数加到对应的CCFLAGS或FCFLAGS中,编译器就知道去哪里找了。
三、链接:
把o文件和lib文件件组织成可执行文件。这也是错误最多的一个地方。
关键环境变量: LINK(其实就是前面的编译器), LDFLAGS(链接参数)
关键参数:
-L[库路径] 告诉链接器(LINK)去哪里找库文件
-l[库名] 告诉链接器需要链接哪些库, 命名方式是这样的: libxxx.a -lxxx 如: libm.a -lm , libmpi.a -lmpi
常见错误:
can not find libxxx,找到需要链接的库的a文件,把路径通过-L告诉链接器
unresolved xxxx 这个最常见
一般google一下缺失的函数,就能知道是什么库,有就用-L和-l加入,没有就想办法装
如果不能确定是一堆库文件里的哪个,有个笨方法:
nm xxx.a 可以看到这个库中所有的函数名,结合 grep命令,找到像要的函数在哪个a中,用-l加上
总之多看看变译时候的抱错信息,无非就那几种,总能找到解决的办法。
编译的套路:
有的小点的程序已经写好了Makefile文件,我们要做的就是根据自己的系统把正确的路径和库加到上面介绍的几个变量里,然后make
大部分程序需要./configure,先-help看看有什么需要注意的参数。
如果抱错,无非是某某库找不到,参考前面的参数:./configure CC=xx CCFLAGS="-Ixxx xxx xxx"
必要的库和程序先装上,环境变量设好,通过之后得到Makefile文件,直接make即可。
还可能遇到其它编译的套路,需要仔细看安装文档,但基本原理都是一样的.
本文来源于分子模拟论坛 ,原文链接: