我还是UNIX/Linux领域的新手,尤其是相关工具,例如GCC编译器。也就是说,我仍然不熟悉makefile和类似的东西(我在Windows上使用MinGW),因为到目前为止,我的大部分开发工作都是使用Visual Studio和Eclipse之类的IDE进行的。
当我打开一个典型的项目文件夹时,我看到如下文件:
configure
make
INSTALL
install-sh (or a variant)
这里有很多我不了解的事情,我的主要问题是:
.sh
文件来编译所有内容? 奖励问题:
make
工具,它们不接受彼此的格式...我怎么知道要使用什么? GCC只是这里常用的工具,还是每个人都应该遵循的一些标准? 随着我对此类项目结构的了解越来越多,我可能还会有更多问题,但是现在,这是我最大的问题。 :)
最佳答案
configure
configure.ac
Makefile
Makefile.in
Makefile.am
install-sh
INSTALL
configure
(通常)是一个shell脚本,用于在构建任何东西之前检查系统的所有必需功能。 Makefile.in
是Makefile
的模板。配置测试的结果将替换为Makefile.in
以生成Makefile
。这是为了处理那些事物(编译器, header ,库)位于模糊路径中,交叉编译(例如,在x86上为ARM构建),可选库支持(某些程序具有可打开或关闭的附加功能)的人们,使用不同的选项进行编译,依此类推。编写一个适合所有人的Makefile
实际上非常困难。正如您所注意到的,
configure
脚本本身就是一团糟。它既不应该被凡人的眼睛所看到,也不能被凡人的双手所编辑。这实际上是使用名为configure.ac
的程序编译autoconf
的结果。 autoconf
是宏包和m4
宏处理器的包装,这是当时解决此类问题的唯一好工具(autoconf
确实是很老的软件,但是已经老化了很多)。 autoconf
使开发人员可以轻松地编写测试来检查构建软件所需的 header ,库或程序(并且程序之间的变化)。如果深入研究,您会发现
Makefile.in
也往往有点丑陋。这是因为编写好的Makefile
常常是很多样板,这启发了另一个工具automake
。 automake
将Makefile.am
(通常是简短的声明式)编译为Makefile.in
(这是巨大的),然后通过Makefile
(本质上)将其编译为configure
。install-sh
是与automake
一起分发但已复制到其他程序包中的脚本。如果系统上install
的版本是废话,则它可以作为替代品存在(install
将文件复制到安装目录中。某些真正的较旧系统的install
版本已损坏,而automake
对于删除旧系统的警告非常保守)。扮演类似角色的其他一些脚本是compile
,depcomp
和ylwrap
。INSTALL
只是描述如何安装软件包的文档。通常是automake
将样板内容复制到包中。 configure.ac ==[autoconf]=> configure
Makefile.am ==[automake]=> Makefile.in ==[configure]=> Makefile
负责程序位于箭头内。要详细了解这一点,我建议使用autotools tutorial。不要被页数拖延,大多数都是逐张出现的图。
Makefile
中的通配符。例如,GNU Make支持$(wildcard)
函数,您可以在其中编写类似以下内容的代码:SOURCES := $(wildcard src/*.c)
未使用诸如
$(wildcard)
之类的功能的主要原因是它们是扩展名,并且automake
极力尝试生成可与任何POSIX兼容Makefile
一起使用的make
。项目成熟后,要编译的文件列表不会发生太大变化。文件被明确列出的第二个原因是程序获得可选功能时。通配符不再适用,您必须列出要在其中编译附加功能的条件。
Makefile
跟踪文件之间的依赖关系,而Shell脚本不能(无论如何也不用费劲)。 如果您有
Makefile
规则,例如:foo.out: foo.in
generate-foo foo.in
它告诉
make
如果foo.in
比foo.out
更新,则可以通过执行foo.out
创建新的generate-foo foo.in
。这样可以节省大型项目上的大量冗余工作,在大型项目中,您只能在重新编译之间更改一个或两个文件。您的奖金问题似乎有些不适。最常见的
make
可能是GNU Make,尽管我猜想BSD make将紧随其后,其次是Solaris,AIX等提供的各种专有make
版本。这些都在
Makefile
中接受相同的基本结构(因为POSIX这样说),但是可能具有特定于供应商的语法扩展。GCC不是像
make
这样的构建工具。 GCC是一个命令行编译器,类似于Windows上的cl.exe
。
关于Makefile, "configure"文件和其他编译工具-它们如何工作?他们为什么按照自己的方式工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5388986/