2013-10-21 151 views
0

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

工作正常,但我不知道这是否是一个正确的实施。

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

非常感谢。

+0

你为什么试图重新定义规则将.C成的.o? –

+0

@ IgnacioVazquez-Abrams因为我使用makefile作为模板,来自另一个人,我对它们的工作原理有一点点想法......你能告诉我哪些行是不必要的吗? – Gera

回答

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时间。

还有其他更先进的东西,你可以添加,像头文件的先决条件自动构建等

+0

不好意思,程序必须用'C'编写,并用'g ++'编译。 这是我的老师希望我们工作的方式。 – Gera

+1

这很奇怪。自从C!= C++以后,我会对此持怀疑态度。换句话说,并非所有的合法C程序都是合法的C++程序(反之亦然)。使用错误的编译器会导致对语言(IMO)的错误理解。当然,我不是给你一个分数的人:-p – MadScientist

+0

有些老师不知道他们在做什么^^“ – Eregrith

1

$(CFLAGS)编译标志:他们正在编译您.c源文件到.o目标文件时使用。

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

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

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

.c.o规则是有用的,如果你不想打扰为每个文件设置规则,你在底部做了什么。最佳做法是为每个文件定义自定义规则,添加源文件包含的头文件作为该规则的依赖关系。这样,makefile将管理只重新编译需要的文件,因为源中的更改会导致包含的标头发生更改。当然,这需要对源文件进行彻底分析,当您更改包含在每个源中的头文件时,会进行常规修改。

+1

在链接中包含'CFLAGS'并不罕见(事实上,这是默认行为),所以我不会同意它不正确。有时候,链接器想知道'CFLAGS',比如'-g','-pthread',代码覆盖标志等等。 – MadScientist

+0

我纠正了我的一句话,谢谢。 – Eregrith