1

我被要求做一个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

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

如果我犯了一些严重的错误,有人可以告诉我吗?

非常感谢你。

4

2 回答 2

3

这里没有任何严重的错误,但有一些奇怪的事情。正如 Ignacio 指出的那样,如果您不想重新定义编译规则,您实际上并不需要重新定义。但是您这样做的原因可能是您将 C 和 C++ 混为一谈。

您正在构建.c文件,这些文件按照约定是 C 代码g++,其中 是一个 C++ 编译器,这很奇怪。如果你真的在构建 C 代码,你应该用gcc. 如果您真的在构建 C++ 代码,您应该将文件重命名为以.cpp.cc类似结尾。此外,C++ 编译器的 GNU make 变量是CXX, not CC,标志的变量CXXFLAGS不是CFLAGS

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

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

否则,即使没有进行任何更改,p1每次运行时都会重新链接。make

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

于 2013-10-21T14:56:58.617 回答
1

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

$(CFLAGS)在做时使用$(CC) -o $(OBJ)不是常见的做法,尽管它工作正常。正确的方法是使用$(LDFLAGS)链接过程的标志将所有.o可能的库与您正在使用的可能的库一起放入二进制可执行文件中。

通常 $(CFLAGS) 包含编译选项,例如您使用的那些,而 $(LDFLAGS) 包含链接选项,例如-L. -lpersonal用于加载libpersonal.a与 makefile 位于同一目录中的文件。

另外,我建议您使用+=您的CFLAGS声明来保留现有的 CFLAGS(如果已经有一些)。

.c.o如果您不想为每个文件设置规则,那么该规则很有用,就像您在底部所做的那样。最佳实践是为每个文件定义一个自定义规则,添加源文件包含的头文件作为该规则的依赖项。这样,makefile 将设法只重新编译需要重新编译的文件,因为源代码发生了变化包含的头文件发生了变化。当然,当您更改包含在每个源中的头文件时,这需要对源文件进行彻底分析并定期修改。

于 2013-10-21T14:56:42.217 回答