Meh*_*dad 9 mingw makefile configure makefile-project
我还是UNIX/Linux世界的新手,尤其是相关工具,比如GCC编译器.也就是说,我仍然是makefiles和类似的东西的新手(我在Windows上使用MinGW),因为到目前为止,我的大多数开发都是使用像Visual Studio和Eclipse这样的IDE.
当我打开一个典型的项目文件夹时,我看到这样的文件:
configure
make
INSTALL
install-sh (or a variant)
Run Code Online (Sandbox Code Playgroud)
这里有很多我不理解的东西,我的主要问题是:
这些之间有什么区别,为什么我们需要每一个?(在IDE世界中,你所拥有的只是一个项目文件;就是这样.所以我很困惑为什么我们这里不仅仅是一个makefile.)
这些文件是如何生成的?对于小型项目,您可以手工编写它们,但对于像GCC这样的大型项目,即使尝试也是荒谬的.我发现编辑这些文件很痛苦,我得出的结论是我不应该手动修改它们.但如果是这样,那么人们通常使用哪些工具来添加和修改这些文件?
为什么他们不在makefile中使用通配符?为什么每个目标文件都有一行?这是因为限制,还是有优势?
拥有一个调用编译器的shell脚本和每个文件,以及一个makefile做同样的事情有什么区别?在Windows中,我很想在文件夹中创建批处理文件,并使用它编译所有内容 - 不需要只有一个文件.有什么不同?为什么不只是一个.sh文件,编译一切?
奖金问题:
make工具不接受彼此的格式......我怎么知道使用什么?GCC只是通常的工具,还是每个人都应遵循一些标准?我可能会有更多问题,因为我对这类项目的结构有了更多了解,但就目前而言,这些是我最大的问题.:)
Jac*_*lly 15
在普通包装中,这些文件各有特定目的.这与unix的理念是一致的,即"每个程序应该做一件事并做好事".在大多数项目中,您将看到如下文件:
configureconfigure.acMakefileMakefile.inMakefile.aminstall-shINSTALLconfigure(通常)是一个shell脚本,它在构建任何内容之前检查系统是否具有所有必需的功能.Makefile.in是一个模板Makefile.配置测试的结果被替换为Makefile.in生成Makefile.这是为了处理人们在不明确的路径中有事物(编译器,标题,库),交叉编译(例如,在x86上为ARM构建),可选的库支持(某些程序具有可以打开或关闭的附加功能),使用不同的选项进行编译,等等.写一个万能Makefile的实际上真的很难.
正如您所注意到的,configure脚本本身就是一团糟.它既不是凡人的眼睛所见,也不是凡人的手所编辑.它实际上是编译的结果configure.ac,使用一个名为的程序autoconf.autoconf是m4宏处理器的一个宏包和宏处理器的包装器,它是当时这种东西的唯一好工具(autoconf真的是很老的软件,但已经非常好了).autoconf让开发人员可以轻松编写测试来检查构建软件所需的头文件,库或程序(这在程序之间有所不同).
如果你深入挖掘一下,你会注意到它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]=> configureMakefile.am ==[automake]=> Makefile.in ==[configure]=> Makefile负责的程序在箭头内.为了详细了解这一点,我推荐这个autotools教程.不要被页数计算,大部分都是逐个出现的图表.
Makefile有时会使用s中的通配符.例如,GNU Make支持一个$(wildcard)函数,您可以在其中编写如下内容:
SOURCES := $(wildcard src/*.c)
$(wildcard)不使用的主要原因是它们是扩展,并且automake非常努力地生成Makefile可以与任何 POSIX兼容的s make.在项目成熟之后,无论如何,要编译的文件列表都不会发生太大变化.
明确列出文件的第二个原因是程序获得可选功能.通配符不再适用,您必须列出编译其他功能的条件.
一个Makefile跟踪文件之间的依赖关系,其中一个shell脚本不能(不是没有显著的努力,反正).
如果您有以下Makefile规则:
foo.out: foo.in
generate-foo foo.in
Run Code Online (Sandbox Code Playgroud)
它告诉make,如果foo.in是新的比foo.out,一个新的foo.out,可以通过执行创建generate-foo foo.in.这节省了大型项目的大量冗余工作,您可能只在重新编译之间更改一个或两个文件.
你的奖金问题似乎有点不合适.最常见make的可能是GNU Make,虽然我猜想BSD make会紧随其后,其次是makeSolaris,AIX等提供的各种专有版本.
这些都接受相同的基本结构Makefile(因为POSIX这样说),但可能具有特定于供应商的语法扩展.
GCC不是像这样的构建工具make.GCC是一个命令行编译器,类似于cl.exeWindows.
不同的事情有很多原因,但最终归结为可移植性.在unix战争期间,每个平台都是不同的,人们试图制作尽可能多的软件.因此必须找到共同的分母.sh就是这样的共性,所以配置脚本被编写为使用最大可移植的sh.最大可移植性意味着使用最少的一组功能.make的不同实现在它们支持的功能上有很大差异,因此编写Makefile时使用的功能尽可能少.今天的情况略好一些,但可移植性问题仍然会推动您所看到的很多事情.