一、configure、makefile.am、makefile.in、makefile 之间的关系
这四个文件都是与 GNU Make(一个用于管理程序的编译和安装过程的工具)有关的文件,它们的关系如下:
-
configure:是一个脚本文件,用于根据系统环境生成 makefile 文件,其中包含了一些变量和选项,以配置要编译的程序。configure 脚本会根据用户的选择生成 makefile.in 文件。
-
makefile.am:是一个 Makefile 的模板文件,包含了程序需要的各种源文件、库链接、编译选项、安装目录等信息,但是这个文件还不能直接使用,需要通过 automake 工具来生成 makefile.in 文件。
-
makefile.in:是一个可根据具体用户平台生成 makefile 的模板文件,其中包含了 configure 脚本中定义的变量和选项信息,以及 makefile.am 文件中定义的源文件、库链接、编译选项、安装目录等信息。
-
makefile:是最终生成的 Makefile 文件,是根据 makefile.in 文件生成的,其中包含了编译、链接、安装等操作的规则和具体的指令信息。最终通过 make 命令执行该文件,完成程序的编译、链接和安装。
二、示例
假设我们有以下简单的 C 语言程序,包含两个源文件 hello.c
和 world.c
,并需要链接 libm
库:
// hello.c
#include <stdio.h>
int main() {
printf("Hello ");
return 0;
}
// world.c
#include <stdio.h>
#include <math.h>
int main() {
printf("World! sin(2.0)=%f\n", sin(2.0));
return 0;
}
针对这个程序,我们需要编写一个 Makefile 文件实现以下功能:
- 编译
hello.c
和world.c
为可执行文件hello
和world
。 - 链接
hello
和world
以生成可执行文件hello_world
。 - 安装可执行文件
hello_world
。
下面是一个简单的示例 Makefile.am 文件:
# Makefile.am
bin_PROGRAMS = hello_world
hello_world_SOURCES = hello.c world.c
hello_world_LDADD = -lm
上述 Makefile 文件使用 Automake 工具生成具有类似以下内容的 Makefile.in 文件:
# Makefile.in
# variables
bindir = /usr/local/bin
# targets
hello_world_SOURCES = hello.c world.c
hello_world_LDADD = -lm
bin_PROGRAMS = hello_world
# rules
all: hello_world
hello_world: hello.o world.o
$(LINK) $(hello_world_LDFLAGS) -o $@ $^ $(hello_world_LDADD)
%.o: %.c
$(COMPILE) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c $< -o $@
install: all
$(mkinstalldirs) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) hello_world $(DESTDIR)$(bindir)/hello_world
.PHONY: clean
clean:
rm -f *.o hello_world
最终,我们可以通过以下命令生成 Makefile、编译和安装可执行文件:
# 生成 Makefile
$ ./configure
# 编译和链接
$ make
# 安装
$ sudo make install