所以我在不久前学会了Makefile,创建了一个模板Makefile,我所做的就是为我正在做的每个程序复制和更改同一个文件。我改了几次,但它仍然是一个非常粗糙的Makefile。我该怎样改进它?这是我当前版本的一个示例:
CC = g++
CFLAGS = -std=gnu++0x -m64 -O3 -Wall
IFLAGS = -I/usr/include/igraph
LFLAGS = -ligraph -lgsl -lgslcblas -lm
DFLAGS = -g -pg
# make all
all: run test
# make a fresh compilation from scratch
fresh: clean test
#makes the final executable binary
run: main.o foo1.o foo2.o
$(CC) $(CFLAGS) $(LFLAGS) $^ -o $@
#makes the test executable with debugging and profiling tags
test: test.o foo1.o foo2.o
$(CC) $(DFLAGS) $(CFLAGS) $(LFLAGS) $^ -o $@
#makes teste.o
teste.o: teste.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@
#makes main.o
main.o: main.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@
#file foo1
foo1.o: foo1.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@
#file foo2
foo2.o: foo2.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@
clean: clean-test clean-o clean-annoying
clean-test:
rm test-rfv
clean-o:
rm *.o -rfv
clean-annoying:
rm *~ -rfv
只是通过视觉比较我在网络上看到的其他makefile,这似乎不是一个非常明亮的Makefile。我不知道它们是如何工作的,但我可以看到它们的样板和更通用的代码明显更少。
这可以使每个项目更好,更安全,更容易细化吗?
答案 0 :(得分:6)
如果您可以使用它,您不希望在makefile中命名特定文件,并且99%的时间都可以。 This page展示了如何开发一个非常通用的makefile。以下是我自己的makefile,基于该页面的信息:
SHELL := bash
PROG := pathed.exe
OUTDIRS := bin/debug bin/rel obj/debug obj/rel
PROG_REL := bin/rel/$(PROG)
PROG_DEBUG := bin/debug/$(PROG)
SRCFILES := $(wildcard src/*.cpp)
OBJFILES_REL := $(patsubst src/%.cpp,obj/rel/%.o,$(SRCFILES))
OBJFILES_DEBUG := $(patsubst src/%.cpp,obj/debug/%.o,$(SRCFILES))
DEPFILES := $(patsubst src/%.cpp,obj/%.d,$(SRCFILES))
CFLAGS := -Iinc -Wall -Wextra -MMD -MP
DBFLAGS := -g
RELFLAGS :=
CC := g++
.PHONY: default all testmake debug release clean dirs
default: debug
all: dirs clean debug release
dirs:
@mkdir -p $(OUTDIRS)
debug: $(PROG_DEBUG)
release: $(PROG_REL)
testmake:
@echo OBJFILES_REL = $(OBJFILES_REL)
@echo OBJFILES_DEBUG = $(OBJFILES_DEBUG)
@echo SRCFILES = $(SRCFILES)
@echo DEPFILES = $(DEPFILES)
clean:
rm -f $(OBJFILES_REL) $(OBJFILES_DEBUG) $(DEPFILES) $(PROG)
$(PROG_REL): $(OBJFILES_REL)
$(CC) $(OBJFILES_REL) -o $(PROG_REL)
strip $(PROG_REL)
@echo "---- created release binary ----"
$(PROG_DEBUG): $(OBJFILES_DEBUG)
$(CC) $(OBJFILES_DEBUG) -o $(PROG_DEBUG)
@echo "---- created debug binary ----"
-include $(DEPFILES)
obj/rel/%.o: src/%.cpp
$(CC) $(RELFLAGS) $(CFLAGS) -MF $(patsubst obj/rel/%.o, obj/%.d,$@) -c $< -o $@
obj/debug/%.o: src/%.cpp
$(CC) $(DBFLAGS) $(CFLAGS) -MF $(patsubst obj/debug/%.o, obj/%.d,$@) -c $< -o $@
答案 1 :(得分:4)
不要将CC用于C ++编译器。标准惯例是CC是C编译器,CXX是C ++编译器。 CFLAGS是C编译器的标志,CXXFLAGS是C ++编译器的标志,CPPFLAGS是预处理器的标志(例如,-I或-D标志)。对链接器使用LDFLAGS表示-L标志,对-l标志使用LDLIBS(或LOADLIBES)。
使用标准约定不仅仅是因为它使其他人更容易理解,而且因为它允许您利用隐式规则。如果make需要从.c文件制作.o文件而您尚未提供规则,则它将使用标准规则并遵守CC,CFLAGS和CPPFLAGS的设置。如果CC是C ++编译器,那么事情可能不会起作用。