English 中文(简体)
制作更好的Makefile
原标题:Making a better Makefile
  • 时间:2011-05-27 14:02:46
  •  标签:
  • makefile

所以我不久前了解了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。我不知道它们是如何工作的,但我可以看到它们的样板文件明显更少,通用代码更多。

这能让每个项目变得更好、更安全、更容易具体化吗?

最佳回答

如果你能逃脱惩罚的话,你不想在makefile中命名特定的文件,99%的时候你都可以此页面展示了如何开发一个非常通用的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 $@
问题回答

不要将CC用于C++编译器。标准约定是CC是C编译器,CXX是C++编译器。CFLAGS是C编译器的标志,CXXFLAGS是C++编译器的标志;CPPFLAGS是预处理器的标志(例如,-I或-D标志)。对链接器的-L标志使用LDFLAGS,对-L标志使用LDLIBS(或LOADLIBES)。

使用标准约定很好,不仅因为它让其他人更容易理解,还因为它允许你利用隐含的规则。如果make需要从.c文件生成.o文件,而您尚未提供规则,则它将使用标准规则并遵守CC、CFLAGS和CPPFLAGS的设置。如果CC是一个C++编译器,事情可能就不起作用了。





相关问题
makefile: how to show line numbers for debugging?

Is there a way to have make display the line number where it declares an error? The -d switch doesn t seem to cut it. Updated: Example output: Reaping winning child 0x08aa8648 PID 9381 /bin/sh: ...

What is the reasoning behind the Makefile whitespace syntax?

I m revisiting Python after Michael Sparks s excellent walk through of Peter Norvig s Python spell checker at the SO DevDay in London. One of the points he highlighted was how clean Python is to look ...

Debugging GNU make

Is there a command line way in make to find out which of the prerequisites of a target is not updated?

How to add an all rule to this Makefile?

I want to just type make all and have the following Makefile do everything it s supposed to do: LEX = lex YACC = yacc CC = gcc calcu: y.tab.o lex.yy.o $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl ...

How to discover number of *logical* cores on Mac OS X?

How can you tell, from the command line, how many cores are on the machine when you re running Mac OS X? On Linux, I use: x=$(awk /^processor/ {++n} END {print n+1} /proc/cpuinfo) It s not ...

Using extern in C doesn t work as expected

I have created two files: tunables.h #ifndef TUNABLES_H #define TUNABLES_H void tunables_load_conservative(); void tunables_load_aggressive(); extern int timer_x; #endif /*TUNABLES_H */ and ...

热门标签