这个Makefile是否正确?

时间:2013-10-21 14:49:02

标签: c makefile

我被要求做一个makefile,我已经这样做了:

# La siguiente no es necesariamente requerida, se agrega para
# mostrar como funciona.

.SUFFIXES: .o .c
.c.o:
    $(CC) -c $(CFLAGS) $<


# Macros

CC = g++
CFLAGS = -Wall -Wextra -Werror -pedantic
SRC = main.c metbasicos.c metbasicos.h metintermedios.c metintermedios.h metavanzados.c metavanzados.h
OBJ = main.c metbasicos.c metintermedios.c metavanzados.c


# Reglas explicitas

all: $(OBJ)
    $(CC) $(CFLAGS) -o p1 $(OBJ)

clean:
    $(RM) $(OBJ) main

# Reglas implicitas

metbasicos.o: metbasicos.c metbasicos.h
metintermedios.o: metintermedios.c metintermedios.h
metavanzados.o: metavanzados.c metavanzados.h
main.o: main.c metbasicos.h metintermedios.h metavanzados.h

这是对的吗?

要编译,我通常使用以下命令:

g++ -Wall -Wextra -Werror -pedantic main.c metbasicos.c metintermedios.c metavanzados.c -o p1.exe

如果我用以下方法进行一些测试:

make ./p1 < input.txt

工作正常,但我不确定它是否是正确的实现。

有人可以告诉我,我是否犯了一些严重的错误?

非常感谢。

2 个答案:

答案 0 :(得分:3)

这里没有任何严重错误,但有一些奇怪的事情。正如Ignacio指出的那样,如果你不愿意,你根本不需要重新定义编译规则。但你可能做到这一点的原因是你混淆了C和C ++。

您正在构建.c文件,这些文件是按照惯例的C代码,g++是一个C ++编译器,这是奇怪的。如果您真的在构建C代码,则应使用gcc进行编译。如果您真的正在构建C ++代码,则应将文件重命名为.cpp.cc或类似名称。此外,C ++编译器的GNU make变量是CXX,而不是CC,而标志的变量是CXXFLAGS而不是CFLAGS

此外,您的all目标应取决于p1p1目标应包含该链接:

.PHONY: all
all: p1
p1: $(OBJ)
        $(CC) $(CFLAGS) -o p1 $(OBJ)

每当您运行p1时,即使未进行任何更改,make也会重新关联。

您还可以添加其他更高级的内容,例如自动构建头文件先决条件等等。

答案 1 :(得分:1)

$(CFLAGS)编译标志:在将.c源文件编译为.o目标文件时使用它们。

在执行$(CFLAGS)时使用$(CC) -o $(OBJ)并不常见,但效果很好。一种正确的方法是使用$(LDFLAGS)标记进行链接过程,将所有.o与您正在使用的可能库一起放入二进制可执行文件中。

通常$(CFLAGS)包含编译选项,例如您使用的编译选项,$(LDFLAGS)包含链接选项,例如-L. -lpersonal,用于在与makefile相同的目录中加载名为libpersonal.a的文件

此外,我建议您在+=声明中使用CFLAGS来保留现有的CFLAGS(如果已有的话)。

如果您不想为每个文件设置规则,那么.c.o规则很有用,您在底部执行了哪些操作。最佳做法是为每个文件定义自定义规则,将源文件包含的头文件添加为该规则的依赖关系。这样,makefile将只管理重新编译需要的文件,因为源更改了包含的标头。当然,当您更改每个源中包含的头文件时,需要对源文件进行全面分析。